From e9730f8eaed88cc742e6db34786b19bb712b5866 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 19 Jun 2026 10:26:22 +0200 Subject: perf: scan single nvchecker entry with -e for single-package checks When --check is given exactly one package, and when --hintfile suggests a version without -v, run `nvchecker -e ` 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 --- CLAUDE.md | 4 +++- README.md | 19 ++++++++++++++++++- mkhint | 14 ++++++++++---- tests/mkhint_test.sh | 37 +++++++++++++++++++++++++++++++++++-- 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 ` | +| 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 ` 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 `.) 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 ` 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 '? [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 ` 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 ` 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 ────────────── +echo "" +echo "T42: --check one package runs nvchecker -e " +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 -- cgit v1.2.3