-
Notifications
You must be signed in to change notification settings - Fork 10.5k
feat(templates): add py: lines to command templates' scripts frontmatter #3403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
marcelsafin
wants to merge
4
commits into
github:main
Choose a base branch
from
marcelsafin:feat/3283-py-script-lines
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
9abc4a5
feat(templates): add py: lines to command templates' scripts frontmatter
marcelsafin aa7e627
fix: install scripts/python for the py script type
marcelsafin 1667e1b
test: read templates with explicit utf-8 encoding
marcelsafin ee3709f
fix: keep py: lines standalone, enforce script existence in tests
marcelsafin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| """Command templates with a py: script line must render for --script py. | ||
|
|
||
| Covers #3283: ``py:`` lines in the ``scripts:`` frontmatter of | ||
| ``templates/commands/*.md`` reference Python scripts that exist in the repo, | ||
| and ``process_template`` turns them into a valid Python invocation | ||
| (interpreter-prefixed, path rewritten to the ``.specify`` tree). | ||
|
|
||
| ``plan.md`` and ``tasks.md`` gain their ``py:`` lines together with | ||
| ``setup_plan.py``/``setup_tasks.py`` in the core-scripts port (#3280); the | ||
| existence check below enforces that ordering. | ||
| """ | ||
|
|
||
| import re | ||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
|
|
||
| from specify_cli.integrations.base import IntegrationBase | ||
|
|
||
| REPO_ROOT = Path(__file__).parent.parent | ||
| TEMPLATES_DIR = REPO_ROOT / "templates" / "commands" | ||
|
|
||
| _PY_LINE = re.compile(r"^\s*py: (scripts/python/\S+\.py)", re.MULTILINE) | ||
|
|
||
|
|
||
| def _py_script(name: str) -> str | None: | ||
| match = _PY_LINE.search((TEMPLATES_DIR / name).read_text(encoding="utf-8")) | ||
| return match.group(1) if match else None | ||
|
|
||
|
|
||
| PY_TEMPLATES = sorted( | ||
| p.name for p in TEMPLATES_DIR.glob("*.md") if _py_script(p.name) | ||
| ) | ||
|
|
||
|
|
||
| @pytest.fixture(autouse=True) | ||
| def _pin_interpreter(monkeypatch): | ||
| monkeypatch.setattr( | ||
| "specify_cli.integrations.base.shutil.which", | ||
| lambda name: "/usr/bin/python3" if name == "python3" else None, | ||
| ) | ||
|
|
||
|
|
||
| def test_py_templates_discovered(): | ||
| # Guard: the glob must find the known py-scripted templates, otherwise | ||
| # the parametrized tests below would silently pass on an empty set. | ||
| assert "implement.md" in PY_TEMPLATES | ||
| assert "clarify.md" in PY_TEMPLATES | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("name", PY_TEMPLATES) | ||
| def test_referenced_python_script_exists(name: str): | ||
| # A py: line must never point at a script the repo does not ship — | ||
| # rendering would produce a broken invocation at runtime. | ||
| script = _py_script(name) | ||
| assert (REPO_ROOT / script).is_file(), f"{name} references missing {script}" | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("name", PY_TEMPLATES) | ||
| def test_template_renders_python_invocation(name: str): | ||
| content = (TEMPLATES_DIR / name).read_text(encoding="utf-8") | ||
| result = IntegrationBase.process_template(content, "agent", "py") | ||
| assert "{SCRIPT}" not in result | ||
| assert re.search( | ||
| r"python3 \.specify/scripts/python/\w+\.py(?: --[\w-]+)*", result | ||
| ), f"{name} did not render a Python invocation" | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("name", PY_TEMPLATES) | ||
| def test_sh_rendering_unchanged(name: str): | ||
| # Negative: adding py: lines must not leak into sh rendering. | ||
| content = (TEMPLATES_DIR / name).read_text(encoding="utf-8") | ||
| result = IntegrationBase.process_template(content, "agent", "sh") | ||
| assert "{SCRIPT}" not in result | ||
| assert "scripts/python" not in result | ||
|
|
||
|
|
||
| def test_install_shared_infra_copies_python_scripts(tmp_path): | ||
| # --script py must install scripts/python/ into .specify/scripts/python/ | ||
| # so the rendered invocations point at files that exist. | ||
| from rich.console import Console | ||
|
|
||
| from specify_cli.shared_infra import install_shared_infra | ||
|
|
||
| install_shared_infra( | ||
| tmp_path, | ||
| "py", | ||
| version="0.0.0", | ||
| core_pack=None, | ||
| repo_root=REPO_ROOT, | ||
| console=Console(quiet=True), | ||
| force=False, | ||
| ) | ||
| dest = tmp_path / ".specify" / "scripts" / "python" | ||
| assert (dest / "check_prerequisites.py").is_file() | ||
| assert not (tmp_path / ".specify" / "scripts" / "powershell").exists() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, thanks.
install_shared_inframapped every non-shtype topowershell. Fixed in aa7e627:pynow maps to thepythonvariant dir (with__pycache__excluded from the copy), plus a test that runs the installer with--script pyand assertscheck_prerequisites.pylands in.specify/scripts/python/.