Skip to content

Commit 8d1f99b

Browse files
committed
Align malformed preset manifest handling
Assisted-by: GitHub Copilot (model: GPT-5.6 Sol, autonomous) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3158e06f-95df-4e3a-843f-f159a35aa30c
1 parent f633596 commit 8d1f99b

4 files changed

Lines changed: 39 additions & 6 deletions

File tree

‎scripts/bash/common.sh‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,15 @@ try:
676676
data = yaml.safe_load(f)
677677
if not isinstance(data, dict):
678678
raise ValueError('manifest root must be a mapping')
679-
for t in data.get('provides', {}).get('templates', []):
679+
provides = data.get('provides', {})
680+
if not isinstance(provides, dict):
681+
raise ValueError('manifest provides must be a mapping')
682+
templates = provides.get('templates', [])
683+
if not isinstance(templates, list):
684+
raise ValueError('manifest templates must be a list')
685+
for t in templates:
686+
if not isinstance(t, dict):
687+
raise ValueError('manifest template entries must be mappings')
680688
if t.get('name') == os.environ['SPECKIT_TMPL'] and t.get('type', 'template') == 'template':
681689
print('found\t' + t.get('strategy', 'replace') + '\t' + t.get('file', ''))
682690
sys.exit(0)

‎scripts/powershell/common.ps1‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,15 @@ try:
602602
data = yaml.safe_load(f)
603603
if not isinstance(data, dict):
604604
raise ValueError('manifest root must be a mapping')
605-
for t in data.get('provides', {}).get('templates', []):
605+
provides = data.get('provides', {})
606+
if not isinstance(provides, dict):
607+
raise ValueError('manifest provides must be a mapping')
608+
templates = provides.get('templates', [])
609+
if not isinstance(templates, list):
610+
raise ValueError('manifest templates must be a list')
611+
for t in templates:
612+
if not isinstance(t, dict):
613+
raise ValueError('manifest template entries must be mappings')
606614
if t.get('name') == sys.argv[2] and t.get('type', 'template') == 'template':
607615
print('found\t' + t.get('strategy', 'replace') + '\t' + t.get('file', ''))
608616
sys.exit(0)

‎scripts/python/common.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ def _preset_template_layer(
353353

354354
if manifest_path.is_file():
355355
try:
356-
manifest = yaml.safe_load(manifest_path.read_text(encoding="utf-8")) or {}
356+
manifest = yaml.safe_load(manifest_path.read_text(encoding="utf-8"))
357357
if not isinstance(manifest, dict):
358358
raise ValueError("manifest root must be a mapping")
359359
provides = manifest.get("provides", {})
@@ -363,9 +363,10 @@ def _preset_template_layer(
363363
if not isinstance(templates, list):
364364
raise ValueError("manifest templates must be a list")
365365
for entry in templates:
366+
if not isinstance(entry, dict):
367+
raise ValueError("manifest template entries must be mappings")
366368
if (
367-
not isinstance(entry, dict)
368-
or entry.get("name") != template_name
369+
entry.get("name") != template_name
369370
or entry.get("type", "template") != "template"
370371
):
371372
continue

‎tests/test_resolve_template_python_parity.py‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,13 +440,29 @@ def test_all_variants_fail_when_yaml_parser_is_unavailable(
440440

441441

442442
@requires_bash
443+
@pytest.mark.parametrize(
444+
"manifest_content",
445+
[
446+
"provides: [\n",
447+
"",
448+
"provides:\n templates:\n - null\n",
449+
"provides:\n templates: {}\n",
450+
],
451+
ids=[
452+
"invalid_yaml",
453+
"empty_document",
454+
"non_mapping_template_entry",
455+
"non_list_templates",
456+
],
457+
)
443458
def test_all_variants_fail_for_malformed_preset_manifest(
444459
tmp_path: Path,
460+
manifest_content: str,
445461
) -> None:
446462
repo, _ = _setup_repo(tmp_path)
447463
(
448464
repo / ".specify" / "presets" / "wrap-pack" / "preset.yml"
449-
).write_text("provides: [\n", encoding="utf-8")
465+
).write_text(manifest_content, encoding="utf-8")
450466

451467
results = [
452468
run(bash_cmd(repo, SCRIPT, TEMPLATE, "--json"), repo),

0 commit comments

Comments
 (0)