diff options
| author | Danilo M. <danix@danix.xyz> | 2026-07-04 18:02:41 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-07-04 18:02:41 +0200 |
| commit | 59493cf11193271bbf6a30e3ea0e2983e61d825d (patch) | |
| tree | 9376bc0bdcf15e50a8a8e389e1a7586e5c0c9fe5 | |
| parent | ab590f9b88a2d8bb12bd24ba8b792c09977bb92f (diff) | |
| download | mkhintfile-59493cf11193271bbf6a30e3ea0e2983e61d825d.tar.gz mkhintfile-59493cf11193271bbf6a30e3ea0e2983e61d825d.zip | |
docs: implementation plan for semver adoption
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rw-r--r-- | docs/superpowers/plans/2026-07-04-semver-adoption.md | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/docs/superpowers/plans/2026-07-04-semver-adoption.md b/docs/superpowers/plans/2026-07-04-semver-adoption.md new file mode 100644 index 0000000..05ffc2a --- /dev/null +++ b/docs/superpowers/plans/2026-07-04-semver-adoption.md @@ -0,0 +1,376 @@ +# SemVer adoption 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:** Adopt SemVer: `mkhint -v`/`--version` prints the tool version, the hint-version flag moves to `-V`/`--set-version`, add a CHANGELOG, and tag `v1.0.0` signed. + +**Architecture:** A `readonly MKHINT_VERSION` constant drives `--help` and a new `-v`/`--version` handler that prints and exits. The `getopt` spec and case handlers swap `-v`/`--version` (was hint-version, now tool-version) for `-V`/`--set-version` (hint-version). Tests, completion, and docs follow the rename. Release tagged at the end. + +**Tech Stack:** bash, `getopt`, existing `tests/mkhint_test.sh` harness, git signed tags. + +--- + +## File structure + +- Modify: `mkhint` — version constant, `getopt` line, case handlers, mutual-exclusion messages, `show_help` + header comments. +- Modify: `tests/mkhint_test.sh` — rename `-v`→`-V` in 9 hint-version calls + T26/T56; add T65-T67. +- Modify: `mkhint.bash-completion` — `all_flags`, move the version-suggest case to `--set-version|-V`. +- Modify: `README.md` — flag docs, examples, SemVer/Conventional-commits note. +- Modify: `CLAUDE.md` — flag references, test table (T65-T67). +- Create: `CHANGELOG.md`. + +No new dependencies. + +--- + +## Task 1: Version constant + `-v`/`--version` output, flag rename + +**Files:** +- Modify: `mkhint` (const near line 35; `getopt` ~1009; case ~1016; mutual-excl ~1103/1108) +- Test: `tests/mkhint_test.sh` (T65, T66, T67; rename existing `-v`) + +- [ ] **Step 1: Write failing tests T65, T66, T67** + +Append after T64 (before the SUMMARY block) in `tests/mkhint_test.sh`: + +```bash +# ── T65: mkhint -v prints tool version ─────────────────────────────────────── +echo "" +echo "T65: -v prints 'mkhint <version>' and exits 0" +set +e +out=$(run_mkhint -v 2>&1); code=$? +set -e +assert_exit_code "-v exits 0" 0 "$code" +echo "$out" | grep -Eq '^mkhint [0-9]+\.[0-9]+\.[0-9]+$' \ + && { echo " PASS: -v prints version"; (( PASS++ )); } \ + || { echo " FAIL: -v output wrong: $out"; (( FAIL++ )); ERRORS+=("T65 output"); } + +# ── T66: mkhint --version prints tool version ──────────────────────────────── +echo "" +echo "T66: --version prints 'mkhint <version>' and exits 0" +set +e +out=$(run_mkhint --version 2>&1); code=$? +set -e +assert_exit_code "--version exits 0" 0 "$code" +echo "$out" | grep -Eq '^mkhint [0-9]+\.[0-9]+\.[0-9]+$' \ + && { echo " PASS: --version prints version"; (( PASS++ )); } \ + || { echo " FAIL: --version output wrong: $out"; (( FAIL++ )); ERRORS+=("T66 output"); } + +# ── T67: -V still sets the hint version (rename works) ─────────────────────── +echo "" +echo "T67: -V <ver> -n <pkg> sets hint VERSION" +rm -f "$MOCK_HINT"/*.hint "$MOCK_HINT"/*.bak 2>/dev/null +run_mkhint -n curl -V 8.6.0 >/dev/null 2>&1 +assert_contains "hint VERSION set via -V" "$MOCK_HINT/curl.hint" 'VERSION="8.6.0"' +``` + +- [ ] **Step 2: Run tests, verify they fail** + +Run: `bash tests/mkhint_test.sh 2>&1 | grep -E 'T6[567]'` +Expected: T65/T66 FAIL (`-v` currently expects an argument → getopt error / wrong output), T67 FAIL (`-V` unknown flag). + +- [ ] **Step 3: Add the version constant** + +In `mkhint`, after the `VERSION=""` line (~35), add: + +```bash +readonly MKHINT_VERSION="1.0.0" +``` + +- [ ] **Step 4: Update the getopt spec** + +Replace the `getopt` invocation (~1009): + +```bash + parsed=$(getopt -o vV:f:n:lcCdNhRF \ + --long version,set-version:,hintfile:,new:,list,clean,check,delete,no-dl,help,review,fix-current \ + -n 'mkhint' -- "$@") || { show_help; exit 1; } +``` + +- [ ] **Step 5: Replace the case handler** + +Replace the `--version|-v)` case (~1016): + +```bash + --version|-v) + echo "mkhint $MKHINT_VERSION" + exit 0 + ;; + --set-version|-V) + VERSION="$2" + shift 2 + ;; +``` + +- [ ] **Step 6: Update mutual-exclusion messages** + +Change both messages (~1103, ~1108) `--version` → `--set-version`: + +```bash + echo "Error: --check cannot be combined with --set-version/--hintfile/--new" >&2 +``` +```bash + echo "Error: --fix-current cannot be combined with --set-version/--hintfile/--new" >&2 +``` + +- [ ] **Step 7: Rename existing `-v` hint-version calls in tests** + +In `tests/mkhint_test.sh`, change `-v` to `-V` in these hint-version invocations +(the version-setting ones only — do NOT touch T65/T66 which use bare `-v`): + +- line ~330: `run_mkhint -n curl -V 8.6.0` +- line ~347: `run_mkhint -n curl -V 8.7.0 -N` +- line ~372: `run_mkhint -f curl -V 8.9.0` +- line ~389: `run_mkhint -f curl -V 9.0.0 -N` +- line ~401: `run_mkhint -f clion -V 2025.4` +- line ~419: `run_mkhint -f nonexistent -V 1.0 2>/dev/null` +- line ~456: `echo "" | run_mkhint -n protoc-gen-go-grpc -V 1.4.0` +- line ~610 (T26): `run_mkhint -C -V 1.0 2>/dev/null` +- line ~1096 (T56): `run_mkhint -F -V 1.0.0 2>/dev/null` + +Use grep to confirm none remain: `grep -n 'run_mkhint.* -v ' tests/mkhint_test.sh` +Expected: only the `-v` in T65 (bare, no value) — actually T65 uses `run_mkhint -v 2>&1` +with no trailing space-value, so this grep (`-v ` followed by a token) should +return nothing. Verify by eye. + +- [ ] **Step 8: Run full suite** + +Run: `bash -n mkhint && bash tests/mkhint_test.sh 2>&1 | tail -4` +Expected: `Results: 138 passed, 0 failed` (135 + T65/T66/T67). + +- [ ] **Step 9: Commit** + +```bash +git add mkhint tests/mkhint_test.sh +git commit -S -m "feat!: -v/--version prints tool version; hint version moves to -V/--set-version" +``` + +--- + +## Task 2: `--help` text + script header comments + +**Files:** +- Modify: `mkhint` (header comments ~6-7; `show_help` ~50-78) + +- [ ] **Step 1: Update the version-showing header line in show_help** + +In `mkhint`, change the `show_help` title line (~50): + +```bash +mkhint $MKHINT_VERSION - Manage hint files for slackrepo scripts +``` + +(The heredoc is `<<EOF` (unquoted), so `$MKHINT_VERSION` expands.) + +- [ ] **Step 2: Update usage/synopsis lines in show_help** + +Change the two `--version VERSION` usage lines (~53-54): + +```bash + ./mkhint --set-version VERSION --hintfile FILE Update existing hint file + ./mkhint --set-version VERSION --new FILE Create new hint file +``` + +- [ ] **Step 3: Update the Options block in show_help** + +Replace the `--version, -v VERSION` option line (~68) with two lines: + +```bash + --version, -v Print version and exit + --set-version, -V VER New version string (required for --hintfile) +``` + +And update the `--new` line (~70) reference `--version` → `--set-version`: + +```bash + --new, -n FILE Create new hint file (required with --set-version or standalone) +``` + +Also `--hintfile` line (~69): `required with --version` → `required with --set-version`. + +- [ ] **Step 4: Update the script-header comments** + +Change the two comment usage lines (~6-7): + +```bash +# ./mkhint --set-version VERSION --hintfile FILE Update existing hint file +# ./mkhint --set-version VERSION --new FILE Create new hint file +``` + +- [ ] **Step 5: Verify help renders and syntax is clean** + +Run: `bash -n mkhint && bash mkhint --help | head -3` +Expected: line 1 shows `mkhint 1.0.0 - Manage hint files for slackrepo scripts`. + +- [ ] **Step 6: Commit** + +```bash +git add mkhint +git commit -S -m "docs: show version in --help, rename version flag in help text" +``` + +--- + +## Task 3: Bash completion + +**Files:** +- Modify: `mkhint.bash-completion` (`all_flags` line 11; case ~42) + +- [ ] **Step 1: Update all_flags** + +In `mkhint.bash-completion`, replace the `all_flags` line (11) to add `--set-version -V` +(keep `--version -v` in the list; it is terminal, no argument): + +```bash + local all_flags="--version -v --set-version -V --hintfile -f --new -n --list -l --review -R --clean -c --check -C --fix-current -F --delete -d --no-dl -N --help -h" +``` + +- [ ] **Step 2: Move the version-suggest case to --set-version|-V** + +Change the case label (~42) from `--version|-v)` to: + +```bash + --set-version|-V) +``` + +The body (suggesting the current VERSION from the named hint file) is unchanged. +`--version`/`-v` need no case — they take no argument. + +- [ ] **Step 3: Syntax check the completion** + +Run: `bash -n mkhint.bash-completion && echo OK` +Expected: `OK` + +- [ ] **Step 4: Commit** + +```bash +git add mkhint.bash-completion +git commit -S -m "feat: completion knows -V/--set-version, -v/--version terminal" +``` + +--- + +## Task 4: CHANGELOG + docs + SemVer note + +**Files:** +- Create: `CHANGELOG.md` +- Modify: `README.md` (flag refs, examples, SemVer note) +- Modify: `CLAUDE.md` (flag refs, test table) + +- [ ] **Step 1: Create CHANGELOG.md** + +Write `CHANGELOG.md`: + +```markdown +# Changelog + +All notable changes to this project are documented here. The format is based on +[Keep a Changelog](https://keepachangelog.com/), and this project adheres to +[Semantic Versioning](https://semver.org/). + +## [1.0.0] - 2026-07-04 + +First tagged release. mkhint manages slackrepo hint files: create/update hints, +nvchecker-driven update checks, phantom-dep stripping for -current, and a +listing/review workflow. + +### Changed +- **Breaking:** the hint-version flag is now `-V` / `--set-version`. `-v` / + `--version` now prints the tool's own version and exits. + +### Added +- `-v` / `--version` prints `mkhint X.Y.Z`. +- The `--help` header shows the version. +- `-l` colors the newer version cell green and adds a `DelReq` column. +``` + +- [ ] **Step 2: Update README flag references and examples** + +In `README.md`, find every `-v` / `--version` that meant setting the hint version +and change to `-V` / `--set-version`. Run first to locate: + +Run: `grep -n '\-v \|--version\|set-version' README.md` + +Update each hint-version usage example and the options/flags description. Add a +short SemVer section near the top or bottom: + +```markdown +## Versioning + +This project follows [Semantic Versioning](https://semver.org/). Commits use +[Conventional Commits](https://www.conventionalcommits.org/): `feat:` bumps the +minor version, `fix:` the patch version, and a `!` / `BREAKING CHANGE` the major +version. Releases are tagged `vX.Y.Z`; the version is stored in `MKHINT_VERSION` +in the `mkhint` script. `mkhint -v` prints it. +``` + +- [ ] **Step 3: Update CLAUDE.md flag references** + +In `CLAUDE.md`, update any `-v`/`--version` that means hint-version to +`-V`/`--set-version`. Run first: `grep -n '\-v \|--version\|set-version' CLAUDE.md` + +Add a one-line note under Configuration or a new "Versioning" note: the tool +version lives in `MKHINT_VERSION`; `-v`/`--version` prints it; `-V`/`--set-version` +sets a hint's version. + +- [ ] **Step 4: Add T65-T67 to the CLAUDE.md test table** + +Append after T64: + +``` +| T65 | `mkhint -v` prints `mkhint <version>`, exit 0 | +| T66 | `mkhint --version` prints `mkhint <version>`, exit 0 | +| T67 | `mkhint -V <ver> -n <pkg>` sets hint VERSION (rename works) | +``` + +- [ ] **Step 5: Full suite + syntax, sanity re-read docs** + +Run: `bash -n mkhint && bash tests/mkhint_test.sh 2>&1 | tail -3` +Expected: `138 passed, 0 failed`. + +- [ ] **Step 6: Commit** + +```bash +git add CHANGELOG.md README.md CLAUDE.md +git commit -S -m "docs: add CHANGELOG, document SemVer and -V/--set-version rename" +``` + +--- + +## Task 5: Tag the release + +**Files:** none (git tag only) + +- [ ] **Step 1: Confirm working tree is clean and tests pass** + +Run: `git status --porcelain && bash tests/mkhint_test.sh 2>&1 | tail -2` +Expected: no output from status; `138 passed, 0 failed`. + +- [ ] **Step 2: Create the signed annotated tag** + +```bash +git tag -s v1.0.0 -m "mkhint 1.0.0" +git tag -v v1.0.0 +``` +Expected: `git tag -v` shows a good GPG signature. + +- [ ] **Step 3: Push commits and tag to both remotes** + +`origin` has two push URLs (danix_git, slackware_forge). + +```bash +git push origin master +git push origin v1.0.0 +``` +Expected: both refs land on both remotes. + +--- + +## Self-review notes + +- Spec coverage: version constant + output (Task 1), flag rename (Task 1), mutual-excl messages (Task 1), help text (Task 2), completion (Task 3), CHANGELOG (Task 4), README/CLAUDE + SemVer/Conventional note (Task 4), git tag (Task 5), tests T65-T67 + renames (Task 1). All covered. +- Flag names consistent across tasks: `-V`/`--set-version` (hint version), `-v`/`--version` (tool version, no arg). +- getopt string `vV:f:n:lcCdNhRF` — `v` bare, `V:` takes arg. Verified against current `v:f:n:lcCdNhRF`. +- Test count: 135 → 138 (T65, T66, T67). Renamed calls do not change the count. +- T26/T56 assert exit code only (no message grep), so `-v`→`-V` is safe there. +- Breaking change flagged with `feat!:` commit and CHANGELOG "Breaking" entry. |
