On Sat, 17 May 2025, at 2:38 PM, Stephen J. Turnbull wrote:
> Hi
>
> Is there a policy reason why
>
>  > On 5/16/25 12:09 PM, Thomas Ward via Mailman-Developers wrote:
>  > > [plugin.example]
>  > > ```
>  > > class: example_mm_plugin.hooks.ExamplePlugin
>  > > enabled: yes
>  > > config_item_one: Foo
>  > > config_item_two: Bar
>  > > config_item_three: 1234567890
>  > > ```
>
> doesn't work, but instead per Mark Sapiro we must do
>
>  > [plugin.example]
>  > ```
>  > class: example_mm_plugin.hooks.ExamplePlugin
>  > enabled: yes
>  > configuration: /path/to/example.cfg
>  > ```
>  > and in /path/to/example.cfg
>  > ```
>  > [plugin.example]
>  > config_item_one: Foo
>  > config_item_two: Bar
>  > config_item_three: 1234567890
>  > ```
>  > Then in example_archiver.py you would have things like
>  > ```
>  > from mailman.config import config
>  > from mailman.config.config import external_configuration
>  > ...
>  > my_config = external_configuration(config.plugin.example.configuration)
>  > # and then things like
>  > item_one = my_config.get('plugin.example', 'config_item_one')
>  > ```
>
> Is there a "that's a bad/dangerous API" reason why we can't have a
> scheme where in schema.py we have
>
> [paths.master]
> ext_dir: $var_dir/ext
> # This path is relative to the top-level of the extension 'example':
> ext_schema_file: default.cfg
>
> and $ext_dir/example/default.cfg defines all the configurable
> variables in the manner of schema.cfg?

Currently, plugins are just python packages and don't require to be put in a 
specific directory. The design goal was that it makes installing plugin easier 
with `pip` instead of having to copy the code into a specific directory.

Moreover, maybe I don't remember this correctly, but I don't think we currently 
provide a way to define config "schema" for plugins like we do for Core. 
`external_configuration` simply provides a way to read .cfg files parsed by 
`configparser.ConfigParser` from stdlib.

So, if we want to provide schema/config.cfg setup like today, we'll need to 
make changes in the initialization code for that.

> Every plugin's schema would get an implicit 'enabled' variable
> defaulting to 'no'.  The configuration code could either scan $ext_dir
> for importable packages and read their default.cfgs after parsing
> schema.cfg, or it could scan and parse [plugin.*] sections in
> mailman.cfg for enabled plugins and parse and instantiate their
> default.cfg before instatiating the corresponding section.

I _think_ it might okay to pre-load any provided configuration and it should be 
as simple as adding:

```
    if string(plugin_config['configuration']) != '':
        # pre-load the configuration.
        plugin.config = 
external_configuration(config.plugin.example.configuration)
```
in the src/mailman/plugins/initialize.py in the end. We can specify paths with 
`python:example.default` which will resolve to a filesystem path of package and 
import the example/default.cfg configuration.

>
> It really should be possible to create simple extensions with just
> example/__init__.py and example/default.cfg, or even just example.py
> if the only configuration is to enable it. 

You probably only just need a pyproject.toml and example.py to implement hooks 
and REST API endpoints. However, for "components", it follows a standard 
dynamic loading mechanism where plugin system expects that same folder 
structure as mailman core itself is followed. In order to define syles or 
rules, you need to have package with `example/styles` for Core to be able to 
discover them.

I am fine if you want to make this simpler and not force Core's internal 
directory structure. It is a convention we should probably follow in any 1st 
party plugins we provide (of which there are currently none) but doesn't 
necessarily need to enforced for 3rd party.

We could provide a decorator or something like `@mailman.plugins.style` which 
would be added on any class implementing `IStyle` interface and it gets added 
to config.styles. Same goes for other components.

We currently use `mailman.utilities.modules.add_components` in all the places 
to discover and load them.

https://gitlab.com/search?search=add_components&nav_source=navbar&project_id=183616&group_id=124427&search_code=true&repository_ref=master

The decorator really just needs to do required initializations/checks and add 
the component to `config.{component}`, same/similar to `add_components`.

Hope this helps!

-- 
  thanks,
  Abhilash Raj (maxking)
_______________________________________________
Mailman-Developers mailing list -- mailman-developers@python.org
To unsubscribe send an email to mailman-developers-le...@python.org
https://mail.python.org/mailman3/lists/mailman-developers.python.org/
Mailman FAQ: https://wiki.list.org/x/AgA3

Security Policy: https://wiki.list.org/x/QIA9

Reply via email to