From 14c6a2e4b50b422a3c2e16a6f1db3b0ad560767d Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sun, 5 Jul 2026 20:41:34 +0200 Subject: docs: plan for man page + compact --help Co-Authored-By: Claude Opus 4.8 --- .../plans/2026-07-05-manpage-and-compact-help.md | 460 +++++++++++++++++++++ 1 file changed, 460 insertions(+) create mode 100644 docs/superpowers/plans/2026-07-05-manpage-and-compact-help.md diff --git a/docs/superpowers/plans/2026-07-05-manpage-and-compact-help.md b/docs/superpowers/plans/2026-07-05-manpage-and-compact-help.md new file mode 100644 index 0000000..2f887f3 --- /dev/null +++ b/docs/superpowers/plans/2026-07-05-manpage-and-compact-help.md @@ -0,0 +1,460 @@ +# Man page + compact --help Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a gzipped `mkhint.1` man page as the full reference and slim `--help` to a scannable summary that points at it. + +**Architecture:** Man page authored in Markdown (`mkhint.1.md`), built with pandoc to roff, gzipped, and committed as `mkhint.1.gz` so the target VM needs no pandoc. The `show_help` heredoc in `mkhint` is trimmed to title + synopsis + options + runtime paths + man pointer. Install docs and the test suite are updated to match. + +**Tech Stack:** bash, pandoc 3.9 (dev host only), gzip, groff/man for verification. + +--- + +### Task 1: Author the man page source + +**Files:** +- Create: `mkhint.1.md` + +- [ ] **Step 1: Write `mkhint.1.md`** + +Create `mkhint.1.md` with exactly this content: + +````markdown +% MKHINT(1) mkhint 1.1.0 | User Commands +% Danilo M. +% July 2026 + +# NAME + +mkhint - manage hint files for slackrepo scripts + +# SYNOPSIS + +**mkhint** \[**--set-version** *VERSION*] **--hintfile** *FILE* + +**mkhint** \[**--set-version** *VERSION*] **--new** *FILE* \[**--no-dl**] + +**mkhint** **--check** \[*FILE*...] + +**mkhint** **--fix-current** + +**mkhint** **--list** \[*FILE*...] + +**mkhint** **--review** \[*FILE*...] + +**mkhint** **--delete** *FILE*... + +**mkhint** **--clean** + +**mkhint** {**--version** | **--help**} + +# DESCRIPTION + +**mkhint** manages [slackrepo](https://idlemoor.github.io/slackrepo/) hint +files. A hint file overrides build variables (version, download URL, checksum, +dependencies) for a SlackBuild. **mkhint** updates the version string and +download checksums of an existing hint, creates a new hint from a repository +`.info` file, checks upstream for newer versions via **nvchecker**, and manages +`DELREQUIRES` for Slackware -current phantom dependencies. + +After a version-changing update, **mkhint** dispatches **slackrepo** for the +affected package: `slackrepo update` if the package is already built in the +package repository, `slackrepo build` if it is not. + +# OPTIONS + +**--set-version**, **-V** *VERSION* +: New version string. Required with **--hintfile**; optional with **--new**. +Replaces the old version everywhere in the hint and recalculates MD5 checksums. + +**--hintfile**, **-f** *FILE* +: Update an existing hint file. Without **-V**, queries **nvchecker** for the +latest version and prompts to accept, override, or decline. Backs the hint up +to *FILE*.bak first. + +**--new**, **-n** *FILE* +: Create a new hint file from the package's `.info` template. Keeps `VERSION` +from the `.info` unless **-V** is given. Appends an **nvchecker** section to the +config, autodetecting a github or pypi source or leaving a commented stub. + +**--check**, **-C** \[*FILE*...] +: Check all (or the named) hints for upstream updates via **nvchecker** and +apply them interactively. With one package, uses `nvchecker -e`; with two or +more, one full scan. Mutually exclusive with **-V**. + +**--fix-current**, **-F** +: Sweep the whole repository. For every package whose `REQUIRES` contains a +phantom dependency, ensure its hint carries the matching `DELREQUIRES`. +Idempotent. Mutually exclusive with **-V**, **-f**, **-n**. + +**--list**, **-l** \[*FILE*...] +: List all hint files with their hint version, `.info` version, and a +`DelReq` marker. With package names, show each hint side by side with its +`.info` instead of the table. + +**--review**, **-R** \[*FILE*...] +: Review hints. With no arguments, iterate the hints whose version matches the +`.info`. With names, review each named hint regardless of match. For each, +show a diff and prompt **[K]eep / [D]elete / [S]kip**. + +**--delete**, **-d** *FILE*... +: Delete a hint file and its `.bak`. Accepts multiple names. + +**--clean**, **-c** +: Remove all `.bak` files from the hint directory. + +**--no-dl**, **-N** +: Download and recalculate checksums, then append `NODOWNLOAD=yes`. Use with +**--hintfile** or **--new**; an error on its own. + +**--version**, **-v** +: Print `mkhint ` and exit. + +**--help**, **-h** +: Print a short usage summary and exit. + +# USAGE EXAMPLES + +Update an existing hint to a new version (re-downloads, recalculates MD5, +backs up to `.bak`): + + mkhint --hintfile mypackage --set-version 2.0.1 + mkhint -f mypackage -V 2.0.1 + +Same, then append `NODOWNLOAD=yes`: + + mkhint -f mypackage -V 2.0.1 -N + +Create a new hint from `.info`: + + mkhint --new mypackage # copy .info as-is, keep its VERSION + mkhint -n mypackage -V 1.2.3 # update version + recalculate md5 + mkhint -n mypackage -V 1.2.3 -N # same, add NODOWNLOAD=yes + +Suggest the latest version for an existing hint via nvchecker (no **-V**): + + mkhint --hintfile mypackage + +Check upstream for updates: + + mkhint --check # all hints + mkhint --check pkg1 pkg2 # named hints + +List, review, sweep, delete, clean: + + mkhint --list + mkhint --list mypackage + mkhint --review + mkhint --fix-current + mkhint --delete mypackage + mkhint --clean + +URLs set to `UNSUPPORTED` or `UNTESTED` are skipped during download. + +# CONFIGURATION + +**mkhint** reads an optional sourced config file, plain bash `KEY="value"` +pairs, right after its baked-in defaults. A missing file leaves the defaults in +place. + + ~/.config/mkhint/config + +The overridable variables and their defaults: + +`REPO_DIR` (`/var/lib/sbopkg/SBo-danix/`) +: SBo repository holding the `.info` files. + +`HINT_DIR` (`/etc/slackrepo/SBo-danix/hintfiles/`) +: Where `.hint` files live. + +`PACKAGES_DIR` (`/repo/`) +: Built-package repository holding `*.txz`. Used to decide `slackrepo update` +vs `slackrepo build`. + +`NVCHECKER_CONFIG` (`$HOME/.config/nvchecker/nvchecker.toml`) +: nvchecker config. The `[__config__]` section must be created manually once +before version-checking works. **mkhint** only appends per-package sections. + +`PHANTOM_DEPS_FILE` (`$HOME/.config/mkhint/phantom-deps`) +: One phantom dependency per line, `#` comments allowed. Deps needed on +Slackware stable but not on -current. A missing file makes **--fix-current** +and the **--new** phantom-dep hook no-ops. + +`TMP_DIR` (`/tmp/mkhint`) +: Scratch directory for downloads. + +# FILES + +*~/.config/mkhint/config* +: Optional config overrides. + +*~/.config/mkhint/phantom-deps* +: Phantom dependency list. + +*~/.config/nvchecker/nvchecker.toml* +: nvchecker configuration. + +# EXIT CODES + +0 +: Success. + +1 +: Invalid arguments or missing required options. + +2 +: File not found. + +3 +: File already exists. + +4 +: Required tool not available (wget / nvchecker / nvtake / jq). + +# SEE ALSO + +**slackrepo**(8), **nvchecker**(1), **nvtake**(1) + +# AUTHOR + +Danilo M. +```` + +- [ ] **Step 2: Commit** + +```bash +git add mkhint.1.md +git commit -S -m "docs: add mkhint.1 man page source" +``` + +--- + +### Task 2: Build and commit the gzipped man page + +**Files:** +- Create: `mkhint.1.gz` (generated) +- Create: `.gitignore` + +- [ ] **Step 1: Add `.gitignore` for the uncompressed intermediate** + +Create `.gitignore` with: + +``` +mkhint.1 +``` + +- [ ] **Step 2: Build the man page** + +Run: + +```bash +pandoc mkhint.1.md -s -t man -o mkhint.1 && gzip -9 -n -f mkhint.1 +``` + +Expected: produces `mkhint.1.gz`, no `mkhint.1` left (gzip removes the source). + +- [ ] **Step 3: Verify it renders** + +Run: `man ./mkhint.1.gz` +Expected: the man page displays with NAME, SYNOPSIS, OPTIONS, etc. Quit with `q`. Check for no groff warnings on stderr: + +```bash +zcat mkhint.1.gz | groff -man -Tascii -ww >/dev/null +``` + +Expected: no output (no warnings). + +- [ ] **Step 4: Commit** + +```bash +git add .gitignore mkhint.1.gz +git commit -S -m "docs: build gzipped mkhint.1 man page" +``` + +--- + +### Task 3: Compact the `--help` output (TDD) + +**Files:** +- Modify: `mkhint` (the `show_help` heredoc, lines ~59-105) +- Test: `tests/mkhint_test.sh` (add T73) + +- [ ] **Step 1: Write the failing test** + +Add T73 at the end of the test file, immediately after the last existing test block (T72). Model it exactly on T65/T66: use the `run_mkhint` wrapper, wrap the call in `set +e`/`set -e`, check the exit code with the existing `assert_exit_code` helper, and grep the captured output. Note: the suite's `assert_contains` takes a **file** path, not a string, so it cannot be used for stdout — grep the captured `$out` directly, as T65/T66 do. + +```bash +# ── T73: --help compact, exits 0, points at man page ───────────────────────── +echo "" +echo "T73: --help exits 0 and points at 'man mkhint'" +set +e +out=$(run_mkhint --help 2>&1); code=$? +set -e +assert_exit_code "--help exits 0" 0 "$code" +echo "$out" | grep -q 'man mkhint' \ + && { echo " PASS: --help points at man page"; (( PASS++ )); } \ + || { echo " FAIL: --help missing man pointer: $out"; (( FAIL++ )); ERRORS+=("T73 pointer"); } +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `bash tests/mkhint_test.sh 2>&1 | grep -i t73` +Expected: FAIL — current help contains no `man mkhint` string. + +- [ ] **Step 3: Rewrite `show_help`** + +Replace the entire `show_help` function body (the `cat <&1 | grep -i t73` +Expected: PASS. + +- [ ] **Step 5: Run the full suite and syntax check** + +Run: + +```bash +bash -n mkhint && bash tests/mkhint_test.sh 2>&1 | tail -5 +``` + +Expected: `bash -n` clean, full suite passes (T1..T73), no regressions. + +- [ ] **Step 6: Eyeball the help** + +Run: `bash mkhint --help` +Expected: ~20 lines, ends with the `man mkhint` pointer, config-status line present. + +- [ ] **Step 7: Commit** + +```bash +git add mkhint tests/mkhint_test.sh +git commit -S -m "feat: compact --help, move reference to man page + +Trim show_help to a usage synopsis, the options list, the runtime +paths, and a 'man mkhint' pointer. The usage examples, variable-order +note, and exit-code table now live in the man page. Add T73 asserting +--help exits 0 and points at the man page." +``` + +--- + +### Task 4: Update install docs + +**Files:** +- Modify: `README.md` (Installation section, around lines 5-17) +- Modify: `CLAUDE.md` (Installation section near the bottom) + +- [ ] **Step 1: Add man-page install to README.md** + +In `README.md`, after the Bash Completion install block (the `mkhint.bash-completion` `sudo cp`, around line 17), add: + +````markdown +### Man Page + +```bash +sudo cp mkhint.1.gz /usr/local/man/man1/mkhint.1.gz +``` + +The man page is pre-built and committed. To regenerate it from source (requires +pandoc): + +```bash +pandoc mkhint.1.md -s -t man -o mkhint.1 && gzip -9 -n -f mkhint.1 +``` +```` + +- [ ] **Step 2: Add man-page install to CLAUDE.md** + +In `CLAUDE.md`, in the `## Installation` block, after the completion `sudo cp` +line, add: + +```bash +sudo cp mkhint.1.gz /usr/local/man/man1/mkhint.1.gz +``` + +And add a sentence noting the man page source is `mkhint.1.md`, rebuilt with +`pandoc mkhint.1.md -s -t man -o mkhint.1 && gzip -9 -n -f mkhint.1`; `--help` +is a compact summary that points at `man mkhint`. + +- [ ] **Step 3: Commit** + +```bash +git add README.md CLAUDE.md +git commit -S -m "docs: document man page install and compact --help" +``` + +--- + +### Task 5: Update CHANGELOG + +**Files:** +- Modify: `CHANGELOG.md` + +- [ ] **Step 1: Add an [Unreleased] entry** + +At the top of `CHANGELOG.md`, above `## [1.1.0]`, add (create the +`## [Unreleased]` heading if absent, follow the existing Keep-a-Changelog +style already in the file): + +```markdown +## [Unreleased] + +### Added +- `mkhint.1` man page (gzipped, built from `mkhint.1.md` with pandoc) as the full reference. +- `--help` now reports whether `~/.config/mkhint/config` is present and sourced. + +### Changed +- `--help` is now a compact summary; usage examples, the variable-order note, and the exit-code table moved to the man page. +``` + +- [ ] **Step 2: Commit** + +```bash +git add CHANGELOG.md +git commit -S -m "docs: changelog for man page and compact --help" +``` + +--- + +## Notes for the executor + +- All commits are GPG-signed (`-S`); the environment signs without prompting. +- Do not release/tag in this plan; version bump and tagging happen in a + separate release step chosen by the user. +- Do not deploy to the VM in this plan; deployment is a separate ship step. +- The config-status line in `show_help` was already added earlier (commit + `a59ae6c`); Task 3 preserves it inside the rewritten heredoc. -- cgit v1.2.3