diff --git a/rehash.py b/rehash.py index a5d1654..cada03d 100644 --- a/rehash.py +++ b/rehash.py @@ -15,6 +15,7 @@ import argparse import hashlib import json import os +import re import subprocess import sys from pathlib import Path @@ -35,6 +36,10 @@ from fdroidserver import common, signindex HASH_SUFFIX_LEN = 12 +# Matches a trailing "-<12 lowercase hex>" right before the extension. Used to +# strip the prior suffix when re-rehashing the same file, so we don't accrete +# index-v2-abc-def-ghi.json from repeated runs. +_HASH_SUFFIX_RE = re.compile(r'-[0-9a-f]{12}$') def sha256_last_chars(path: Path) -> str: @@ -50,12 +55,30 @@ def write_entry_json(entry: dict, path: Path) -> None: json.dump(entry, fp, ensure_ascii=False, sort_keys=True) +def cleanup_stale_indexes(repodir: Path, keep_filename: str) -> None: + """Remove leftover index-v2-.json files (and their .asc) from prior runs. + + `fdroid update` always writes the fresh index back to the stable + `index-v2.json` name, so anything matching `index-v2-*.json` in this + directory is from a previous rehash. Skip `keep_filename` to make + re-running the script standalone safe. + """ + for stale in repodir.glob('index-v2-*.json'): + if stale.name == keep_filename: + continue + stale.unlink() + asc = stale.with_suffix(stale.suffix + '.asc') + if asc.exists(): + asc.unlink() + + def rehash_entry_file(repodir: Path, file_entry: dict) -> None: """Rename the file referenced by file_entry["name"] and update name/ipfsCIDv1 in place.""" old_rel = file_entry['name'].lstrip('/') old_path = repodir / old_rel suffix = sha256_last_chars(old_path) - new_path = old_path.with_name(f"{old_path.stem}-{suffix}{old_path.suffix}") + base_stem = _HASH_SUFFIX_RE.sub('', old_path.stem) + new_path = old_path.with_name(f"{base_stem}-{suffix}{old_path.suffix}") cid = common.calculate_IPFS_cid(str(old_path)) @@ -76,6 +99,9 @@ def rehash_repodir(repodir_name: str) -> bool: with entry_json.open(encoding='utf-8') as fp: entry = json.load(fp) + current_index = Path(entry['index']['name'].lstrip('/')).name + cleanup_stale_indexes(repodir, keep_filename=current_index) + rehash_entry_file(repodir, entry['index']) for diff_entry in entry.get('diffs', {}).values(): rehash_entry_file(repodir, diff_entry)