From 8c4d8dac3afd0cbdb018c895e20d503c48c4393c Mon Sep 17 00:00:00 2001 From: Human Date: Sat, 26 Sep 2026 16:35:53 -0700 Subject: [PATCH] sync help, man page and reference with current behavior - wrktr_use: parses the five session keys and never executes the config; a failed load keeps the previous session. The reference also claimed old-format configs are sourced, which has been untrue since 1.0.1. - wrktr_push (-u, force offer only after a rejection), wrktr_adopt (all remotes, uncommitted-changes warning), wrktr_reload (keeps the session, refuses a bad file), wrktr_git in dry-run (read-only commands run) and the offline fallback of wrktr_add/wrktr_checkout are now documented. - Man page: replace the placeholder clone URLs, keep the ./install.sh line from being dropped as a macro, and use a date mandoc can parse. Tests: guard tests for the help, man page and reference statements, a check for placeholder URLs in every doc, and a mandoc lint test. CI installs mandoc on Linux so that test runs there. --- .github/workflows/ci.yml | 4 +-- CHANGELOG.md | 2 ++ docs/wrktr.1 | 23 ++++++++++----- docs/wrktr.md | 8 +++--- tests/commands.bats | 61 ++++++++++++++++++++++++++++++++++++++-- worktree-functions.sh | 31 +++++++++++++++----- 6 files changed, 107 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b31cc4a..bc3970c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,12 +72,12 @@ jobs: steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Install bats-core and zsh (Ubuntu) + - name: Install bats-core, zsh and mandoc (Ubuntu) if: runner.os == 'Linux' run: | git clone --depth 1 https://github.com/bats-core/bats-core.git /tmp/bats-core sudo /tmp/bats-core/install.sh /usr/local - sudo apt-get install -y zsh + sudo apt-get install -y zsh mandoc - name: Install bats-core and bash (macOS) if: runner.os == 'macOS' diff --git a/CHANGELOG.md b/CHANGELOG.md index f03415d..ec9b58a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html): - Tests: `wrktr_init` dry-run and stale-temp-dir cases (run in a pty via `tests/helpers/run_in_pty.py`), and zsh source/unload/reload cases ### Changed +- CI: the Linux job installs `mandoc` so the man-page lint test runs there (macOS already has it) - CI: `actions/checkout` bumped to v7.0.1 (pinned by SHA), which runs on Node 24; the previous pin ran on the deprecated Node 20 - `install.sh` no longer edits your shell profile without consent: it asks first when run in a terminal, and leaves the profile untouched (printing the line to add) when it is not. New flags: `--yes` adds the line without asking, `--no-profile` never touches the profile. `update.sh` passes flags through. - `uninstall.sh` asks before removing the source line from each profile, and lists the profiles without changing them when not run in a terminal. `--yes` removes the line without asking. @@ -31,6 +32,7 @@ Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html): - Release workflow: fails if the tag does not match `WRKTR_VERSION` and a CHANGELOG entry ### Fixed +- Docs: in-script `wrktr_help`, the man page and `docs/wrktr.md` now describe current behavior for `wrktr_use` (parses the config, never sources it; a failed load keeps the previous session), `wrktr_push`, `wrktr_adopt`, `wrktr_reload`, `wrktr_git` in dry-run, and the offline fallback of `wrktr_add`/`wrktr_checkout`; the reference no longer says old-format configs are sourced. Man page: replaced the placeholder clone URLs, fixed the `./install.sh` line that was dropped from the rendered page, and set a date that man tools can parse - `wrktr_use`: when the session being loaded fails validation, the previously loaded session is restored instead of being lost - `wrktr_init`: the bare repository's `HEAD` now points at the chosen main branch instead of an unborn `master`, so plain git commands in the bare repo work; an invalid branch name is now rejected before anything is created - `uninstall.sh`: rewrites profiles in place, so a symlinked profile stays a symlink and keeps its permissions, and no longer aborts when the source line was the only line diff --git a/docs/wrktr.1 b/docs/wrktr.1 index 3e74257..c7b3ccc 100644 --- a/docs/wrktr.1 +++ b/docs/wrktr.1 @@ -1,6 +1,6 @@ .\" wrktr.1 — manual page for the wrktr shell worktree manager .\" Install: cp wrktr.1 ~/.local/share/man/man1/ && man -W ~/.local/share/man/man1 -.TH WRKTR 1 "June 2026" "wrktr 1.0.2" "User Commands" +.TH WRKTR 1 "June 23, 2026" "wrktr 1.0.2" "User Commands" . .SH NAME wrktr \- branch-as-directory git worktree session manager @@ -80,9 +80,9 @@ Required only by . .SH INSTALLATION .nf -git clone https://github.com/your-username/wrktr.git +git clone https://github.com/gentbot/wrktr.git cd wrktr -./install.sh +\&./install.sh .fi .PP .B install.sh @@ -132,8 +132,11 @@ Convert an existing normal git clone to the wrktr structure. wrktr_adopt [path] .fi .PP -Creates a bare clone from an existing repo. +Creates a bare clone from an existing repo and restores every remote of the +original clone. The original clone is not modified. +Only committed state is carried over; uncommitted changes and stash entries +are listed and confirmed before continuing. . .SS wrktr_init Initialize a bare repository from a new local project with no remote. @@ -185,7 +188,7 @@ wrktr_use Parses .IR ~/.config/wrktr/.env , exports session variables, and validates. -On failure, all variables are unset. +On failure, the previously loaded session, if any, stays active. Sessions are shell-scoped. . .SS wrktr_list @@ -281,9 +284,12 @@ Refuses if the working tree has uncommitted changes. .SS wrktr_push Push the current branch to the configured remote. Refuses to push the main branch. +Pushes with +.BR \-u , +so the branch tracks the remote. Prompts before retrying with .B \-\-force\-with\-lease -if the push is rejected. +if the push is rejected; other failures are reported without a force offer. . .SS wrktr_remove Remove a worktree and optionally delete the branch ref. @@ -309,6 +315,7 @@ Automatically supplies Use from outside a worktree; from inside, plain .BR git (1) works without it. +In dry-run mode, read-only commands still run and only mutating ones are printed. . .SS wrktr Raw passthrough to @@ -360,6 +367,8 @@ variables from the current shell. .B wrktr_reload Unload and re-source from the original path. Useful after editing .IR worktree-functions.sh . +The loaded session, dry-run state and settings are kept, and the reload is +refused if the file has a syntax error. .TP .B wrktr_prompt_info Output a context string for embedding in @@ -510,7 +519,7 @@ in the repository root. wrktr contributors. .PP Source and issue tracker: -.I https://github.com/your-username/wrktr +.I https://github.com/gentbot/wrktr . .SH LICENSE MIT License. See diff --git a/docs/wrktr.md b/docs/wrktr.md index a059f4a..9a40c68 100644 --- a/docs/wrktr.md +++ b/docs/wrktr.md @@ -427,7 +427,7 @@ Loads a project config into the current shell. wrktr_use omi ``` -Sources `~/.config/wrktr/omi.env`. If validation fails, all variables are unset so the shell is not left in a partial state. +Parses `~/.config/wrktr/omi.env` (only the five session keys are read; the file is never executed) and validates the result. If validation fails, the previously loaded session, if any, stays active. --- @@ -532,7 +532,7 @@ PS1='$(wrktr_prompt_info) \$ ' Creates a new branch and worktree directory, then `cd`s into it. ```bash -wrktr_add feature/login # branch from origin/main (fetches first) +wrktr_add feature/login # branch from origin/main (fetches first; offline it uses the refs fetched earlier) wrktr_add fix/crash origin/v2 # branch from a specific ref wrktr_add experiment/auth main # branch from local main ``` @@ -552,7 +552,7 @@ Creates a local worktree for a branch that already exists on the remote. wrktr_checkout feature/login ``` -Fetches first, verifies the remote branch exists (lists available ones if not), creates the local worktree, sets up upstream tracking, and `cd`s in. Requires a remote to be configured. +Fetches first (if the fetch fails, for example offline, it continues with the refs fetched earlier), verifies the remote branch exists (lists available ones if not), creates the local worktree, sets up upstream tracking, and `cd`s in. Requires a remote to be configured. --- @@ -792,7 +792,7 @@ This does not affect the project files or bare repository. ### Migrating old configs -Configs created before this format change used shell script syntax (`export KEY=value`). These are detected automatically on load and still work — `wrktr_use` sources them as before and prints a migration notice. To migrate, run `wrktr_config_edit` and remove the `export ` prefix from each line. +Configs created before this format change used shell script syntax (`export KEY=value`). These are detected automatically on load and still work — `wrktr_use` reads the `KEY=value` pairs (it strips the `export ` prefix and never executes the file) and prints a migration notice. To migrate, run `wrktr_config_edit` and remove the `export ` prefix from each line. --- diff --git a/tests/commands.bats b/tests/commands.bats index 9ca57e6..9182d48 100644 --- a/tests/commands.bats +++ b/tests/commands.bats @@ -631,8 +631,14 @@ EOS [ -z "$missing" ] || { echo "undocumented:$missing"; return 1; } } -@test "docs: README has no placeholder clone URL" { - ! grep -q 'your-username' "$BATS_TEST_DIRNAME/../README.md" +@test "docs: no placeholder clone URL in README, reference or man page" { + ! grep -rq 'your-username' "$BATS_TEST_DIRNAME/../README.md" "$BATS_TEST_DIRNAME/../docs" +} + +@test "docs: man page has no lint errors or warnings" { + command -v mandoc >/dev/null 2>&1 || skip "mandoc not available" + run bash -c "mandoc -Tlint \"$BATS_TEST_DIRNAME/../docs/wrktr.1\" 2>&1 | grep -v STYLE" + [ -z "$output" ] } # --------------------------------------------------------------------------- @@ -758,3 +764,54 @@ _make_worktree() { [[ "$output" =~ "Worktree remove failed" ]] [ -f "$TRUNK/feature%2Fr5/untracked" ] } + +# --------------------------------------------------------------------------- +# Help, man page and reference stay in step with behavior +# --------------------------------------------------------------------------- + +@test "help: wrktr_use describes parsing and session restore, not sourcing" { + run wrktr_help use + [ "$status" -eq 0 ] + [[ ! "$output" =~ "Sources" ]] + [[ "$output" =~ "previously loaded session" ]] +} + +@test "help: wrktr_push mentions upstream tracking and force only after a rejection" { + run wrktr_help push + [[ "$output" =~ "-u" ]] + [[ "$output" =~ "rejected" ]] +} + +@test "help: wrktr_adopt mentions every remote and uncommitted changes" { + run wrktr_help adopt + [[ "$output" =~ "remote" ]] + [[ "$output" =~ "uncommitted" ]] +} + +@test "help: wrktr_reload says it keeps the session" { + run wrktr_help reload + [[ "$output" =~ "session" ]] + [[ "$output" =~ "syntax" ]] +} + +@test "help: wrktr_git says read-only commands run in dry-run mode" { + run wrktr_help git + [[ "$output" =~ "dry-run" ]] +} + +@test "help: wrktr_add and wrktr_checkout mention the offline fallback" { + run wrktr_help add + [[ "$output" =~ "fetch fails" ]] + run wrktr_help checkout + [[ "$output" =~ "fetch fails" ]] +} + +@test "docs: reference no longer says wrktr_use sources configs" { + ! grep -q 'sources them as before' "$BATS_TEST_DIRNAME/../docs/wrktr.md" + ! grep -q '^Sources `~/.config/wrktr' "$BATS_TEST_DIRNAME/../docs/wrktr.md" + ! grep -q 'all variables are unset' "$BATS_TEST_DIRNAME/../docs/wrktr.md" +} + +@test "docs: man page does not say a failed wrktr_use unsets all variables" { + ! grep -q 'all variables are unset' "$BATS_TEST_DIRNAME/../docs/wrktr.1" +} diff --git a/worktree-functions.sh b/worktree-functions.sh index 69f0164..e288aaf 100644 --- a/worktree-functions.sh +++ b/worktree-functions.sh @@ -555,6 +555,9 @@ wrktr_adopt [path] Convert an existing normal git clone into a wrktr bare repository structure. The original clone is not modified — remove it manually when confirmed. + Every remote of the original clone is restored, not only origin. Only + committed state is carried over: if the clone has uncommitted changes or + stash entries, they are listed and you are asked before continuing. Prompts: Path to existing git clone Must have a .git subdirectory @@ -635,9 +638,10 @@ EOF cat <<'EOF' wrktr_use - Load a project session config into the current shell. Sources - ~/.config/wrktr/.env and validates the result. If validation - fails, all variables are unset so the shell is not left in a partial state. + Load a project session config into the current shell. Parses + ~/.config/wrktr/.env (only the five session keys are read; the + file is never executed) and validates the result. If validation fails, the + previously loaded session, if any, is left active. Examples: wrktr_use myapp @@ -754,6 +758,8 @@ wrktr_add [base-ref] when a remote is configured, or without one. Fetches from the remote automatically before creating (when remote is set). + If the fetch fails (for example offline), it continues with the refs fetched + previously and fails only if the base ref is not among them. Examples: wrktr_add feature/login @@ -768,7 +774,9 @@ wrktr_checkout Create a local worktree for a branch that already exists on the remote. Fetches first, verifies the remote branch exists, creates the worktree, - sets up upstream tracking, and cds in. Requires a remote to be configured. + sets up upstream tracking, and cds in. If the fetch fails (for example + offline), it continues with the refs fetched previously. Requires a remote + to be configured. Examples: wrktr_checkout feature/login @@ -821,9 +829,10 @@ wrktr_push Push the current branch to the configured remote. Must be run from inside a worktree belonging to the loaded session. - Refuses to push the main branch. Attempts a regular push first; if rejected - (expected after wrktr_rebase), prompts before retrying with --force-with-lease. - Requires a remote to be configured. + Refuses to push the main branch. Pushes with -u so the branch tracks the + remote. If the push is rejected (expected after wrktr_rebase), prompts before + retrying with --force-with-lease; other failures (authentication, network) + are reported without a force-push offer. Requires a remote to be configured. Examples: wrktr_push @@ -885,6 +894,10 @@ wrktr_git automatically. Use from outside a worktree. From inside a worktree, ordinary 'git' commands work without it. + In dry-run mode, read-only commands (log, status, rev-parse, branch + listing, ...) still run; anything that could change the repository is only + printed. + Examples: wrktr_git fetch origin wrktr_git branch -d feature/login @@ -962,6 +975,10 @@ wrktr_reload path it was originally loaded from (WRKTR_SOURCE_PATH). Use after editing the file to pick up changes without starting a new shell. + The loaded session, dry-run state, WRKTR_CONFIG_DIR and WRKTR_REPO_DIR_NAME + are kept. If the file has a syntax error the reload is refused and the + version already loaded stays in place. + Examples: wrktr_reload EOF