feat(templates): add py: lines to command templates' scripts frontmatter#3403
feat(templates): add py: lines to command templates' scripts frontmatter#3403marcelsafin wants to merge 4 commits into
Conversation
Every templates/commands/*.md with a scripts: block now declares a py: variant so --script py renders a Python invocation via the existing interpreter-prefixing in process_template. Fixes github#3283 Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR updates Spec Kit’s command templates to include a py: entry in their scripts: frontmatter blocks, and adds tests to ensure IntegrationBase.process_template(..., script_type="py") renders a Python-invocation string (supporting the --script py pathway described in #3283/#3277).
Changes:
- Add
py:script lines to all 8templates/commands/*.mdfiles that declare ascripts:block. - Add
tests/test_command_template_py_scripts.pyto validatepy:presence and basic--script pyrendering behavior.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_command_template_py_scripts.py | New tests to discover scripted templates, assert py: lines exist, and validate process_template(..., "py") output shape |
| templates/commands/analyze.md | Add py: script entry for check prerequisites |
| templates/commands/checklist.md | Add py: script entry for check prerequisites |
| templates/commands/clarify.md | Add py: script entry for check prerequisites |
| templates/commands/converge.md | Add py: script entry for check prerequisites |
| templates/commands/implement.md | Add py: script entry for check prerequisites |
| templates/commands/plan.md | Add py: script entry for plan setup |
| templates/commands/tasks.md | Add py: script entry for tasks setup |
| templates/commands/taskstoissues.md | Add py: script entry for check prerequisites |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| scripts: | ||
| sh: scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks | ||
| ps: scripts/powershell/check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks | ||
| py: scripts/python/check_prerequisites.py --json --require-tasks --include-tasks |
There was a problem hiding this comment.
Right, thanks. install_shared_infra mapped every non-sh type to powershell. Fixed in aa7e627: py now maps to the python variant dir (with __pycache__ excluded from the copy), plus a test that runs the installer with --script py and asserts check_prerequisites.py lands in .specify/scripts/python/.
| scripts: | ||
| sh: scripts/bash/setup-plan.sh --json | ||
| ps: scripts/powershell/setup-plan.ps1 -Json | ||
| py: scripts/python/setup_plan.py --json |
| scripts: | ||
| sh: scripts/bash/setup-tasks.sh --json | ||
| ps: scripts/powershell/setup-tasks.ps1 -Json | ||
| py: scripts/python/setup_tasks.py --json |
There was a problem hiding this comment.
Same as the plan.md thread: setup_tasks.py ships in #3386, which should land before this one. Happy to split these two lines out if standalone mergeability matters more than epic order.
install_shared_infra mapped every non-sh script type to powershell, so --script py rendered invocations pointing at files that were never installed. Map py to the python variant dir and skip __pycache__ artifacts during the copy. Co-authored-by: Copilot <[email protected]>
| SCRIPTED_TEMPLATES = sorted( | ||
| p.name for p in TEMPLATES_DIR.glob("*.md") if "\nscripts:\n" in p.read_text() | ||
| ) |
There was a problem hiding this comment.
Fixed, all four read_text() calls now pass encoding="utf-8".
|
|
||
| @pytest.mark.parametrize("name", SCRIPTED_TEMPLATES) | ||
| def test_template_declares_py_script(name: str): | ||
| content = (TEMPLATES_DIR / name).read_text() |
There was a problem hiding this comment.
Fixed, all four read_text() calls now pass encoding="utf-8".
|
|
||
| @pytest.mark.parametrize("name", SCRIPTED_TEMPLATES) | ||
| def test_template_renders_python_invocation(name: str): | ||
| content = (TEMPLATES_DIR / name).read_text() |
There was a problem hiding this comment.
Fixed, all four read_text() calls now pass encoding="utf-8".
| @pytest.mark.parametrize("name", SCRIPTED_TEMPLATES) | ||
| def test_sh_rendering_unchanged(name: str): | ||
| # Negative: adding py: lines must not leak into sh rendering. | ||
| content = (TEMPLATES_DIR / name).read_text() |
There was a problem hiding this comment.
Fixed, all four read_text() calls now pass encoding="utf-8".
| scripts: | ||
| sh: scripts/bash/setup-plan.sh --json | ||
| ps: scripts/powershell/setup-plan.ps1 -Json | ||
| py: scripts/python/setup_plan.py --json |
There was a problem hiding this comment.
Same dependency as the earlier plan.md thread: setup_plan.py ships in #3386, which should merge before this PR. Flagged in the description.
| scripts: | ||
| sh: scripts/bash/setup-tasks.sh --json | ||
| ps: scripts/powershell/setup-tasks.ps1 -Json | ||
| py: scripts/python/setup_tasks.py --json |
There was a problem hiding this comment.
Covered by the #3386 dependency noted in the description; setup_tasks.py lands there first.
Co-authored-by: Copilot <[email protected]>
| content = (TEMPLATES_DIR / name).read_text(encoding="utf-8") | ||
| assert re.search(r"^\s*py: scripts/python/\S+\.py", content, re.MULTILINE), ( | ||
| f"{name} has a scripts: block but no py: line" | ||
| ) |
There was a problem hiding this comment.
Agreed, an existence check is stronger than a description note. Done in latest commit: the plan/tasks lines move to #3386 where the scripts ship, and the test now asserts every py: path exists in the repo, so a dangling reference cannot merge green. This PR is standalone now.
Drop the plan/tasks py: lines that referenced scripts shipping in the core port (github#3280); they move to that PR. Tests now assert every py: line points at a script the repo ships, so a dangling reference can never merge green. Co-authored-by: Copilot <[email protected]>
Ships with the scripts they reference; the remaining templates got their py: lines in github#3403. Co-authored-by: Copilot <[email protected]>
Description
Fixes #3283 (part of #3277)
Adds a
py:line to thescripts:frontmatter block in the 6 command templates whose referenced Python script already ships in the repo (check_prerequisites.py).plan.mdandtasks.mdget their lines in #3386 together withsetup_plan.py/setup_tasks.py; a test asserts everypy:line points at an existing script, so a dangling reference cannot merge green.process_templatealready handles thepyscript type (interpreter resolution, quoting, path rewrite to.specify/scripts/python/), so this is the last wiring needed for--script pyrendering.Extension commands reference scripts inline in prose rather than through
scripts:frontmatter, so no extension files change.Testing
uv run specify --helpuv sync && uv run pytest(3834 passed)New
tests/test_command_template_py_scripts.py(25 tests) discovers every scripted template and verifies: apy:line exists,--script pyrendering produces an interpreter-prefixed Python invocation, andshrendering is unchanged.AI Disclosure
Written with GitHub Copilot CLI; I reviewed the diff and test results.