alunduil / alunduil/alunduil-infrastructure

Stand up git-worktree-poi as a Rust binary repo to replace the bash worktree pruner

Aberta
#116 0 comentários 0 reações 0 responsáveis Ver no GitHub
enhancement
Linguagem predominante
Shell
Estrelas
0
Forks
0
Merge médio
6h 30min
PRs com merge (30d)
97

Descrição

## Summary

Stand up [`alunduil/git-worktree-poi`](https://github.com/alunduil/git-worktree-poi) — a Rust CLI that replaces the chezmoi-managed bash `dot_local/bin/executable_git-worktree-poi` (now ~633 lines) driving worktree classification, the gh-poi-style report, and pruning in the pair workflow. This is the cross-repo planning artifact for the project: decisions, the single new repo to create, and the bootstrap milestone that closes it. Supersedes the deferral in [alunduil-chezmoi ADR 0001](https://github.com/alunduil/alunduil-chezmoi/blob/main/docs/adr/0001-keep-git-worktree-poi-in-bash.md), re-evaluated in [alunduil-chezmoi#205](https://github.com/alunduil/alunduil-chezmoi/issues/205) and recorded as [alunduil-chezmoi ADR 0002](https://github.com/alunduil/alunduil-chezmoi/blob/main/docs/adr/0002-port-git-worktree-poi-to-rust.md).

Bounded against the other pair-workflow artifact, #155 (`zellij-claude-pair`): that plugin owns the in-session surface (repo picker, status widgets); this CLI runs headless under a systemd timer and the `git-poi-all` sweeper, outside any zellij session.

## Background and motivation

ADR 0001 (2026, alunduil-chezmoi) kept the pruner in bash and deferred a rewrite behind explicit triggers. Two have since fired:

- **Size.** The ADR cited 234 lines as the evidence it was small enough for bash. The script is now 633 lines — 2.7×, well past the ADR's own "~100 lines of bash addition" trigger.
- **GraphQL batching.** ADR 0001 named [alunduil-chezmoi#147](https://github.com/alunduil/alunduil-chezmoi/issues/147) (batched PR-state lookup) as a revisit trigger; it landed as bash in [alunduil-chezmoi#154](https://github.com/alunduil/alunduil-chezmoi/issues/154) via a `gh api graphql` heredoc + `jq` — exactly the "more jq/heredoc surgery than a rewrite would cost" trigger.

ADR 0001 picked Go on a `gh-poi`-extension framing, but the tool never became a `gh` extension — it's a standalone bin. The pair workflow's other tooling has since standardized on Rust (#155, which absorbed the separately-planned `git-repo-picker` #54 and `zellij-git-status` #26), and rustup is already bootstrapped in chezmoi. So the port goes to Rust, aligning the toolchain.

## Strategic decisions

| Decision | Choice | Rationale |
|---|---|---|
| Binary runtime | Rust → native CLI | Matches the pair workflow's other Rust tooling (#155); rustup bootstrapped in chezmoi. Supersedes ADR 0001's Go pick |
| License | MIT | Matches surrounding ecosystem |
| Versioning | SemVer 2.0.0 | Standard |
| Changelog | Keep a Changelog 1.1.0 | Manual; no auto-gen day 1 |
| Distribution | GitHub Releases (precompiled per platform) | Mirrors `script/install/{gcx,act,lazygit}` in chezmoi |
| Platforms | linux-x86_64, linux-aarch64 | Covers Crostini host; expand on request |
| Data sources | `git`, `gh`/`octocrab` | `git` for worktree/branch state; batched GraphQL for PR state (replaces chezmoi#154's jq/heredoc) |
| Color | Rust color crate (`owo-colors`/`anstream`) | Replaces ADR 0001's `tput`/ANSI in `print_section` |

## Repository inventory

| Status | Repository | Purpose | Notes |
|---|---|---|---|
| ✅ created | [`alunduil/git-worktree-poi`](https://github.com/alunduil/git-worktree-poi) | The CLI binary | Created out-of-band, adopted into Terraform in #263 |
| ✅ exists | `alunduil/alunduil-chezmoi` | Binary consumer | `script/install/` pin, bin removal, systemd `ExecStart` swap, bats removal, `git-poi-all` contract — [alunduil-chezmoi#295](https://github.com/alunduil/alunduil-chezmoi/issues/295) |
| ✅ exists | `alunduil/alunduil-infrastructure` | Cross-repo planning | This issue |

## Architecture

Issue references below are alunduil-chezmoi, where the bash pruner lives.

- **Worktree classification** — canonical-path resolution ([chezmoi#138](https://github.com/alunduil/alunduil-chezmoi/issues/138)), namespaced `/worktree/` branches ([chezmoi#110](https://github.com/alunduil/alunduil-chezmoi/issues/110)), in-use guard ([chezmoi#140](https://github.com/alunduil/alunduil-chezmoi/issues/140)), empty-worktree safe path ([chezmoi#141](https://github.com/alunduil/alunduil-chezmoi/issues/141)).
- **PR-state lookup** — one batched GraphQL per repo (the [chezmoi#154](https://github.com/alunduil/alunduil-chezmoi/issues/154) logic, in a typed language; `octocrab` or `gh api graphql` shell-out).
- **gh-poi-style report** — color, single-line rows, dimmed metadata, progress markers ([chezmoi#177](https://github.com/alunduil/alunduil-chezmoi/issues/177), [chezmoi#184](https://github.com/alunduil/alunduil-chezmoi/issues/184)).
- **Prune verbs** — merged / gone-upstream, empty-no-PR; `NAME` targeting + `--force` ([chezmoi#215](https://github.com/alunduil/alunduil-chezmoi/issues/215) parity).
- **Scheduling** — invoked by the `git-worktree-poi.timer` systemd user unit ([chezmoi#273](https://github.com/alunduil/alunduil-chezmoi/issues/273)); consumer keeps the timer, swaps `ExecStart` to the binary.
- **Sweeper contract** — `git-poi-all` ([chezmoi#253](https://github.com/alunduil/alunduil-chezmoi/issues/253)) shells `git-worktree-poi` across clones; keep the CLI stable or co-port (open question).

## Milestones to 1.0.0

**M0 — Repo bootstrap.** README/CONTRIBUTING/CHANGELOG/SECURITY; Cargo + `clap` hello-world; CI (fmt, clippy, test, cross-compile linux-{x86_64,aarch64}, `cargo deny`); Renovate (`config:best-practices`, pre-commit manager); templates + labels; first tagged `v0.0.1` (empty CLI, proves CI+release). *Exit:* binary downloads from Releases on both targets, runs `--version`, exits 0. **Tracked by this issue — the remaining work.**

**M1 — Pruner parity (0.1.0).** [git-worktree-poi#1](https://github.com/alunduil/git-worktree-poi/issues/1). Worktree enumeration + classification; gh-poi-style report; prune verbs; `NAME` + `--force`; bats → cargo test for pure logic, integration tests for git/gh paths. *Exit:* behaviour parity with the chezmoi bash pruner on the same host.

**M2 — Typed PR-state batching (0.2.0).** [git-worktree-poi#2](https://github.com/alunduil/git-worktree-poi/issues/2). Replace the chezmoi#154 `gh api graphql` heredoc + `jq` with typed batched lookup (`octocrab` or structured `gh` shell-out). *Exit:* one batched query per repo; no per-branch round-trips.

**M3 — Cut 1.0.0.** [git-worktree-poi#3](https://github.com/alunduil/git-worktree-poi/issues/3). Version bump, CHANGELOG release section, `v1.0.0` tag, both platform artifacts, and a documented CLI surface for the sweeper and the systemd unit to pin against. *Exit:* `v1.0.0` released and consumable.

The chezmoi-side swap — `script/install/git-worktree-poi` download-and-verify, `dot_local/bin/executable_git-worktree-poi` removed, `git-worktree-poi.service` `ExecStart` repointed, `git-poi-all` contract preserved, `test/git_worktree_poi.bats` deleted — lives in [alunduil-chezmoi#295](https://github.com/alunduil/alunduil-chezmoi/issues/295), blocked by M3. The consumer changes stay in the repo that owns those files rather than being tracked twice.

## CI/CD, release, Renovate, security

No Rust repo in the org is bootstrapped yet — `zellij-claude-pair` (#155) is still LICENSE-only, and `git-repo-picker` (#54) was closed without a repo — so M0 writes this blueprint rather than copying one: `ci.yml` (fmt/clippy/test/build-matrix/`cargo deny`, all required, draft PRs); `release.yml` on tag `v*` (per-platform tarballs + sha256, notes from CHANGELOG); manual version bump; Renovate `config:best-practices` + pre-commit manager + grouped `rust-lang/*`; Dependabot alerts, secret scanning + push protection, private vuln reporting. Repository settings are declared in `terraform/alunduil/repositories.tf`, not clicked in.

## Open questions

1. **Color crate** — `owo-colors` vs `anstream`/`yansi`. Decide before M1 (restated in git-worktree-poi#1).
2. **PR-state client** — `octocrab` vs `gh api graphql` shell-out. Decide before M2 (restated in git-worktree-poi#2).
3. **`git-poi-all`** — co-port to Rust, or keep the bash sweeper calling the new binary? Decide before M3 (restated in git-worktree-poi#3).
4. **Directory input** — positional arguments vs configuration for the worktree directories to scan. Raised in git-worktree-poi#1; bears on the sweeper contract and the systemd unit's invocation.

## Out of scope (deliberately)

- In-session repo picking and status widgets — #155 handles those.
- Shared cache/report crate with `zellij-claude-pair` — extract on rule of three.
- Non-GitHub forges, multi-VCS (jj/hg), telemetry.

## Done when

- [x] Repo created at [`alunduil/git-worktree-poi`](https://github.com/alunduil/git-worktree-poi) (MIT), adopted into Terraform (#263)
- [ ] M0 bootstrap complete (CI, release, templates, tagged `v0.0.1`)
- [x] Tracking issues for M1–M3 opened in the new repo ([#1](https://github.com/alunduil/git-worktree-poi/issues/1), [#2](https://github.com/alunduil/git-worktree-poi/issues/2), [#3](https://github.com/alunduil/git-worktree-poi/issues/3))
- [x] This issue updated with links to the new repo and per-milestone issues
- [x] alunduil-chezmoi consumer issue filed ([alunduil-chezmoi#295](https://github.com/alunduil/alunduil-chezmoi/issues/295)), blocked-by this issue

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.