aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-07 20:21:27 +0200
committerDanilo M. <danix@danix.xyz>2026-07-07 20:24:29 +0200
commit870b97b0ace6792b18a710e85f78bf7731efa326 (patch)
tree230fdd25f89b820efbe9090744c813b94f2f0387
parentd792150c601c2f516ed9360d9ce6aad0bf6257f5 (diff)
downloadmkhintfile-870b97b0ace6792b18a710e85f78bf7731efa326.tar.gz
mkhintfile-870b97b0ace6792b18a710e85f78bf7731efa326.zip
fix: reconcile backup, versioned change report, no double reportv1.2.0
Review findings before v1.2.0 deploy: - apply mode now writes a .bak before mutating (parity with every other mutator; the --force recovery path had no rollback) - the changed-deps report shows old->new basenames so bumps are visible, not the version-stripped 'dep -> dep' - apply mode no longer re-prints the report (report/apply split) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--CHANGELOG.md4
-rwxr-xr-xmkhint23
-rwxr-xr-xtests/mkhint_test.sh53
3 files changed, 71 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c5a156f..bb42635 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,10 @@ All notable changes to this project are documented here. The format is based on
reconcile without changing the hint.
- `--force` flag (check-only): run the bundled-dep reconcile even when the
primary version is unchanged (e.g. to retry after a failed manifest fetch).
+- The bundled-dep reconcile writes a `.bak` before mutating a hint (parity with
+ every other mutator, so a `--force` reconcile is recoverable), and its change
+ report shows old and new URL basenames so version bumps are visible before you
+ confirm.
## [1.1.3] - 2026-07-07
diff --git a/mkhint b/mkhint
index 1e171d9..e606f86 100755
--- a/mkhint
+++ b/mkhint
@@ -598,25 +598,30 @@ reconcile_bundle_deps() {
for m in "${manifest_urls[@]}"; do
[[ -z "${matched_manifest[$m]:-}" ]] && extra+=("$(_dep_label "$m")")
done
- if [[ ${#extra[@]} -gt 0 ]]; then
+ if [[ ${#extra[@]} -gt 0 && "$mode" == report ]]; then
echo "$pkg: manifest has ${#extra[@]} deps not in hint:"
printf '%s\n' "${extra[@]}"
fi
if [[ ${#changed_idx[@]} -eq 0 ]]; then
- echo " $pkg: bundled deps all current"
+ [[ "$mode" == report ]] && echo " $pkg: bundled deps all current"
return 0
fi
- echo ""
- echo "$pkg bundled deps changed upstream:"
- for (( i=0; i<${#changed_idx[@]}; i++ )); do
- printf ' %s -> %s\n' "$(_dep_label "${changed_from[$i]}")" "$(_dep_label "${changed_to[$i]}")"
- done
-
- [[ "$mode" == report ]] && return 0
+ if [[ "$mode" == report ]]; then
+ echo ""
+ echo "$pkg bundled deps changed upstream:"
+ for (( i=0; i<${#changed_idx[@]}; i++ )); do
+ printf ' %s -> %s\n' "${changed_from[$i]##*/}" "${changed_to[$i]##*/}"
+ done
+ return 0
+ fi
# apply mode: recompute md5 only for changed lines, rewrite DOWNLOAD+MD5SUM.
+ # Back up first (mkhint convention) — only reached when there is something
+ # to write, since the no-change case already returned above.
+ cp "$hint" "${hint}.bak"
+
local -a new_md5s=("${md5s[@]}")
local idx md5
for idx in "${changed_idx[@]}"; do
diff --git a/tests/mkhint_test.sh b/tests/mkhint_test.sh
index a684fe7..1afda97 100755
--- a/tests/mkhint_test.sh
+++ b/tests/mkhint_test.sh
@@ -1777,6 +1777,59 @@ grep -q 'VERSION="0.14.0"' "$MOCK_HINT/bmnvim.hint" \
|| { echo " FAIL: -f -V parity:"; cat "$MOCK_HINT/bmnvim.hint"; (( FAIL++ )); ERRORS+=("T-BM18"); }
rm -f "$MOCK_BASE/manifest_fixture" "$MOCK_BASE/bundle-manifests" "$MOCK_HINT/bmnvim.hint"
+# ── T-BM19: --check --force apply writes a .bak before rewriting the hint ────
+echo ""
+echo "T-BM19: --check --force reconcile apply creates a .bak with original content"
+setup_bmnvim_check
+rm -f "$MOCK_HINT/bmnvim.hint.bak"
+run_mkhint -C --force bmnvim < <(printf 'Y\n') >/dev/null 2>&1 || true
+[[ -f "$MOCK_HINT/bmnvim.hint.bak" ]] && grep -q 'v0.26.7' "$MOCK_HINT/bmnvim.hint.bak" \
+ && { echo " PASS: .bak created with original (pre-bump) content"; (( PASS++ )); } \
+ || { echo " FAIL: .bak missing or wrong content"; ls "$MOCK_HINT"; (( FAIL++ )); ERRORS+=("T-BM19"); }
+rm -f "$MOCK_BASE/manifest_fixture" "$MOCK_BASE/bundle-manifests" "$MOCK_HINT/bmnvim.hint" "$MOCK_HINT/bmnvim.hint.bak"
+
+# ── T-BM20: --check --force with deps already current does NOT create a .bak ─
+echo ""
+echo "T-BM20: --check --force, bundled deps already current → no .bak churn"
+setup_bmnvim_check
+# Make the hint's tree-sitter dep URL byte-identical to the manifest's so
+# reconcile finds no change (match_dep_url compares full URL strings, not
+# just versions — the manifest fixture uses a bare archive/vX.Y.Z.tar.gz
+# shape, so the hint line must match that exact shape here).
+sed -i 's#tree-sitter/archive/v0.26.7/tree-sitter-0.26.7.tar.gz#tree-sitter/archive/v0.26.8.tar.gz#' "$MOCK_HINT/bmnvim.hint"
+rm -f "$MOCK_HINT/bmnvim.hint.bak"
+run_mkhint -C --force bmnvim < <(printf 'Y\n') >/dev/null 2>&1 || true
+[[ ! -f "$MOCK_HINT/bmnvim.hint.bak" ]] \
+ && { echo " PASS: no .bak written on no-op reconcile"; (( PASS++ )); } \
+ || { echo " FAIL: .bak written despite no changes"; (( FAIL++ )); ERRORS+=("T-BM20"); }
+rm -f "$MOCK_BASE/manifest_fixture" "$MOCK_BASE/bundle-manifests" "$MOCK_HINT/bmnvim.hint" "$MOCK_HINT/bmnvim.hint.bak"
+
+# ── T-BM21: changed-deps report shows old and new versions, not bare names ───
+echo ""
+echo "T-BM21: reconcile changed-deps report shows versions on both sides"
+cat > "$MOCK_BASE/manifest_fixture" << 'EOF'
+NVIM_URL https://github.com/neovim/neovim/archive/v0.13.0.tar.gz
+NVIM_SHA256 a
+TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.26.8.tar.gz
+TREESITTER_SHA256 b
+EOF
+cat > "$MOCK_HINT/nvim.hint" << 'EOF'
+VERSION="0.13.0"
+DOWNLOAD="https://github.com/neovim/neovim/archive/v0.13.0/neovim-0.13.0.tar.gz \
+ https://github.com/tree-sitter/tree-sitter/archive/v0.26.7/tree-sitter-0.26.7.tar.gz"
+MD5SUM="aaa \
+ bbb"
+DOWNLOAD_x86_64=""
+MD5SUM_x86_64=""
+ARCH="x86_64"
+EOF
+rep=$(bash -c "TMP_DIR='$MOCK_TMP'; PATH=\"$MOCK_BASE/bin:\$PATH\"; source '$SCRIPT' 2>/dev/null; reconcile_bundle_deps nvim '$MOCK_HINT/nvim.hint' 'https://x/deps.txt' report" 2>&1) || true
+arrow_line=$(echo "$rep" | grep -- '->')
+echo "$arrow_line" | grep -q '0.26.7' && echo "$arrow_line" | grep -q '0.26.8' \
+ && { echo " PASS: report shows old and new versions"; (( PASS++ )); } \
+ || { echo " FAIL: report versions. out=$rep"; (( FAIL++ )); ERRORS+=("T-BM21"); }
+rm -f "$MOCK_BASE/manifest_fixture" "$MOCK_HINT/nvim.hint"
+
# ─── SUMMARY ──────────────────────────────────────────────────────────────────
teardown