# danix-nvchecker A unified [nvchecker](https://github.com/lilydjwg/nvchecker) configuration plus `nvtable`, a small Bash tool that answers the question nvchecker alone cannot: > upstream released a new version, but **do I have it installed**, and does the > SlackBuild in my repo still ship the old one? `nvcmp` compares upstream against its own last-seen state. `nvtable` adds the two columns that matter in practice, the version installed on this machine and the version shipped by the SlackBuild repo that packages it. ``` package upstream installed repo ๐Ÿ”ด discord 1.0.152 1.0.151 my 1.0.152 ๐Ÿ”ด๐ŸŸก nuclei 3.11.1 3.11.0 sbo 3.11.0 ๐Ÿ”ด signal-desktop 8.22.0 8.20.0 -- ๐ŸŸข qarma 1.1.1 1.1.1 my 1.1.1 26 to upgrade ยท 2 repos to bump ยท 32 current ยท 13 not installed ``` | marker | meaning | |--------|---------| | ๐Ÿ”ด | installed version is behind upstream | | ๐ŸŸก | the repo `.info` still ships an older version, so it needs a bump | | ๐ŸŸข | installed and packaged versions both match upstream | | โšช | not installed on this host (tracked only) | A row can carry two markers: ๐Ÿ”ด๐ŸŸก means upstream moved and neither the system nor the SlackBuild has caught up. ## Contents - `nvchecker.toml` - one config covering everything tracked: software installed on this machine, packages maintained in three SlackBuild repos, and services running elsewhere. - `nvtable` - the comparison tool. ## nvchecker.toml Merged from a personal config and the `.extras/nvchecker.toml` of three SlackBuild repositories, deduplicated. The per-repo configs are kept in their repos for standalone sweeps; this one is the superset used day to day. Two conventions make the joins work without a lookup table: - **The stanza name is the Slackware package name** wherever a package exists, so results join directly against `/var/log/packages` and against `/.info`. Where they genuinely differ (`kvantum` builds both `kvantum-qt5` and `kvantum-qt6`) `nvtable` carries a small alias map. - **A `# repo=` comment marks which repository ships the package**: `sbo`, `my`, `sps`, or nothing for tracked-only entries. Watch for two nvchecker details that cause silent wrong answers: - A stanza name containing a dot **must be quoted**. `[llama.cpp-vulkan]` parses as a nested `llama` table and fails with `no source specified`; write `["llama.cpp-vulkan"]`. - Omitting `prefix = "v"` on a `use_latest_release` GitHub source yields `v8.30.1` rather than `8.30.1`, which then never matches a `.info` VERSION. ## nvtable ### Requirements `bash`, `jq`, and nvchecker's `nvcmp`/`nvtake`. `flatpak` is optional and used only if present. ### Usage ``` nvtable [-a] [-n] [-C] [-E] -a, --all show every tracked package, not just those needing action -n, --no-take do not run nvtake on caught-up packages -C, --no-color plain output -E, --no-emoji ASCII status markers instead of emoji ``` By default only actionable rows print. Packages that are current, and packages not installed on this host, are folded into the summary line. Color is disabled automatically when output is not a terminal. ### Where the three versions come from **upstream** is read from nvchecker's `new_ver.json`. `nvtable` never fetches anything itself, so it is fast enough to run on every login; refreshing that file is nvchecker's job. **installed** is resolved from three sources, in order: 1. `/var/log/packages` for Slackware packages 2. `~/.local/state/appimage-updater/installed.json` for AppImages managed by [appimage-updater](https://git.danix.xyz/appimage-updater/) 3. `flatpak list` for flatpak apps **repo** is the `VERSION=` line of `///.info` across the configured SlackBuild repositories. ### Version comparison Versions arrive from unrelated sources and rarely agree on formatting, so they are normalised before comparison: a leading `v` is stripped, `-` and `_` fold to `.`, and case is ignored. Installed versions also carry build metadata that upstream never has, for instance `r8125` installs as `9.018.00_6.18.41` (version plus kernel) against an upstream `9.018.00`. An installed version that merely *extends* upstream at a component boundary counts as equal, otherwise every such package would report as permanently behind. One related trap: a Slackware package filename is `PRGNAM-VERSION-ARCH-BUILD`, but VERSION may itself contain a dash (`solvespace-3.1-659215d`), so the PRGNAM/VERSION boundary cannot be found by counting dashes. Lookups anchor on the package name being searched for instead. ### nvtake When a package's installed version matches upstream, `nvtable` runs `nvtake` for it, so nvchecker's `old_ver.json` tracks the state of this system rather than only what upstream last did. Pass `-n` to disable. Because a login shell can start while another is still running, the take is serialised with `flock`; `nvtake` rewrites `old_ver.json` without locking of its own. If the lock is held the take is skipped, and the next run picks it up. ## Installation ``` ln -s "$PWD/nvtable" ~/bin/nvtable cp nvchecker.toml ~/.config/nvchecker/nvchecker.toml ``` The config expects a GitHub token in `~/.config/nvchecker/keys.toml`, without which the many GitHub sources exhaust the anonymous rate limit: ```toml [keys] github = "ghp_..." ``` To show the table at login, call `nvtable` where `nvcmp` would have gone. The repository paths `nvtable` scans are the `REPOS` array at the top of the script. ## Notes `nvtable` reads `new_ver.json` and does not refresh it. If that file is stale, for example right after renaming stanzas, the table reports the old names as untracked until `nvchecker` runs again. ## License GPLv2 (v2 only). See [LICENSE](LICENSE). ## Development Approach This project is developed using AI-assisted tools. Code is generated with the help of AI based on human-provided specifications, design decisions, and iterative feedback. All contributions are reviewed, tested, and curated by the maintainer before being included in the codebase. AI is used as a productivity and exploration tool, while human oversight remains central to all decisions. The goal is to combine the flexibility of AI-assisted development with standard open-source practices such as transparency, review, and accountability.