mirror of
https://github.com/github/spec-kit.git
synced 2026-08-15 14:02:04 +02:00
fix(events): return None for an unparseable script command (#3957)
_script_command() split the configured command with a bare shlex.split(), so a command string with unbalanced quotes crashed event dispatch with a raw ValueError. The dispatcher-template twin a few lines up already wraps the same call in try/except ValueError and returns None so dispatch falls back cleanly. Wrap the split the same way and return None, restoring parity between the two paths. Assisted-by: GitHub Copilot (model: claude-fable-5, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -584,7 +584,13 @@ def _resolve_event_command_argv(
|
||||
else:
|
||||
base = project_root / ".specify"
|
||||
|
||||
tokens = shlex.split(script_cmd, posix=(os.name != "nt"))
|
||||
try:
|
||||
tokens = shlex.split(script_cmd, posix=(os.name != "nt"))
|
||||
except ValueError:
|
||||
# Mirror the generated dispatcher's _resolve_argv: a scripts: value
|
||||
# shlex cannot tokenize (e.g. an unclosed quote) declares no runnable
|
||||
# script, so degrade to "no argv" instead of raising.
|
||||
return None
|
||||
if not tokens:
|
||||
return None
|
||||
script_abs = base / tokens[0]
|
||||
|
||||
@@ -1186,6 +1186,32 @@ class TestCommandRunner:
|
||||
assert PurePath(argv[1]).as_posix().endswith(".specify/scripts/python/boot.py")
|
||||
assert ".specify" in argv[1]
|
||||
|
||||
def test_unparseable_script_command_returns_none(self, tmp_path):
|
||||
"""A ``scripts:`` value shlex cannot tokenize must resolve to no argv.
|
||||
|
||||
The generated dispatcher's ``_resolve_argv`` twin wraps its
|
||||
``shlex.split`` in ``except ValueError: return None``, but the
|
||||
CLI-side resolver did not: an unclosed quote in a ``scripts:``
|
||||
frontmatter value raised a raw ``ValueError: No closing quotation``
|
||||
through ``resolve_and_run_event_command`` instead of degrading to
|
||||
"no runnable script" like every other malformed-input case here.
|
||||
"""
|
||||
from specify_cli.events import _resolve_event_command_argv
|
||||
|
||||
cmd_dir = tmp_path / ".specify" / "templates" / "commands"
|
||||
cmd_dir.mkdir(parents=True)
|
||||
(cmd_dir / "boot.md").write_text(
|
||||
"---\n"
|
||||
"description: \"Boot\"\n"
|
||||
"scripts:\n"
|
||||
" sh: scripts/bash/boot.sh \"unclosed\n"
|
||||
"---\nBody\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
argv = _resolve_event_command_argv(cmd_dir / "boot.md", tmp_path, None)
|
||||
assert argv is None
|
||||
|
||||
def test_ps_variant_prefixed_with_powershell_launcher(self, tmp_path):
|
||||
"""S6: the ps variant prefixes argv with pwsh/powershell -File so
|
||||
subprocess.run(shell=False) can execute the .ps1 script."""
|
||||
|
||||
Reference in New Issue
Block a user