airvzxf / airvzxf/voxora

Enhance Makefile with install/uninstall pair, developer-ergonomics, and release-helper targets

Aperta
#164 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
enhancement infrastructure
Lingua principale
Rust
Stelle
0
Fork
1
Merge medio
11m
PR unite (30g)
47

Descrizione

## Context

The repository ships a 96-line `Makefile` (build / test / lint / doc / package / bench / clean) but no `install` / `uninstall` pair, no PREFIX/DESTDIR support, and no developer-ergonomics targets. Downstream consumers and local operators who want `voxora-cli` on their `$PATH` have to either:

- run `sudo install -m 0755 target/release/voxora-cli /usr/local/bin/voxora` by hand, or
- rely on `cargo install --path voxora-cli --locked` (no FHS-style prefix, doesn't match the musl build path, and doesn't record where the binary landed so an uninstall is guesswork).

This came up while answering \"how do I install voxora locally with `sudo make install`?\" — there is no such target today, and `.DEFAULT_GOAL := help` swallows the request with a help banner.

## Goal

Extend the existing `Makefile` (do not replace it) with a coherent set of new targets grouped by concern, keeping the current target names, the T0/T1/T2/T3 validation tiers documented in `AGENTS.md`, and the documented `voxora-bridge` feature plumbing (`whisper` / `qwen3asr`) intact.

## Proposed target set

### Install / uninstall

| Target | Purpose |
|---|---|
| `install` | Build release `voxora-cli`, copy it to `$(BINDIR)/voxora` with `install -m 0755`, record the absolute path in `.install-track`. Honors `PREFIX` (default `/usr/local`) and `DESTDIR` (packagers). |
| `install-musl` | Same, but uses the static musl build under `target/x86_64-unknown-linux-musl/release/voxora-cli`. Fails fast if `rustup target list --installed` doesn't include `x86_64-unknown-linux-musl`. |
| `uninstall` | Reads `.install-track` and removes exactly the path the previous `make install` placed; refuses to guess if the track file is missing. |
| `reinstall` | `uninstall` + `install` (idempotent dev loop). |
| `prefix-check` | Echoes the effective `PREFIX` / `DESTDIR` / `BINDIR` so operators can dry-run packaging before `sudo make install`. |

### Developer ergonomics

| Target | Purpose |
|---|---|
| `init` | One-shot dev setup: best-effort `cargo install cargo-deny cargo-outdated cargo-audit cargo-watch cargo-sort cargo-msrv tokei-cli cargo-cyclonedx`; registers the repo's git hooks if present; prints the T0/T1/T2/T3 ladder from `AGENTS.md`. |
| `pre-commit` | T0 (`cargo fmt --all --check`) + T1 (`cargo clippy --workspace --all-targets -- -D warnings`). Mirrors AGENTS.md tier table. |
| `pre-push` | `pre-commit` + T2 (`cargo test --workspace --all-targets`, `cargo doc --no-deps --workspace`). |
| `ci` | The full T3 set used by `.github/workflows/*.yml` plus `package` and `bench-no-run`. |
| `watch` | `cargo watch -x check` (uses `cargo-watch` if installed; falls back to `find … -exec cargo check`). |
| `watch-test` | Same, but `-x test`. |
| `fmt-watch` | `cargo watch -x 'fmt --all'`. |
| `doc-open` | `xdg-open target/doc/index.html` (or `open` on macOS). |
| `tree` | `cargo tree --workspace --edges normal --no-dedupe`. |
| `meta` | `cargo metadata --format-version 1 > target/cargo-metadata.json` plus a one-line summary. |
| `outdated` | `cargo outdated --workspace --root-deps-only` (graceful skip if the subcommand isn't installed). |
| `audit` | `cargo audit` (security advisory DB). |
| `deny` | `cargo deny check` (mirrors the CI T3 job). |
| `msrv` | `cargo +$(MSRV) check --workspace --locked` (uses `rust-version` from `Cargo.toml`, currently 1.88). |
| `loc` | `tokei .` lines-of-code report. |
| `coverage` | `cargo tarpaulin --workspace --all-targets --out Html` (graceful skip if not installed). |
| `bump-patch` / `bump-minor` / `bump-major` | Coordinated workspace version bump. Defer to `release-plz` once #58 lands; until then a guarded `cargo set-version --workspace` + per-crate pin reminder. |

### Hygiene

| Target | Purpose |
|---|---|
| `clean-all` | `cargo clean` + `git clean -fdx` (with explicit `-e` for whatever the operator wants preserved). |
| `clean-target` | Just `rm -rf target/` without touching `.cargo-target/` or `.worktrees/` (matches `AGENTS.md` guard-artifacts paths). |
| `clean-doc` | `rm -rf target/doc/`. |
| `clean-fuzz` | `rm -rf fuzz/target fuzz/artifacts fuzz/corpus` (the AGENTS.md notes fuzz already lives in its own subtree). |

### Release helpers

| Target | Purpose |
|---|---|
| `publish-dry` | For every `publish = true` workspace crate, run `cargo publish --dry-run --locked --allow-dirty` and abort on the first failure. |
| `publish-order` | Print the publish ordering from `cargo metadata` reverse-dependency order so operators can `cargo publish` in the right sequence (the existing `release.yml::publish-cratesio` step consumes the same graph). |
| `tag` | Show the latest reachable git tag, the tag's commit, and confirm `tag^{commit} == origin/main` (mirrors the `AGENTS.md` § \"red / failed workflows\" invariant). |
| `sbom` | `cargo cyclonedx --format json --override-filename target/sbom.json --workspace` (best-effort; gracefully skip if `cargo-cyclonedx` is missing). |

## Acceptance

- `make help` lists every new target with a one-line description in the same compact format the current help banner uses.
- `make install PREFIX=\$HOME/.local DESTDIR=/tmp/stage` lands the binary at `/tmp/stage/$HOME/.local/bin/voxora` and writes the absolute path to `.install-track`.
- `make uninstall` removes exactly the path written by the previous `make install`; prints a clear \"no install record\" error if `.install-track` is absent instead of guessing.
- `make install-musl` fails with a helpful \"run rustup target add x86_64-unknown-linux-musl\" message when the musl target isn't installed.
- `make pre-commit`, `make pre-push`, and `make ci` map 1-to-1 to the T0/T1/T2/T3 tiers documented in `AGENTS.md`.
- Every target that needs an optional tool (`cargo-audit`, `cargo-deny`, `cargo-outdated`, `cargo-watch`, `tokei`, `cargo-tarpaulin`, `cargo-cyclonedx`, `cargo-msrv`, `cargo-sort`) gracefully reports \"tool not installed — skipping\" and exits 0 so the Makefile stays useful on minimal CI runners.
- `make tag` is read-only and emits the same `tag^{commit} == origin/main` verification the AGENTS.md § \"red / failed workflows\" section demands.
- `make guard-artifacts` (existing) still passes — the new targets do not introduce tracked files under `target/`, `.cargo-target/`, or `.worktrees/`.

## Out of scope

- Replacing `cargo` invocations with raw `rustc` calls.
- Adding a Rust source generator or `cargo xtask` (the project already uses `Makefile`; this issue keeps that boundary).
- Adopting `release-plz` (issue #58) — the `bump-*` targets should degrade gracefully until that lands.
- Anything that requires `sudo` by default. `sudo make install` is the operator's choice; the Makefile must work without root for `$HOME/.local` prefixes.
- Changing the existing target names or breaking the current `.DEFAULT_GOAL := help` behavior.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.