aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-06-19 10:26:22 +0200
committerDanilo M. <danix@danix.xyz>2026-06-19 10:26:22 +0200
commite9730f8eaed88cc742e6db34786b19bb712b5866 (patch)
tree82a0756ff1f6c131a5c68a9c04a9836c98f28115
parentf2f19227b14d5a342fdfb48f7d67914d947160a9 (diff)
downloadmkhintfile-e9730f8eaed88cc742e6db34786b19bb712b5866.tar.gz
mkhintfile-e9730f8eaed88cc742e6db34786b19bb712b5866.zip
perf: scan single nvchecker entry with -e for single-package checksHEADmaster
When --check is given exactly one package, and when --hintfile suggests a version without -v, run `nvchecker -e <pkg>` so only that entry is scanned instead of the whole nvchecker.toml. Two+ packages or no args still do one full scan, since nvchecker -e accepts only a single entry. Add T42/T43 (mock nvchecker now logs its args), and update CLAUDE.md and README.md (including the previously undocumented -R/--review and -l highlight). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--CLAUDE.md4
-rw-r--r--README.md19
-rwxr-xr-xmkhint14
-rwxr-xr-xtests/mkhint_test.sh37
4 files changed, 66 insertions, 8 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 854d529..c539d4b 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -95,6 +95,8 @@ Test coverage:
| T39 | `-R` empty answer — kept (default) |
| T40 | `-R` answer S — matched hint unchanged |
| T41 | `-R` no matched rows — "nothing to review", exit 0 |
+| T42 | `--check` single pkg — nvchecker called with `-e <pkg>` |
+| T43 | `--check` two pkgs — nvchecker full scan, no `-e` |
When adding new features, add a corresponding test case to `tests/mkhint_test.sh`.
@@ -106,7 +108,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`: iterates only the matched (highlighted) hints. 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. `-l` and `-R` combine: `-lR` shows the table first, then reviews. No matches → "nothing to review", exit 0.
-- `--check` / `-C`: runs nvchecker for all (or named) hints, 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.
- `--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/README.md b/README.md
index 5eb5ec0..40cd960 100644
--- a/README.md
+++ b/README.md
@@ -101,11 +101,26 @@ When updating a hint with multiline DOWNLOAD, mkhint:
### List hint files
+Lists each hint file with its `HintVer` (version in the hint) and `SBOVer` (version in the repository `.info`). Rows where the two are byte-equal are highlighted, so you can see at a glance which hints are now redundant with the upstream SBo version. Color is used only on a TTY; piped output is plain. A legend is printed when any row matched.
+
```bash
mkhint --list
mkhint -l
```
+### Review matched hint files
+
+Iterates only the matched (highlighted) hints from `--list` — those whose version equals the SBo `.info` version. For each, it shows the hint side by side with its `.info` (`git diff --no-index` if git is available, otherwise `diff -y`), then prompts `[K]eep / [D]elete / [S]kip` (default Keep). Delete removes the hint and its `.bak`. A deleted/kept summary is printed at the end.
+
+```bash
+mkhint --review
+mkhint -R
+mkhint --list --review # show the highlighted table first, then review
+mkhint -lR # same, combined
+```
+
+If no hints match, it prints "nothing to review" and exits 0.
+
### Delete a hint file
Removes the hint file and its .bak backup if present:
@@ -146,6 +161,8 @@ mkhint --check pkg1 pkg2 # check specific packages
mkhint -C # short form
```
+When exactly one package is given, mkhint runs `nvchecker -e <package>` so only that entry is scanned instead of the whole `nvchecker.toml`. With two or more packages, or no arguments, it does a single full scan. (`--hintfile` without `-v` likewise queries just its one entry via `-e`.)
+
If any scanned hint file has no nvchecker source configured, `--check` lists those packages and offers to populate `nvchecker.toml` for them in one prompt — auto-detecting github/pypi from the SBo `.info`, otherwise writing a commented stub to fill in. After populating, it asks you to review the file (fill any stubs) and re-run `mkhint -C`. Packages with no matching `.info` in the repository are skipped.
### Help
@@ -183,4 +200,4 @@ mkhint -h
- If DOWNLOAD or DOWNLOAD_x86_64 is `UNSUPPORTED` or `UNTESTED`, that URL is skipped and its MD5SUM is left unchanged.
- `--no-dl` / `-N` does **not** skip downloads — it downloads and recalculates checksums as normal, then appends `NODOWNLOAD=yes` to the hint file.
- After a successful `--hintfile` update, mkhint prompts `Run 'slackrepo update <package>'? [Y/n]`. Enter or `y` runs slackrepo immediately; `n` skips.
-- Bash completion for `-f`/`--hintfile`, `-n`/`--new`, `-d`/`--delete`, and `-C`/`--check` autocompletes package names from their respective directories. When `-f <package>` is already on the command line, `-v [TAB]` suggests the current `VERSION` from that package's hint file. If the hint file is absent, no version is suggested. Short flags (`-v`, `-f`, `-n`, `-l`, `-c`, `-d`, `-C`, `-N`, `-h`) are also completed.
+- Bash completion for `-f`/`--hintfile`, `-n`/`--new`, `-d`/`--delete`, and `-C`/`--check` autocompletes package names from their respective directories. When `-f <package>` is already on the command line, `-v [TAB]` suggests the current `VERSION` from that package's hint file. If the hint file is absent, no version is suggested. Short flags (`-v`, `-f`, `-n`, `-l`, `-R`, `-c`, `-d`, `-C`, `-N`, `-h`) and their long forms (including `--review`) are also completed.
diff --git a/mkhint b/mkhint
index 8decc76..bca91bc 100755
--- a/mkhint
+++ b/mkhint
@@ -509,8 +509,9 @@ build_multiline_value() {
suggest_version() {
local pkg="$1"
- # Refresh nvchecker results (stderr only; keep stdout clean for the echo)
- nvchecker -c "$NVCHECKER_CONFIG" >&2 || true
+ # Refresh nvchecker results (stderr only; keep stdout clean for the echo).
+ # -e limits the run to this entry instead of scanning the whole config.
+ nvchecker -c "$NVCHECKER_CONFIG" -e "$pkg" >&2 || true
local latest
latest=$(nvchecker_latest "$pkg") || {
@@ -731,9 +732,14 @@ check_updates() {
done
fi
- # Refresh nvchecker results once for everything
+ # Refresh nvchecker results. With exactly one explicit target, -e limits
+ # the run to that entry; otherwise scan the whole config in one pass.
echo "Running nvchecker..."
- nvchecker -c "$NVCHECKER_CONFIG" >&2 || true
+ if [[ ${#targets[@]} -eq 1 && $# -gt 0 ]]; then
+ nvchecker -c "$NVCHECKER_CONFIG" -e "${targets[0]}" >&2 || true
+ else
+ nvchecker -c "$NVCHECKER_CONFIG" >&2 || true
+ fi
# Classify each target
local outdated_pkgs=() outdated_old=() outdated_new=() outdated_flag=()
diff --git a/tests/mkhint_test.sh b/tests/mkhint_test.sh
index e95b529..4ee3059 100755
--- a/tests/mkhint_test.sh
+++ b/tests/mkhint_test.sh
@@ -163,9 +163,10 @@ EOF
mock_nvchecker_tools() {
mkdir -p "$MOCK_BASE/bin"
- # nvchecker: no-op success (keyfile is pre-seeded by setup/tests)
- cat > "$MOCK_BASE/bin/nvchecker" << 'EOF'
+ # nvchecker: record invocations, no-op success (keyfile pre-seeded by setup/tests)
+ cat > "$MOCK_BASE/bin/nvchecker" << EOF
#!/bin/bash
+echo "nvchecker \$*" >> "$MOCK_BASE/nvchecker.log"
exit 0
EOF
chmod +x "$MOCK_BASE/bin/nvchecker"
@@ -838,6 +839,38 @@ echo "$out" | grep -q "nothing to review" \
&& { echo " PASS: nothing-to-review message"; (( PASS++ )); } \
|| { echo " FAIL: message missing"; echo "$out" | sed 's/^/ /'; (( FAIL++ )); ERRORS+=("T41 msg"); }
+# ── T42: --check single package → nvchecker called with -e <pkg> ──────────────
+echo ""
+echo "T42: --check one package runs nvchecker -e <pkg>"
+rm -f "$MOCK_HINT"/*.hint "$MOCK_HINT"/*.bak "$MOCK_BASE/nvchecker.log" 2>/dev/null
+cat > "$MOCK_BASE/new_ver.json" << 'EOF'
+{ "version": 2, "data": { "curl": { "version": "8.5.0" } } }
+EOF
+cat > "$MOCK_HINT/curl.hint" << 'EOF'
+VERSION="8.5.0"
+ARCH="x86_64"
+DOWNLOAD="https://curl.se/download/curl-8.5.0.tar.gz"
+MD5SUM="abc123def456abc123def456abc123de"
+EOF
+run_mkhint -C curl < <(printf '\n') > /dev/null 2>&1
+assert_contains "nvchecker run with -e curl" "$MOCK_BASE/nvchecker.log" '\-e curl'
+
+# ── T43: --check two packages → nvchecker scans all (no -e) ───────────────────
+echo ""
+echo "T43: --check two packages runs nvchecker without -e (full scan)"
+rm -f "$MOCK_BASE/nvchecker.log" 2>/dev/null
+cat > "$MOCK_BASE/new_ver.json" << 'EOF'
+{ "version": 2, "data": { "curl": { "version": "8.5.0" }, "clion": { "version": "2025.4" } } }
+EOF
+cat > "$MOCK_HINT/clion.hint" << 'EOF'
+VERSION="2025.4"
+ARCH="x86_64"
+DOWNLOAD="UNSUPPORTED"
+MD5SUM=""
+EOF
+run_mkhint -C curl clion < <(printf '\n') > /dev/null 2>&1
+assert_not_contains "two-pkg check has no -e" "$MOCK_BASE/nvchecker.log" '\-e '
+
# ─── SUMMARY ──────────────────────────────────────────────────────────────────
teardown