fix: delete stale index-v2-<hash>.json files from prior rehash runs
Build fdroidserver-ipfs image / build (push) Successful in 1m10s

Without this, every update left another renamed index lying in repo/
forever — pinning the repo to IPFS would keep re-pinning all of them.

Also strip a pre-existing -<hex12> suffix from the stem before computing
the new one, so re-running rehash standalone (without an intervening
fdroid update) is idempotent instead of producing index-v2-abc-def.json.

diff/*.json doesn't need the same treatment: fdroidserver's make_v2()
already wipes the whole diff/ directory at the start of every update.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mrambossek
2026-05-24 22:54:10 +02:00
co-authored by Claude Opus 4.7
parent a6168221d1
commit 917ddbe550
+27 -1
View File
@@ -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-<hash>.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)