GitBaby/AGENTS.md
zhenyi 680411c4fb chore: initialize gitbaby repository
gitbaby is an asynchronous Rust library wrapping git operations, built on
gix + tokio + async-trait.

Module layout:
- archive, blame, blob, branch, cleanup, commit, compare, config,
  conflict, diff, merge, refs, remote, setup, share, submodule, tags,
  tree (feature modules)
- command: command scheduler (cmd/env/pipe/context/error)
- repo: RepositoryFacade trait (consumers implement, exposing a
  gix::Repository)

Features:
- async API on tokio 1.53
- order-preserving Env (Vec<(String, String)>)
- hand-written BabyError / CmdError, not using thiserror derive
- integration tests covering cmd_run / context / env / pipe (env keys
  prefixed for isolation)

CI: none, standard cargo build / test / clippy / fmt only
2026-08-14 18:10:04 +08:00

38 lines
3.2 KiB
Markdown

# AGENTS.md — gitbaby
## What this is
- Single-crate Rust **library** (no binary, no workspace). Edition `2024`.
- Public entrypoint: `GitBaby::new(facade: Arc<dyn RepositoryFacade>, pipe: Pipe)` in `src/lib.rs`.
- Consumers **must implement** `RepositoryFacade` (`src/repo.rs`) — three async fns returning a path/paths and a `gix::Repository`. There is no default impl.
## Build / test / verify
- Standard cargo only. No CI, no pre-commit, no scripts, no rust-toolchain pin.
- Edition 2024 requires a recent stable toolchain (rustc ≥ 1.85). Local env verified at `rustc 1.97.1`.
- Useful commands (no order dependency beyond what's standard):
- `cargo build` / `cargo check` / `cargo build --release`
- `cargo test` (sync + `#[tokio::test]` integration tests in `tests/`)
- `cargo test --test <file>` to run a single integration test file
- `cargo test <name>` to filter by test name substring
- `cargo clippy --all-targets -- -D warnings` if strict
- `cargo fmt --check` / `cargo fmt` (default rustfmt; no `rustfmt.toml`)
## Architecture notes
- **Error pattern is hand-written.** `BabyError` (`src/error.rs`, ~50 variants) and `CmdError` (`src/command/error.rs`) implement `Display` + `std::error::Error` by hand. `thiserror` is in `Cargo.toml` **but not used via `#[derive(thiserror::Error)]`**. Do not "modernize" by adding the derive — keep the hand-written impls consistent.
- `Env` in `src/command/env.rs` is **order-preserving** (`Vec<(String, String)>`), not a `HashMap`. `with` appends, `set` replaces in place. This matters for env-var ordering in spawned processes.
- `Cmd::Display` = `prog` + `config_args` + `args` (config_args are prepended to args at runtime).
- `Pipe` is `Clone`; `cancel_pipe()` sets `cancelled=true` and sends `start_kill()` to every running child but does **not** remove them from `cmds`.
## Module layout convention
- Most feature modules follow `src/<feature>/{mod.rs, types.rs, helper.rs, usecase.rs}`; `mod.rs` re-exports the public types from `types.rs`.
- **`src/share/` is the outlier**: it uses `{cmd.rs, env.rs, error.rs, path.rs}` instead. Don't "normalize" it.
- `src/command/` uses `{cmd.rs, context.rs, env.rs, error.rs, pipe.rs}` and has its own `error.rs` separate from `src/error.rs`.
## Test quirks (`tests/`)
- `tests/cmd_run.rs` defines a local `unwrap_or_recover_or_panic!`-style macro for asserting command output — reuse it, don't reinvent.
- `tests/env.rs` mutates process env. It guards tests with `static ENV_LOCK: Mutex<()>` and uses keys prefixed `GITBABY_TEST_ENV_<suffix>` for isolation. `std::env::set_var` / `remove_var` are wrapped in local `unsafe fn`s; follow that pattern when adding env-mutating tests.
- `tests/pipe.rs` async cancel tests call `tokio::time::sleep(Duration::from_millis(200))` after `cancel_pipe()` to let `Child::try_wait` observe exit — keep that delay when adding new cancel tests.
## Gotchas
- No README. No docs beyond the code. Treat `Cargo.toml` + source as the only source of truth.
- `gix = "0.86"`, `tokio = 1.53` (full features), `time = 0.3` — all recent; do not bump them speculatively.
- Public API surfaces async (`async_trait`); sync callers must use a runtime (tests use `#[tokio::test]`).