fix: scaffold extension config when installing via bundler - #4285
fix: scaffold extension config when installing via bundler#4285chelsealong wants to merge 2 commits into
Conversation
ExtensionPrimitive.install_from_directory/install_from_zip in the bundler never called ExtensionManager.scaffold_config, so an extension's provides.config templates were deployed only when installed with `specify extension add`, not via `specify bundle install`. Call scaffold_config after a successful install in both code paths, matching the extension-add command flow. Fixes github#4283
There was a problem hiding this comment.
Pull request overview
Fixes bundle-installed extensions failing to scaffold declared configuration templates.
Changes:
- Scaffolds config after directory and ZIP installs.
- Adds bundled-directory regression coverage.
- Updates mocks to return manifest IDs.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/bundler/services/primitives.py |
Scaffolds extension config after installation. |
tests/unit/test_bundler_primitives.py |
Adds regression coverage and updates mocks. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
| project = tmp_path / "project" | ||
| ext_source = tmp_path / "ext-source" | ||
| _write_extension_with_config(ext_source) | ||
| monkeypatch.setattr(assets, "_locate_bundled_extension", lambda cid: ext_source) |
|
Please add a regression test for the catalog/ZIP install path. The current test covers only an extension already bundled with Spec Kit, while the reported reproduction uses an extension downloaded from the catalog. The new test should confirm that installing the downloaded ZIP creates the extension's configuration file. Once updated, we'll take another look. |
Adds a regression test that exercises the catalog-download branch (install_from_zip) rather than the bundled-directory branch, per review feedback that the reported reproduction used a catalog-resolved extension.
|
Added |
Summary
Fixes #4283.
specify bundle installinstalls an extension by callingExtensionManager.install_from_directory/install_from_zipdirectlyfrom
_ExtensionKindManager._do_installinsrc/specify_cli/bundler/services/primitives.py, but never calledExtensionManager.scaffold_configafterwards. Thespecify extension addcommand flow (
src/specify_cli/extensions/_commands.py) does call it, soan extension installed as part of a bundle ended up with its
provides.configtemplates present on disk but never deployed — theextension silently had no configuration, while installing the same
extension directly worked correctly.
Change
src/specify_cli/bundler/services/primitives.py: callself._manager.scaffold_config(manifest.id)right after a successfulinstall_from_directory/install_from_zipcall in_ExtensionKindManager._do_install, using the id from the manifestreturned by the install call (matching what the
extension addcommandflow does).
tests/unit/test_bundler_primitives.py: addedtest_bundled_extension_install_scaffolds_config, which installs a real(unmocked) extension source with a
provides.configentry throughprimitive_manager("extensions", ...)and asserts the config file landsat
.specify/extensions/<id>/<name>. Also updated the existinginstall_from_directorymocks in this file to return an object with an.idattribute (as the real method does), since the new call site readsmanifest.idoff the return value.Out of scope: the issue's related documentation nit about
_target_follows_preserved_conventionnaming conventions not beingdocumented in
EXTENSION-API-REFERENCE.md, and surfacing per-filedeployed/skipped/failed console reporting through the bundler's CLI
summary (the bundler currently reports install results only as install
counts, not per-component detail — plumbing that through is a larger,
separate change).
Test plan
Confirmed the new test fails without the fix (temporarily reverted just
the production file):
With the fix:
Full suite (unmodified elsewhere):
ruff checkon the touched files reports 4 pre-existing issues (unusednoqaon lines untouched by this change, import-order in two unrelatedtest functions) that are also present on unmodified
upstream/main—confirmed by stashing this change and re-running the same
ruff checkinvocation, which reported the identical 4 findings at the same
locations.
AI disclosure
This change was implemented with AI assistance (Claude Code), including
the fix, the regression test, and this PR description. All commands
listed above were run and their output verified directly.