diff --git a/scripts/refresh.py b/scripts/refresh.py index 252c278..f329cb1 100644 --- a/scripts/refresh.py +++ b/scripts/refresh.py @@ -116,10 +116,10 @@ def main(argv: list[str] | None = None) -> int: common.preflight_checks(["git", "buildx"]) cli = args.stellar_cli_version - data = builds.load() - entry = builds.find_cli(data, cli) try: + data = builds.load() + entry = builds.find_cli(data, cli) if args.rust_versions: labels = [k.strip() for k in args.rust_versions.split(",") if k.strip()] common.log(f"rust base labels (from --rust-versions): {' '.join(labels)}") diff --git a/scripts/validate_json.py b/scripts/validate_json.py index c5338e4..8e12a35 100755 --- a/scripts/validate_json.py +++ b/scripts/validate_json.py @@ -90,8 +90,12 @@ def main(argv: list[str] | None = None) -> int: builds_path = root / "builds.json" schema_path = root / "builds.schema.json" - builds_data = json.loads(builds_path.read_text()) - schema = json.loads(schema_path.read_text()) + try: + builds_data = json.loads(builds_path.read_text()) + schema = json.loads(schema_path.read_text()) + except (OSError, UnicodeDecodeError, json.JSONDecodeError) as exc: + common.err(f"could not load builds.json/builds.schema.json: {exc}") + return 1 ok &= check_schema(builds_data, schema) diff --git a/tests/integration/test_refresh.py b/tests/integration/test_refresh.py index 3abe4ab..c3dd7af 100644 --- a/tests/integration/test_refresh.py +++ b/tests/integration/test_refresh.py @@ -156,6 +156,17 @@ def test_creates_new_cli_entry(monkeypatch: pytest.MonkeyPatch, staged_minimal: assert [e["version"] for e in data["stellar_cli_versions"]] == ["26.0.0", "27.0.0"] +def test_malformed_builds_dies_cleanly(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + # A malformed builds.json must route through common.die() (SystemExit), + # not surface a raw JSONDecodeError from builds.load(). + target = tmp_path / "builds.json" + target.write_text("{ this is not valid json") + monkeypatch.setattr(builds, "DEFAULT_PATH", target) + monkeypatch.setattr(refresh.common, "preflight_checks", lambda _: None) + with pytest.raises(SystemExit): + refresh.main(["--stellar-cli-version", "26.0.0", "--rust-versions", "1.94.0-slim-trixie"]) + + def test_unresolvable_tag_dies(monkeypatch: pytest.MonkeyPatch, staged_minimal: Path) -> None: monkeypatch.setattr(refresh.common, "preflight_checks", lambda _: None) monkeypatch.setattr(refresh.git_remote, "resolve_tag_commit", lambda repo, tag: None) diff --git a/tests/unit/test_validate_json.py b/tests/unit/test_validate_json.py index d6e6dbc..a19e47f 100644 --- a/tests/unit/test_validate_json.py +++ b/tests/unit/test_validate_json.py @@ -91,3 +91,26 @@ def test_main_fails_on_invalid_entry( ) monkeypatch.setattr(validate_json.common, "repo_root", lambda: tmp_path) assert validate_json.main([]) == 1 + + +def test_main_returns_1_on_malformed_builds( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, fixtures_dir: Path +) -> None: + # A malformed builds.json must exit 1 cleanly, not raise JSONDecodeError. + (tmp_path / "builds.json").write_text("{ this is not valid json") + (tmp_path / "builds.schema.json").write_text( + (fixtures_dir.parent.parent / "builds.schema.json").read_text() + ) + monkeypatch.setattr(validate_json.common, "repo_root", lambda: tmp_path) + assert validate_json.main([]) == 1 + + +def test_main_returns_1_on_missing_builds( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, fixtures_dir: Path +) -> None: + # A missing builds.json must exit 1 cleanly, not raise FileNotFoundError. + (tmp_path / "builds.schema.json").write_text( + (fixtures_dir.parent.parent / "builds.schema.json").read_text() + ) + monkeypatch.setattr(validate_json.common, "repo_root", lambda: tmp_path) + assert validate_json.main([]) == 1