feat(scripts): port create-new-feature, setup-plan and setup-tasks to Python#3386
feat(scripts): port create-new-feature, setup-plan and setup-tasks to Python#3386marcelsafin wants to merge 29 commits into
Conversation
… Python Ports the three core workflow scripts to Python as part of github#3280, following the check-prerequisites PoC pattern from github#3302. Adds resolve_template() to the shared common.py module and parity tests that run bash and Python side by side. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Ports three core Spec Kit workflow scripts (create-new-feature, setup-plan, setup-tasks) to Python while preserving the existing shell implementations, and adds parity tests to ensure the Python ports match Bash/PowerShell output and exit behavior.
Changes:
- Added Python implementations for
create-new-feature,setup-plan, andsetup-tasks, plus sharedresolve_template()logic inscripts/python/common.py. - Added shared parity-test utilities (
tests/parity_helpers.py) to run Bash/PowerShell/Python twins in temporary repos with normalized output comparisons. - Added parity test suites for the three newly-ported scripts, including JSON/text output parity and PowerShell JSON parity where available.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/test_setup_tasks_python_parity.py | Adds Bash/Python + PowerShell/Python parity tests for setup-tasks. |
| tests/test_setup_plan_python_parity.py | Adds Bash/Python + PowerShell/Python parity tests for setup-plan. |
| tests/test_create_new_feature_python_parity.py | Adds parity tests for create-new-feature including numbering, truncation, errors, and persistence. |
| tests/parity_helpers.py | Introduces reusable helpers for parity tests (repo scaffolding, command builders, normalization, subprocess runner). |
| scripts/python/setup_tasks.py | Python port of setup-tasks including prereq checks + template resolution and JSON/text output. |
| scripts/python/setup_plan.py | Python port of setup-plan including template copy behavior and JSON-mode stderr status messages. |
| scripts/python/create_new_feature.py | Python port of create-new-feature including naming rules, numbering/timestamp modes, truncation, and feature.json persistence. |
| scripts/python/common.py | Adds resolve_template() and preset ordering helper to mirror Bash template resolution priority. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… hidden preset dirs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ships with the scripts they reference; the remaining templates got their py: lines in github#3403. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
resolve_skill_placeholders only accepted sh/ps, so a py init option
fell into the fallback path and {SCRIPT} rendered without an
interpreter prefix. Accept py and prefix the resolved interpreter,
matching process_template. Also guard ps_cmd against a missing
PowerShell with a clear assert.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot review |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/specify_cli/agents.py:495
- The fallback can select a variant that
--script pydid not install. For example, on Windows a command exposing onlysh(a supported extension-command shape) reaches the secondary fallback here, butshared_infra.py:406-410installs onlypythonpluspowershell; after path rewriting the generated command points to a missing.specify/scripts/bash/...file. Restrict fallback selection to variants guaranteed to be installed, or install whichever fallback is selected, and cover one-sided frontmatter on the opposite platform.
default_variant = (
"ps" if platform.system().lower().startswith("win") else "sh"
)
secondary_variant = "sh" if default_variant == "ps" else "ps"
if default_variant in scripts:
fallback_order.append(default_variant)
if secondary_variant in scripts:
fallback_order.append(secondary_variant)
for key in scripts:
if key not in fallback_order:
fallback_order.append(key)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot review |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot review |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot review |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot review |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/specify_cli/agents.py:486
- Skills use the same opposite-shell fallback, so a Windows
pyproject with only anshentry receives a bare.shinvocation that PowerShell cannot execute merely because the file was installed. Limit fallback to a runnable platform variant or surface a clear unsupported-variant error.
fallback_order = []
default_variant = (
"ps" if platform.system().lower().startswith("win") else "sh"
)
secondary_variant = "sh" if default_variant == "ps" else "ps"
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot review |
|
@mnriem Copilot’s current-head review on |
|
@marcelsafin Please address test & lint errors |
Description
Ports the three core workflow scripts to Python, per #3280. Follows the pattern established by the check-prerequisites PoC (#3302): additive port with parity tests that run the bash and Python versions side by side and compare output. Two small non-additive touches:
templates/commands/plan.mdandtemplates/commands/tasks.mdgain ascripts.pyentry, andresolve_skill_placeholdersacceptspyas a script variant (with interpreter prefixing and a fallback when a command's frontmatter lacks the configured variant).Scope:
scripts/python/create_new_feature.py— port ofcreate-new-feature.sh, including branch-name generation (stop words, acronym detection, word limits), feature numbering (specs scan + timestamp-dir handling), the 244-char ref-length truncation,--allow-existing-branchmode, andfeature.jsonpersistence (byte-identical to the jq output).scripts/python/setup_plan.py— port ofsetup-plan.sh, including plan template resolution and the status messages that go to stderr in--jsonmode.scripts/python/setup_tasks.py— port ofsetup-tasks.sh, including plan/spec validation and the tasks-template requirement.scripts/python/common.py— addsresolve_template()(overrides → presets via registry → extensions → core), shared by the three scripts above.src/specify_cli/integrations/base.pyandshared_infra.py— addpytemplate selection, interpreter prefixing, frontmatter-bounded script extraction, and Python-plus-platform-shell fallback installation.tests/parity_helpers.py— shared fixtures/helpers for parity tests, extracted from the pattern intest_check_prerequisites_python_parity.py.Testing
uv run specify --helpAI Disclosure
Ported and tested with GitHub Copilot CLI. I reviewed the diff and verified parity behavior manually.
Fixes #3280