New plugin syntax for pyproject.toml

As discussed a few times, @matterhorn103 has been suggesting a new strategy for plugins (e.g., load at install, use pyproject.toml)

He provided a loose demo for discussion is at avo-plugin-demo/pyproject.toml at dd417d51e10e5525d4a2def6bc197fa3f040a498 · matterhorn103/avo-plugin-demo · GitHub

What’s implied is that for all plugins like this, there would be one and only one project.scripts .. otherwise, there’s no way to indicate to Avogadro that some features / subcommands get called from one script and others get called from another script (e.g., the way the current input generators work with a bunch of orca.py in a folder.

I’m opening up this topic to discuss some brainstorming for the syntax (i.e., so I can go implement the C++ side).

Okay, here’s a useful piece:

[[tool.avogadro.charges]]
subcommand = "get-charges"
method-name = "Löwdiken analysis"

[[tool.avogadro.commands]]
subcommand = "transmute"
path.menu = "Build"  # The menu within which the command's menu entry should appear
path.entry = { label = "Transmute into gold", priority = 300 }  # The text for the command's menu entry and its position within "Build"

I don’t like subcommand here (i.e., Avogadro is supposed to run plugin transmute [options] on the command-line.

My alternatives:

  • action
  • call
  • invoke (?)
  • feature

Okay, then there’s the method-name. In the current code, there’s a distinction between name (which will be translated) and identifier (which is how you refer to it in code and not translated). I’m okay if we want to use method-name instead of name for things like charge models and energy calculators with the default that the identifier will be the same.. but I just want to make it clear that names should be translatable.

Finally, there’s the whole menu bit… I’d rather have one string like “&Build | Demo | Transmute” but I guess my bigger question is why path.menu and path.entry and not just menu and entry or menu_item?

I think of those my preference would actually be feature over action, because I’m not sure that “action” is a great fit for all the plugin types. I’d prefer both over call or invoke because I think whatever is chosen should also be used as the internal identifier that you mention. In fact, I don’t think identifier would be a bad choice.

That was essentially why I was suggesting method-name, format-name, program-name – to make it clear that they are the name for use in the GUI rather than internally, and also make a bit more clear what they will be referring to.

Absolutely. I need to edit the draft to include localization.

The logic for splitting up the string was partly to avoid having to parse the string into bits, and mostly to allow a priority to be set for each menu level. It could be menu and entry, but I just figured this organizes the specification of the path neatly together, and makes it clear that all those things are things that specify the path.

After all, it’s the same as doing:

[[tool.avogadro.commands]]
subcommand = "transmute"
path = {
    menu = "Build",
    entry = {
        label = "Transmute into gold",
        priority = 300,
    },
}

but newlines are not allowed in in-line tables in TOML 1.0, only in the freshly minted TOML 1.1, and when they’re all on one line they get a bit unwieldy.

1 Like

Great, let’s go with identifier since that’s already something used in the C++ code.

Got it, that makes more sense.

1 Like

In general the dotted syntax is the idiomatic way to do such nesting in TOML. :slight_smile:

A further question is whether the keys should use camelCase to match Avogadro’s C++ code or kebab-case to match pyproject.toml (and others such as Cargo.toml in the Rust world). So far I’ve been going for the latter, but I don’t have a preference. TOML as a format doesn’t have a recommended style or anything.

I’d go with Python practice. Many C++ packages use camelCase but that doesn’t mean the outwards facing bits need to match the internal code formatting.

1 Like