fix: refuse a restore without its asset registry

gitignored_paths read a missing file as an empty registry: nothing to
restore, nothing unsatisfied, exit 0 with every release asset absent.
The run now stops with the path it could not read.
This commit is contained in:
Abdessamad Derraz committed 2026-11-06 15:13:05 +01:00
1 parent 64ed86cd5f
commit 6d1e8e36fc
2 files changed
+30 -8

No files matched your search

+11 -8
View File
@@ -29,14 +29,15 @@ from common import copy_file_atomic, load_database
def gitignored_paths(gitignore: str) -> set[str]:
"""Paths the repository keeps out of git, as written in .gitignore."""
try:
with open(gitignore) as f:
return {
line.strip() for line in f if line.strip().startswith("bios/")
}
except FileNotFoundError:
return set()
"""Paths the repository keeps out of git, as written in .gitignore.
A missing file raises: read as empty, it left nothing to restore and
nothing unsatisfied, and the run exited 0 with every asset absent.
"""
with open(gitignore) as f:
return {
line.strip() for line in f if line.strip().startswith("bios/")
}
def index_cache(cache_dir: str) -> dict[str, str]:
@@ -144,6 +145,8 @@ def main() -> None:
help="the .gitignore listing release-asset files (default: %(default)s)",
)
args = parser.parse_args()
if not os.path.isfile(args.gitignore):
parser.error(f"no file at {args.gitignore}: it lists the release assets")
_restored, unsatisfied = restore(args.cache, args.db, args.gitignore)
if unsatisfied:
raise SystemExit(1)
+19
View File
@@ -2061,6 +2061,25 @@ class CheckoutCompletenessRegressions(unittest.TestCase):
finally:
os.chdir(cwd)
def test_restore_without_its_registry_fails(self):
"""A mistyped --gitignore read as an empty registry: nothing to
restore, nothing unsatisfied, exit 0 with every asset absent."""
import subprocess
from scripts.restore_large_files import gitignored_paths
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as directory:
missing = str(Path(directory) / "absent")
with self.assertRaises(FileNotFoundError):
gitignored_paths(missing)
proc = subprocess.run(
[sys.executable, str(ROOT / "scripts" / "restore_large_files.py"),
"--gitignore", missing, "--cache", directory],
capture_output=True, text=True, timeout=120,
)
self.assertEqual(proc.returncode, 2, proc.stdout + proc.stderr)
self.assertIn("lists the release assets", proc.stderr)
def test_restore_refuses_a_copy_replaced_after_the_index(self):
"""The cache is hashed first and copied later: another run that
replaced the cached name in between put its bytes at a path the