fix(presets): use _repo_root() for bundled-core source-checkout fallback (#3086)#3091
Conversation
The tier-5 fallback in PresetResolver.resolve() and _find_bundled_core() computed the repo root as Path(__file__).parent.parent.parent. After presets.py was moved to presets/__init__.py (github#2826) that chain is one level short, resolving to src/ and looking for src/templates/commands/<cmd>.md, which never exists. As a result, wrap-strategy presets found no core base layer in source/editable installs. Use the shared _repo_root() helper so both fallbacks resolve against the actual repo-root templates/ tree. Wheel installs were unaffected (core_pack path), so this only impacts source/editable checkouts. Refs github#3086 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes preset resolver tier-5 (“bundled core”) fallback for source/editable installs by using the shared _repo_root() helper (instead of a brittle Path(__file__).parent... chain), and adds regression tests for #3086 to ensure wrap-strategy presets can always locate the core base layer even when .specify/templates/commands/ is empty.
Changes:
- Update
PresetResolver.resolve()tier-5 fallback to usespecify_cli._repo_root()for repo-root template lookup in source checkouts. - Update
PresetResolver._find_bundled_core()to use the same_repo_root()helper for consistent layer collection behavior. - Add regression tests covering tier-5 fallback behavior for
collect_all_layers()andresolve()when no matching core command exists in.specify/templates/commands/.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/presets/__init__.py |
Switch tier-5 repo-root fallback path computation to shared _repo_root() in both resolve() and _find_bundled_core(). |
tests/test_presets.py |
Add regression tests for bundled-core fallback resolution paths when .specify/templates/commands/ has no matching command file. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 1
A prior edit accidentally removed the def test_resolve_extension_command_via_manifest_skips_oserror_manifests line, orphaning its body inside the new bundled-core test. Restore the test definition so pytest collects it again. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Good catch — the Posted on behalf of @mnriem by GitHub Copilot CLI (model: Claude Opus 4.8). |
The two tier-5 fallback regression tests exercise collect_all_layers() and resolve(), not resolve_core(), so they belong in TestPresetResolver rather than TestResolveCore. Relocate them for clearer suite navigation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Assessment and fix for #3086.
The issue claims
specify initnot copyingtemplates/commands/into.specify/templates/commands/causeswrap-strategy presets to fail. That root cause is incorrect:PresetResolverhas an explicit Priority‑5 fallback (_find_bundled_core, plus the matching tier‑5 branch inresolve()) specifically designed to locate the core base layer when.specify/templates/commands/is absent. The missing copy is a layout/cosmetic gap, not a functional one.However, while verifying, I found a real bug that does break
wrappresets — but only in source/editable installs, and for a different reason:Both fallbacks computed the repo root as
Path(__file__).parent.parent.parent. Afterpresets.pywas moved topresets/__init__.py(#2826), that chain is one level short — it resolves tosrc/and looks forsrc/templates/commands/<cmd>.md, which never exists. So the base layer was never found.Wheel installs were unaffected because they take the
core_packbranch.Fix
Use the shared
_repo_root()helper (from_assets.py) in bothresolve()and_find_bundled_core()instead of a hand-rolled.parentchain, so the path stays correct regardless of module nesting.Tests
speckit.implementvia bothcollect_all_layers()andresolve()when.specify/templates/commands/has no matching file.Why not the issue's suggested fix
Copying
templates/commands/into.specify/templates/commands/duringspecify inittouches the core SDD install/manifest/upgrade flow to solve a non-problem (the fallback already covers wheel installs). This PR keeps the change isolated to the preset resolver and does not alter the SDD process.Refs #3086