We have a bit of a code organization issue for plugins in Snapcraft that I'd like to discuss. Built-in plugins are located in
snapcraft/plugins/. Each module in there contains a single plugin defined to be a class that inherits from
snapcraft.BasePlugin. The assumption that things are organized this way exists throughout the codebase. For example:
- The plugin loading code expects the module to be named the same as the plugin specified in the YAML, and loads the first
snapcraft.BasePlugin child from that module it sees
snapcraft list-plugins literally prints out the list of modules found in
This convention encourages each plugin to be self-contained, as it doesn't define a place to put helper classes, etc. It results in plugins like the Catkin plugin, which is over 1000 lines and contains multiple classes. It's getting difficult to maintain, and raises the barrier to entry when trying to contribute.
Now we're starting to discuss adding support for ROS 2, which uses a new build system (ament), but re-uses some of the same components. There is no inherent relationship between catkin and ament, but both use rosdep, for example. I'd like to be able to maintain those helper classes independent of the plugins using them. To that end, I'd like to discuss an acceptable convention for a better-organized plugin, whether it be because the plugin is complex or because components need to be shared and maintained in isolation.
Whatever we decide, it'd be nice to provide the same ability to local plugins as well. That pretty much is the case today as the local plugin path is added to
sys.path, we just need to make it more official and cover it with test cases. Here are a few options to kick-off the discussion for the built-in ones:
- Continue assuming modules in the root of the plugin path are plugins, and skip over packages. This allows plugins to organize helpers/shared components in topic-specific packages (e.g.
snapcraft.plugins.ros would contain
- Continue assuming modules in the root of the plugin path are plugins, but create a single special package, perhaps
snapcraft.plugins.helpers to contain the various helper classes plugins might need. For example, there could be a
Rosdep. This would require skipping over the
helpers package for plugin enumeration.
- Don't change anything at all in the plugin parsing, but create a new package elsewhere in the tree for plugins to put this type of code. Perhaps
snapcraft.plugin_helpers or some such thing.
Any other ideas?