feat: generic plugin protocol with dgoss as builtin plugin#406
feat: generic plugin protocol with dgoss as builtin plugin#406ianpittwood merged 20 commits intomainfrom
Conversation
Documents the design for refactoring dgoss as a builtin plugin implementing the BakeryToolPlugin protocol, including plugin discovery via entry points, CLI registration, and deprecation bridge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13-task plan covering protocol update, registry, dgoss plugin migration, CLI wiring, deprecation bridge, and cleanup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…time_checkable Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements discover_plugins() with entry-point-based loading and caching, and get_plugin() with a KeyError for unknown names. Adds TestDiscoverPlugins and TestGetPlugin test classes (dgoss-dependent tests will pass in Task 7+8). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove posit_bakery/image/goss/ and test/image/goss/ now that all functionality has been migrated to the dgoss plugin. Update image/__init__.py to drop the DGossSuite re-export, and update test/test_error.py to import BakeryDGossError from its new location in the dgoss plugin.
…stry Plugins can now provide tool configuration by exposing a tool_options_class attribute. The config system dynamically builds the discriminated union for YAML deserialization from registered plugin tool options, with model_rebuild after plugin discovery. - Move GossOptions to plugins/builtin/dgoss/options.py - Add config/tools/registry.py for tool options registration - Update config/tools/__init__.py with dynamic ToolField building - Plugin registry registers tool options and rebuilds config models - Break circular import in protocol.py with TYPE_CHECKING guard Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Plugin invocation is handled by the plugin's CLI command or by calling get_plugin().execute() directly. No config wrapper needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tion bridge The dgoss result display logic now lives in DGossPlugin.display_results(). Both the plugin CLI command and the deprecation bridge call it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| :param cls: The ToolOptions subclass to register. | ||
| """ | ||
| if name in _tool_options_classes: | ||
| log.warning(f"Tool options for '{name}' already registered, overwriting.") |
There was a problem hiding this comment.
I'm debating whether this should warn or raise.
There was a problem hiding this comment.
Hmmm... At this point I think it is fine to warn, but if we want to open this up to make it easier to register plugins, we will definitely want to raise.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bschwedler
left a comment
There was a problem hiding this comment.
I am really liking this approach.
My only comment/concern is the difference in CLI structure between core bakery commands and the plugins. I am not suggesting any changes now.
| """Runs dgoss tests against images in the context path | ||
|
|
||
| \b | ||
| DEPRECATED: Use 'bakery dgoss run' instead. |
There was a problem hiding this comment.
This is moving more towards a mixed convention the CLI UX
For bakery operations we use the verb-noun pattern (similar to kubectl). The plugin operations follow more of a namespace-verb pattern (similar to docker and podman).
We already kind of already straddle this with bakery ci.
What are your thoughts here?
There was a problem hiding this comment.
The benefit would be a clear delineation if every plugin is nested under run, but I'm concerned we may go away from that being our desired approach at some point.
| :param cls: The ToolOptions subclass to register. | ||
| """ | ||
| if name in _tool_options_classes: | ||
| log.warning(f"Tool options for '{name}' already registered, overwriting.") |
There was a problem hiding this comment.
Hmmm... At this point I think it is fine to warn, but if we want to open this up to make it easier to register plugins, we will definitely want to raise.
| """ | ||
|
|
||
| import logging | ||
| from typing import TYPE_CHECKING |
There was a problem hiding this comment.
We should probably start enforcing type checking, but not in this PR. 😀
Summary
BakeryToolPluginprotocol that defines a generic contract for tool plugins (CLI registration, execution, and optional tool configuration)posit_bakery/plugins/builtin/dgoss/, fully self-contained with its own command model, suite orchestrator, report models, error types, and YAML tool optionsbakery.pluginsgroup), supporting both builtin and future external pluginsbakery dgoss runwith a deprecation bridge atbakery run dgosstool_options_classthat is automatically wired intobakery.yamldeserialization via pydanticmodel_rebuildTest plan
bakery dgoss run --helpshows the new command groupbakery run dgoss --helpshows deprecation notice and still worksbakery.yamlparses correctly through the plugin's dynamic tool fieldbakery dgoss runagainst a product repo to verify end-to-end🤖 Generated with Claude Code