Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
111 lines
3.8 KiB
Python
111 lines
3.8 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
from repo_manager.sbom import detect_sources, scan_repository
|
|
|
|
|
|
def _git(repo: Path, *args: str) -> None:
|
|
subprocess.run(["git", *args], cwd=repo, check=True, capture_output=True)
|
|
|
|
|
|
def test_scan_derives_snapshot_and_copyleft_report(tmp_path: Path) -> None:
|
|
repo = tmp_path / "example"
|
|
repo.mkdir()
|
|
_git(repo, "init")
|
|
_git(repo, "config", "user.email", "test@example.com")
|
|
_git(repo, "config", "user.name", "Test")
|
|
(repo / "uv.lock").write_text(
|
|
'version = 1\n[[package]]\nname = "pyyaml"\nversion = "6.0.2"\n',
|
|
encoding="utf-8",
|
|
)
|
|
(repo / "package-lock.json").write_text(
|
|
json.dumps(
|
|
{
|
|
"packages": {
|
|
"": {"name": "root", "version": "1.0.0"},
|
|
"node_modules/copyleft": {
|
|
"name": "copyleft",
|
|
"version": "2.0.0",
|
|
"license": "GPL-3.0-only",
|
|
},
|
|
"node_modules/dev-only": {
|
|
"name": "dev-only",
|
|
"version": "3.0.0",
|
|
"license": "AGPL-3.0-only",
|
|
"dev": True,
|
|
},
|
|
}
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
_git(repo, "add", ".")
|
|
_git(repo, "commit", "-m", "seed")
|
|
|
|
result = scan_repository(repo)
|
|
|
|
assert result["ok"] is True
|
|
assert result["schema"] == "repo-manager.sbom-snapshot.v1"
|
|
assert result["source_revision"]
|
|
assert result["generated_at"].endswith("Z")
|
|
assert result["entry_count"] == 3
|
|
assert result["licence_report"]["copyleft_direct_count"] == 1
|
|
assert result["licence_report"]["copyleft_direct_prod"][0]["package_name"] == "copyleft"
|
|
|
|
|
|
def test_detection_covers_sources_and_skips_dependency_directories(tmp_path: Path) -> None:
|
|
(tmp_path / "go.sum").write_text("example.test/mod v1.2.3 h1:abc\n", encoding="utf-8")
|
|
terraform = tmp_path / "infra"
|
|
terraform.mkdir()
|
|
(terraform / ".terraform.lock.hcl").write_text(
|
|
'provider "registry.terraform.io/hashicorp/null" {\n version = "3.2.3"\n}\n',
|
|
encoding="utf-8",
|
|
)
|
|
ansible = tmp_path / "deploy" / "ansible"
|
|
ansible.mkdir(parents=True)
|
|
(ansible / "requirements.yml").write_text("collections:\n - community.general\n", encoding="utf-8")
|
|
ignored = tmp_path / "node_modules"
|
|
ignored.mkdir()
|
|
(ignored / "package-lock.json").write_text("{}", encoding="utf-8")
|
|
|
|
sources = {str(path.relative_to(tmp_path)) for path, _parser in detect_sources(tmp_path)}
|
|
|
|
assert sources == {
|
|
"deploy/ansible/requirements.yml",
|
|
"go.sum",
|
|
"infra/.terraform.lock.hcl",
|
|
}
|
|
|
|
|
|
def test_go_sum_marks_modules_declared_in_go_mod_as_direct(tmp_path: Path) -> None:
|
|
(tmp_path / "go.mod").write_text(
|
|
"module example.test/app\n\nrequire example.test/direct v1.2.3\n",
|
|
encoding="utf-8",
|
|
)
|
|
(tmp_path / "go.sum").write_text(
|
|
"example.test/direct v1.2.3 h1:abc\n"
|
|
"example.test/direct v1.2.3/go.mod h1:def\n"
|
|
"example.test/transitive v2.0.0 h1:ghi\n",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
result = scan_repository(tmp_path)
|
|
|
|
assert result["ok"] is True
|
|
assert [(entry["package_name"], entry["is_direct"]) for entry in result["entries"]] == [
|
|
("example.test/direct", True),
|
|
("example.test/transitive", False),
|
|
]
|
|
|
|
|
|
def test_invalid_source_is_reported_without_partial_failure(tmp_path: Path) -> None:
|
|
(tmp_path / "uv.lock").write_text("not = [valid", encoding="utf-8")
|
|
|
|
result = scan_repository(tmp_path)
|
|
|
|
assert result["ok"] is False
|
|
assert result["entry_count"] == 0
|
|
assert result["errors"][0]["source_path"] == "uv.lock"
|