summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-08 12:11:02 +0200
committerDanilo M. <danix@danix.xyz>2026-07-08 12:11:02 +0200
commit6de9cec3ff26620c6e11de0dc426310346d7786c (patch)
treeb6ce6a6bb6d351f0931b809dcc16e05ffe0a2660
parent9b57db37b6dca87247e30b1e5e2259094c7157b5 (diff)
downloadmkhintfile-6de9cec3ff26620c6e11de0dc426310346d7786c.tar.gz
mkhintfile-6de9cec3ff26620c6e11de0dc426310346d7786c.zip
feat: suppress continuation-URL prompt for manifest-listed pkgs; release v1.2.4v1.2.4
On a primary version bump of a manifest-listed package, mkhint used to prompt interactively for each extra DOWNLOAD (continuation) URL, then Phase 2 (reconcile_bundle_deps) rewrote those same lines from the upstream manifest — a pointless double-touch (13 prompts for neovim). update_hint_file now detects a listed package and threads a skip_cont flag through update_checksums -> _process_download_var, which leaves the continuation URLs for the manifest reconcile and prints a short notice instead of prompting. Non-listed packages prompt exactly as before. Also fixes a set -e abort: the manifest-lookup guard was written as `pkg_has_manifest ... && _skip_cont=1`, whose false result (non-listed package) killed the run right after the backup. Rewritten as an if. This would have broken every non-listed --hintfile -V update. Verified live on a non-listed multiline package (exploitdb). Tests: T-BM18 now asserts the listed-pkg suppression, T-BM25 guards against over-suppression (non-listed still prompts); the read -p prompt is invisible under piped stdin, so both assert on the always-echoed "line N (current)" header. 184 passed. Also defers the multi-file split TODO with a rationale and revisit triggers (extract only the bundled-dep block when the time comes). Bump MKHINT_VERSION and man title to 1.2.4, rebuild mkhint.1.gz. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--CHANGELOG.md16
-rw-r--r--TODO.md2
-rwxr-xr-xmkhint36
-rw-r--r--mkhint.1.gzbin3485 -> 3536 bytes
-rw-r--r--mkhint.1.md6
-rwxr-xr-xtests/mkhint_test.sh37
6 files changed, 82 insertions, 15 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8bad93d..798a049 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,22 @@ All notable changes to this project are documented here. The format is based on
[Keep a Changelog](https://keepachangelog.com/), and this project adheres to
[Semantic Versioning](https://semver.org/).
+## [1.2.4] - 2026-07-08
+
+### Changed
+- On a primary version bump of a manifest-listed package, the interactive
+ continuation-URL prompt is now suppressed: those extra `DOWNLOAD` lines are
+ owned by Phase 2 (`reconcile_bundle_deps`), so hand-editing them during the
+ bump was a pointless double-touch. Non-listed packages still prompt as before.
+ Threaded via a `skip_cont` flag through `update_hint_file` →
+ `update_checksums` → `_process_download_var`.
+
+### Fixed
+- `update_hint_file` no longer aborts (`set -e`) right after backing up when the
+ package has no bundle manifest: the manifest-lookup guard was written as
+ `pkg_has_manifest ... && x=1`, whose false result killed the run. This would
+ have broken every non-listed `--hintfile -V` update.
+
## [1.2.3] - 2026-07-08
### Fixed
diff --git a/TODO.md b/TODO.md
index 7ba7907..ac48326 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,7 +2,7 @@
- [x] **v1.2.1/1.2.2 (bug): reconcile change-detection is version-aware.** 1.2.1 switched `reconcile_bundle_deps` to detect change via `_url_version` (parsed version, not raw URL string) but mis-parsed several real URL shapes; 1.2.2 completes it. `_url_version` strips the URL's own github repo name from the basename (handles digit/dash dep names like `lua-compat-5.3`, bare-tag package-rev suffixes like `1.52.1-0`, sha pins), and `_url_repo` is lowercased (fixes the `JuliaStrings/utf8proc` vs `juliastrings/utf8proc` case mismatch that had utf8proc reporting no-match + in the FYI). Report shows `name old-ver -> new-ver`. Verified against all 13 live neovim 0.12.4 deps: all match + current, no false change, real bump still detected. Tests T-BM17/22/23. Compares version strings only, not `NAME_SHA256`; add sha compare if a same-version-different-content case ever appears.
- [ ] add a `--special` flag to add a package to the bundled list, asking for a link to it's upstream deps list file
- - [ ] consider splitting `mkhint` into multiple files for easier maintenance
+ - [~] split `mkhint` into multiple files — **deferred (2026-07-08).** 1568 lines / 46 functions with clear section markers is under the threshold where a split pays off, and bash has no module system: "split" means `source lib/*.sh`, which complicates the single-binary VM deploy (`scp mkhint` → copy a dir + fixed libdir, or a concatenate build step) and means auditing shared globals (`REPO_DIR`, `VERSION`, `FORCE`, config-source order) crossing file boundaries. Revisit trigger: file grows toward ~2500+ lines, OR a change to one area starts breaking an unrelated one, OR you can't find where something lives. When that happens, extract ONLY the self-contained bundled-dep block (`# ── bundled-dep manifest handling ──` … `# ── end`, already has begin/end markers and its own T-BM tests) as a single `lib/bundle.sh` — do not do a full teardown.
- [ ] add a noDL column to `--list` similar to what we do with DelReq
- [ ] suppress `prompt_continuation_urls` for manifest-listed packages (Phase 2 already corrects those lines; avoids the double-touch during the primary bump)
- [ ] `--check --dry-run`: report what would change across all listed packages without prompting or writing (audit before acting)
diff --git a/mkhint b/mkhint
index 5fc08db..6a0f157 100755
--- a/mkhint
+++ b/mkhint
@@ -45,7 +45,7 @@ if [[ ! -d $TMP_DIR ]]; then
mkdir $TMP_DIR
fi
-readonly MKHINT_VERSION="1.2.3"
+readonly MKHINT_VERSION="1.2.4"
# Variables
VERSION=""
@@ -992,11 +992,17 @@ suggest_version() {
}
# Download files and update MD5SUM/MD5SUM_x86_64 in hint file
+# update_checksums <file> [skip_continuation_prompt]
+# skip_continuation_prompt=1 leaves continuation (index >= 1) URLs untouched and
+# does not prompt for them — used for manifest-listed packages, whose extra
+# lines Phase 2 (reconcile_bundle_deps) rewrites from the upstream manifest, so
+# hand-editing them here would be a pointless double-touch.
update_checksums() {
local file="$1"
+ local skip_cont="${2:-0}"
- _process_download_var "DOWNLOAD" "MD5SUM" "$file"
- _process_download_var "DOWNLOAD_x86_64" "MD5SUM_x86_64" "$file"
+ _process_download_var "DOWNLOAD" "MD5SUM" "$file" "$skip_cont"
+ _process_download_var "DOWNLOAD_x86_64" "MD5SUM_x86_64" "$file" "$skip_cont"
}
# Process one DOWNLOAD/MD5SUM variable pair in a hint file
@@ -1004,6 +1010,7 @@ _process_download_var() {
local dl_var="$1"
local md5_var="$2"
local file="$3"
+ local skip_cont="${4:-0}"
# Read current URLs into array
mapfile -t urls < <(parse_multiline_var "$dl_var" "$file")
@@ -1017,11 +1024,17 @@ _process_download_var() {
# Save original URLs for change detection after prompt
local orig_urls=("${urls[@]}")
- # Prompt user to update continuation URLs if present
+ # Prompt user to update continuation URLs if present. Skipped for
+ # manifest-listed packages: Phase 2 (reconcile_bundle_deps) owns those lines.
if (( ${#urls[@]} > 1 )); then
- echo ""
- echo "Multiline ${dl_var} detected in $(basename "$file")."
- prompt_continuation_urls urls "$dl_var"
+ if [[ "$skip_cont" == 1 ]]; then
+ echo ""
+ echo "Multiline ${dl_var} in $(basename "$file"): continuation URLs left to bundled-dep reconcile."
+ else
+ echo ""
+ echo "Multiline ${dl_var} detected in $(basename "$file")."
+ prompt_continuation_urls urls "$dl_var"
+ fi
fi
# Download and calculate md5 for each URL
@@ -1099,7 +1112,14 @@ update_hint_file() {
sed -i "s/${old_version//_/-}/${new_version//_/-}/g" "$normalized_file"
fi
- update_checksums "$normalized_file"
+ # For manifest-listed packages, skip the continuation-URL prompt — Phase 2
+ # (reconcile_bundle_deps) rewrites those lines from the upstream manifest.
+ load_bundle_manifests
+ local _pkg="${normalized_file%.hint}"; _pkg="${_pkg##*/}"
+ local _skip_cont=0
+ if pkg_has_manifest "$_pkg"; then _skip_cont=1; fi
+
+ update_checksums "$normalized_file" "$_skip_cont"
if [[ $NO_DL -eq 1 ]]; then
add_nodownload "$normalized_file"
diff --git a/mkhint.1.gz b/mkhint.1.gz
index cf7295c..37815c5 100644
--- a/mkhint.1.gz
+++ b/mkhint.1.gz
Binary files differ
diff --git a/mkhint.1.md b/mkhint.1.md
index 5659145..f01be66 100644
--- a/mkhint.1.md
+++ b/mkhint.1.md
@@ -1,4 +1,4 @@
-% MKHINT(1) mkhint 1.2.3 | User Commands
+% MKHINT(1) mkhint 1.2.4 | User Commands
% Danilo M.
% July 2026
@@ -231,7 +231,9 @@ upstream version differs, not merely its URL path shape, so a manifest's
bare-tag archive URL and the hint's SBo-fetched tree URL at the same version
are treated as current. Bundled deps are never followed to their
own latest release; only the manifest's pinned URLs are used. Manifest entries
-with no matching download line are reported but not added.
+with no matching download line are reported but not added. During the primary
+version bump of a listed package, **mkhint** does not prompt to edit the extra
+download lines by hand, since the manifest reconcile owns them.
# SEE ALSO
diff --git a/tests/mkhint_test.sh b/tests/mkhint_test.sh
index 30383d2..85d988d 100755
--- a/tests/mkhint_test.sh
+++ b/tests/mkhint_test.sh
@@ -1860,14 +1860,43 @@ DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
ARCH="x86_64"
EOF
-# stdin: continuation-URL prompt(s) for the primary bump, then apply Y, then slackrepo n
-run_mkhint -f bmnvim -V 0.14.0 < <(printf '\nY\nn\n') >/dev/null 2>&1 || true
+# stdin: apply Y, then slackrepo n. NO continuation-URL prompt: bmnvim is
+# manifest-listed, so the primary bump must NOT ask for the extra URLs.
+out=$(run_mkhint -f bmnvim -V 0.14.0 < <(printf 'Y\nn\n') 2>&1) || true
grep -q 'VERSION="0.14.0"' "$MOCK_HINT/bmnvim.hint" \
&& grep -q 'tree-sitter/archive/v0.26.8' "$MOCK_HINT/bmnvim.hint" \
- && { echo " PASS: -f -V bumped primary + reconciled deps"; (( PASS++ )); } \
- || { echo " FAIL: -f -V parity:"; cat "$MOCK_HINT/bmnvim.hint"; (( FAIL++ )); ERRORS+=("T-BM18"); }
+ && echo "$out" | grep -q 'left to bundled-dep reconcile' \
+ && ! echo "$out" | grep -q 'line 2 (current)' \
+ && { echo " PASS: -f -V bumped primary + reconciled deps, no continuation prompt"; (( PASS++ )); } \
+ || { echo " FAIL: -f -V parity/suppression. out=$out"; cat "$MOCK_HINT/bmnvim.hint"; (( FAIL++ )); ERRORS+=("T-BM18"); }
rm -f "$MOCK_BASE/manifest_fixture" "$MOCK_BASE/bundle-manifests" "$MOCK_HINT/bmnvim.hint"
+# ── T-BM25: NON-listed multiline pkg still prompts for continuation URLs ──────
+# Guard against over-suppression: a package with no bundle manifest must keep
+# the interactive continuation-URL prompt on a primary bump.
+echo ""
+echo "T-BM25: non-listed multiline pkg → continuation URL prompt still shown"
+: > "$MOCK_BASE/bundle-manifests" # nothing listed
+cat > "$MOCK_HINT/plainml.hint" << 'EOF'
+VERSION="1.0.0"
+DOWNLOAD="https://example.com/plainml-1.0.0.tar.gz \
+ https://example.com/extra-9.9.tar.gz"
+MD5SUM="aaa \
+ bbb"
+DOWNLOAD_x86_64=""
+MD5SUM_x86_64=""
+ARCH="x86_64"
+EOF
+# stdin: blank (keep continuation URL), then slackrepo n. The read -p prompt is
+# suppressed by bash when stdin is piped, so assert on the always-echoed
+# "line N (current)" header instead.
+out=$(run_mkhint -f plainml -V 1.1.0 < <(printf '\nn\n') 2>&1) || true
+echo "$out" | grep -q 'line 2 (current)' \
+ && ! echo "$out" | grep -q 'left to bundled-dep reconcile' \
+ && { echo " PASS: non-listed still prompts"; (( PASS++ )); } \
+ || { echo " FAIL: non-listed suppression leak. out=$out"; (( FAIL++ )); ERRORS+=("T-BM25"); }
+rm -f "$MOCK_HINT/plainml.hint" "$MOCK_HINT/plainml.hint.bak" "$MOCK_BASE/bundle-manifests"
+
# ── 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"