import importlib.util import pathlib import os import json import subprocess import tempfile import unittest import zipfile ROOT = pathlib.Path(__file__).resolve().parents[1] SPEC = importlib.util.spec_from_file_location("exporter", ROOT / "tools/export-private-modules.py") MODULE = importlib.util.module_from_spec(SPEC) SPEC.loader.exec_module(MODULE) class ExportTest(unittest.TestCase): def test_native_go_archive_excludes_nested_build_artifacts(self): with tempfile.TemporaryDirectory() as temporary: root = pathlib.Path(temporary) source = root / "source" source.mkdir() module = "example.invalid/fixture.git" (source / "go.mod").write_text("module " + module + "\n\ngo 1.27.0\n") (source / "provider.go").write_text("package fixture\n") boundary = source / "third_party/go-proxy" boundary.mkdir(parents=True) (boundary / "go.mod").write_text("module example.invalid/build-artifacts\n\ngo 1.27.0\n") (boundary / "provider.zip").write_bytes(b"must not enter the provider module archive") subprocess.run(["git", "init", "-q", str(source)], check=True) subprocess.run(["git", "-C", str(source), "add", "."], check=True) subprocess.run(["git", "-C", str(source), "-c", "user.name=Fixture", "-c", "user.email=fixture@example.invalid", "commit", "-qm", "fixture"], check=True) subprocess.run(["git", "-C", str(source), "tag", "v0.1.0"], check=True) config = root / "gitconfig" config.write_text('[url "' + source.as_uri() + '"]\n' '\tinsteadOf = https://example.invalid/fixture\n') # Let Go select the synthetic VCS URL; Git still permits only the # rewritten local file protocol, with no network scheme allowed. env = dict(os.environ, GO111MODULE="on", GOTOOLCHAIN="local", GOFLAGS="", GOWORK="off", GOPROXY="direct", GONOPROXY="none", GOSUMDB="off", GOVCS="*:git", GOINSECURE="example.invalid", GOMODCACHE=str(root / "cache"), GIT_CONFIG_GLOBAL=str(config), GIT_CONFIG_NOSYSTEM="1", GIT_CONFIG_COUNT="0", GIT_ALLOW_PROTOCOL="file") probe = subprocess.run(["git", "ls-remote", "https://example.invalid/fixture"], env=env, capture_output=True) self.assertEqual(probe.returncode, 0, probe.stderr.decode()) # Native Git accepts only the local file protocol: a missed rewrite # cannot turn this proof into a network or credential lookup. result = subprocess.run(["go", "mod", "download", "-json", module + "@v0.1.0"], cwd=root, env=env, capture_output=True) self.assertEqual(result.returncode, 0, result.stdout.decode() + result.stderr.decode()) archive = json.loads(result.stdout)["Zip"] with zipfile.ZipFile(archive) as zipped: names = zipped.namelist() self.assertIn(module + "@v0.1.0/provider.go", names) self.assertFalse(any("third_party/go-proxy" in name for name in names)) def test_committed_bytes_and_provenance_are_exact(self): with tempfile.TemporaryDirectory() as temporary: base = pathlib.Path(temporary) source, target = base / "source", base / "target" source.mkdir() target.mkdir() subprocess.run(["git", "init", "-q", str(source)], check=True) for path in MODULE.FILES: file = source / path file.parent.mkdir(parents=True, exist_ok=True) file.write_text("package main\n") subprocess.run(["git", "-C", str(source), "add", "."], check=True) subprocess.run(["git", "-C", str(source), "-c", "user.name=Fixture", "-c", "user.email=fixture@example.invalid", "commit", "-qm", "fixture"], check=True) revision = MODULE.committed(source, "rev-parse", "HEAD").decode().strip() (source / next(iter(MODULE.FILES))).write_text("dirty worktree must be ignored") MODULE.export(source, target, revision) MODULE.export(source, target, revision, True) subprocess.run(["sha256sum", "-c", "tools/private-modules.sha256"], cwd=target, check=True, stdout=subprocess.DEVNULL) destination = target / "tools/private-modules.go" self.assertEqual(destination.read_text(), "package main\n") destination.write_text("changed") with self.assertRaises(ValueError): MODULE.export(source, target, revision, True) destination.unlink() destination.symlink_to(source / next(iter(MODULE.FILES))) with self.assertRaises(ValueError): MODULE.export(source, target, revision) with self.assertRaises(ValueError): MODULE.export(source, target, "HEAD") if __name__ == "__main__": unittest.main()