aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-03 13:15:49 +0200
committerDanilo M. <danix@danix.xyz>2026-07-03 13:15:49 +0200
commit21aabc67cb9e8e76c6fab6727690a3a9c02a98da (patch)
tree8f80dd92386be5055a12b9cd68dbba5c71d1ad92
parent5fdb01eaaa88146e31a611423b269678074085f3 (diff)
downloadmkhintfile-21aabc67cb9e8e76c6fab6727690a3a9c02a98da.tar.gz
mkhintfile-21aabc67cb9e8e76c6fab6727690a3a9c02a98da.zip
feat: treat dashed upstream version as equivalent to packaged underscore form
SlackBuild versions cannot contain '-' (it breaks PRGNAM parsing), so an upstream date like 2026-06-02 is packaged as 2026_06_02. mkhint was comparing them byte-for-byte and offering a spurious upgrade/downgrade. Add _normalize_version ('-' -> '_') and apply it to the upstream version in --check and --hintfile (no -v) before comparing and before storing, so equivalent versions compare equal and accepted updates are written in the underscore form. nvtake still uses nvchecker's raw keyfile value. Tests T48/T49 cover equivalence and normalized storage (105 passing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--CLAUDE.md4
-rwxr-xr-xmkhint17
-rwxr-xr-xtests/mkhint_test.sh38
3 files changed, 54 insertions, 5 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 560df86..6fa8bac 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -101,6 +101,8 @@ Test coverage:
| T45 | `-R <pkg>` answer D — named hint and .bak removed |
| T46 | `-R <pkg1> <pkg2>` — both reviewed, summary "Reviewed 2" |
| T47 | `-R <missing>` — exit 2 |
+| T48 | `--check` upstream `2026-06-02` vs hint `2026_06_02` — treated as current |
+| T49 | `--check` accept dashed upstream — hint VERSION stored as underscore form |
When adding new features, add a corresponding test case to `tests/mkhint_test.sh`.
@@ -112,7 +114,7 @@ When adding new features, add a corresponding test case to `tests/mkhint_test.sh
- `--hintfile` with no `-v`: queries nvchecker for latest version, shows current vs. latest, prompts to accept/override/decline. After accepting, runs `nvtake` to sync nvchecker's keyfile.
- `--list` / `-l`: lists hints with `HintVer`/`SBOVer`; rows where the two are byte-equal are highlighted (color only on a TTY; plain when piped). Adds a legend when any row matched.
- `--review` / `-R`: with no package args, iterates only the matched (highlighted) hints. With explicit package names (`-R foo bar`), reviews each named hint regardless of version match (existence required: missing hint → exit 2). For each, shows the hint side-by-side with its `.info` (`git diff --no-index` if git present, else `diff -y`), then prompts `[K]eep / [D]elete / [S]kip` (default Keep). Delete removes the hint and its `.bak` via `_remove_hint`. Prints a deleted/kept summary counting hints actually reviewed. `-l` and `-R` combine: `-lR` shows the table first, then reviews. Bare `-R` with no matches → "nothing to review", exit 0. Per-hint logic lives in `_review_one_hint`; `review_hint_files` drives it from either the named list or `MATCHED_PKGS`.
-- `--check` / `-C`: runs nvchecker for all (or named) hints. With exactly one explicit package it uses `nvchecker -e <pkg>` to skip scanning the whole config; with two+ packages or no args it does one full scan. (`--hintfile` with no `-v` also queries via `nvchecker -e <pkg>`.) reports outdated packages with current → latest versions, prompts per-package to update, applies updates with `nvtake`, then prompts single `slackrepo update` for all updated packages. Hints with no `[pkg]` section in `nvchecker.toml` are collected and, after the scan, a single prompt offers to populate the config via `add_nvchecker_section` (github/pypi autodetect, else stub); on accept it prints a "review and re-run" message and stops the run without applying updates. Packages whose `.info` is not found in `REPO_DIR` are skipped.
+- `--check` / `-C`: runs nvchecker for all (or named) hints. With exactly one explicit package it uses `nvchecker -e <pkg>` to skip scanning the whole config; with two+ packages or no args it does one full scan. (`--hintfile` with no `-v` also queries via `nvchecker -e <pkg>`.) reports outdated packages with current → latest versions, prompts per-package to update, applies updates with `nvtake`, then prompts single `slackrepo update` for all updated packages. Hints with no `[pkg]` section in `nvchecker.toml` are collected and, after the scan, a single prompt offers to populate the config via `add_nvchecker_section` (github/pypi autodetect, else stub); on accept it prints a "review and re-run" message and stops the run without applying updates. Packages whose `.info` is not found in `REPO_DIR` are skipped. Upstream versions are normalized via `_normalize_version` (`-` → `_`) before comparing and before storing, so a dashed upstream version like `2026-06-02` matches the packaged `2026_06_02` (SlackBuild versions cannot contain `-`) and updates are written in the underscore form. The same normalization applies to `--hintfile` with no `-v`. `nvtake` still uses nvchecker's own raw keyfile value.
- `--no-dl` / `-N`: downloads and recalculates checksums as normal, then appends `NODOWNLOAD=yes` after `MD5SUM_x86_64=`. Works with `--hintfile` or `--new`. Error if used alone.
- `--delete` / `-d`: removes hint file and `.bak` if present. Accepts multiple package names. Exits 2 on first missing file.
- Downloads go to `/tmp/mkhint/download` (single shared temp file, deleted after md5 calculation).
diff --git a/mkhint b/mkhint
index 6a2c71c..b18cbc3 100755
--- a/mkhint
+++ b/mkhint
@@ -263,6 +263,13 @@ _nvchecker_newver_path() {
}
# Echo the latest version nvchecker found for a package, or return non-zero
+# Normalize an upstream version to our packaging convention: '-' is illegal in
+# a SlackBuild version (breaks PRGNAM parsing), so we store it as '_'. Compare
+# the normalized forms so e.g. upstream 2026-06-02 == packaged 2026_06_02.
+_normalize_version() {
+ printf '%s\n' "${1//-/_}"
+}
+
# Usage: latest=$(nvchecker_latest pkg) || handle "no version"
nvchecker_latest() {
local pkg="$1"
@@ -544,6 +551,7 @@ suggest_version() {
echo "Error: no nvchecker result for '$pkg'. Add/fix its [${pkg}] section in $NVCHECKER_CONFIG" >&2
return 1
}
+ latest=$(_normalize_version "$latest")
# Read current version from the hint file (best effort, for display)
local hintpath="${HINT_DIR%/}/${pkg}.hint"
@@ -785,14 +793,15 @@ check_updates() {
fi
continue
fi
- [[ "$current" == "$latest" ]] && continue # up to date
- # determine direction with sort -V
- local newest; newest=$(printf '%s\n%s\n' "$current" "$latest" | sort -V | tail -1)
+ local latest_norm; latest_norm=$(_normalize_version "$latest")
+ [[ "$current" == "$latest_norm" ]] && continue # up to date
+ # determine direction with sort -V (compare normalized forms)
+ local newest; newest=$(printf '%s\n%s\n' "$current" "$latest_norm" | sort -V | tail -1)
local flag="update"
[[ "$newest" == "$current" ]] && flag="?downgrade"
outdated_pkgs+=("$pkg")
outdated_old+=("$current")
- outdated_new+=("$latest")
+ outdated_new+=("$latest_norm")
outdated_flag+=("$flag")
done
diff --git a/tests/mkhint_test.sh b/tests/mkhint_test.sh
index 102790d..4aa0c2d 100755
--- a/tests/mkhint_test.sh
+++ b/tests/mkhint_test.sh
@@ -937,6 +937,44 @@ code=$?
set -e
assert_exit_code "missing named hint exits 2" 2 "$code"
+# ── T48: --check upstream dashed date == packaged underscore date → current ────
+echo ""
+echo "T48: --check upstream 2026-06-02 vs hint 2026_06_02 → treated as current"
+rm -f "$MOCK_HINT"/*.hint "$MOCK_HINT"/*.bak 2>/dev/null
+cat > "$MOCK_BASE/new_ver.json" << 'EOF'
+{ "version": 2, "data": { "curl": { "version": "2026-06-02" } } }
+EOF
+cat > "$MOCK_HINT/curl.hint" << 'EOF'
+VERSION="2026_06_02"
+ARCH="x86_64"
+DOWNLOAD="https://curl.se/download/curl-2026_06_02.tar.gz"
+MD5SUM="abc123def456abc123def456abc123de"
+DOWNLOAD_x86_64=""
+MD5SUM_x86_64=""
+EOF
+out=$(run_mkhint -C curl < <(printf '\n') 2>&1)
+echo "$out" | grep -q "all up to date" \
+ && { echo " PASS: dashed upstream == underscore packaged"; (( PASS++ )); } \
+ || { echo " FAIL: offered an update for equivalent version"; echo "$out" | sed 's/^/ /'; (( FAIL++ )); ERRORS+=("T48 dash/underscore equivalence"); }
+
+# ── T49: --check accept dashed upstream update → hint stores underscore form ────
+echo ""
+echo "T49: --check accept 2026-07-01 → hint VERSION written as 2026_07_01"
+cat > "$MOCK_BASE/new_ver.json" << 'EOF'
+{ "version": 2, "data": { "curl": { "version": "2026-07-01" } } }
+EOF
+cat > "$MOCK_HINT/curl.hint" << 'EOF'
+VERSION="2026_06_02"
+ARCH="x86_64"
+DOWNLOAD="https://curl.se/download/curl-2026_06_02.tar.gz"
+MD5SUM="abc123def456abc123def456abc123de"
+DOWNLOAD_x86_64=""
+MD5SUM_x86_64=""
+EOF
+# accept update (Y), decline slackrepo (n)
+run_mkhint -C curl < <(printf 'Y\nn\n')
+assert_contains "hint stores normalized version" "$MOCK_HINT/curl.hint" 'VERSION="2026_07_01"'
+
# ─── SUMMARY ──────────────────────────────────────────────────────────────────
teardown