78 lines
2.6 KiB
Markdown
78 lines
2.6 KiB
Markdown
|
|
# Contributing to fj
|
||
|
|
|
||
|
|
## Setup
|
||
|
|
|
||
|
|
```sh
|
||
|
|
git clone ssh://git@rasterhub.com:2222/rasterstate/fj.git
|
||
|
|
cd fj
|
||
|
|
./scripts/install-hooks.sh # symlinks hooks/pre-push into .git/hooks
|
||
|
|
cargo build --release # 4 MB binary at target/release/fj
|
||
|
|
```
|
||
|
|
|
||
|
|
The hook gates every push on fmt, clippy (warnings as errors), the full
|
||
|
|
test suite, and a release build. Set `FJ_E2E=1` to additionally run the
|
||
|
|
live API smoke (requires `fj auth login` already done).
|
||
|
|
|
||
|
|
## Workflow
|
||
|
|
|
||
|
|
1. Branch off `main`.
|
||
|
|
2. Make changes. Keep commits focused.
|
||
|
|
3. `cargo fmt --all` before committing.
|
||
|
|
4. The pre-push hook runs the full bar; if it fails, fix the issue
|
||
|
|
rather than passing `FJ_SKIP_PREPUSH=1` unless you genuinely need
|
||
|
|
to bypass.
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
- 60 tests live in the source tree (51 unit + 9 wiremock integration).
|
||
|
|
- Unit tests stay close to the code they cover, in inline `#[cfg(test)]`
|
||
|
|
modules.
|
||
|
|
- HTTP integration tests live in `src/client/integration_tests.rs` and
|
||
|
|
use a wiremock server. Construct test clients via
|
||
|
|
`Client::for_base_url(base, token)`.
|
||
|
|
- Live API tests live in `scripts/e2e-smoke.sh` and exercise read-only
|
||
|
|
operations against the configured Forgejo. Toggle with `FJ_E2E=1`.
|
||
|
|
|
||
|
|
## Adding a subcommand
|
||
|
|
|
||
|
|
Concrete example: adding `fj sticker list`.
|
||
|
|
|
||
|
|
1. `src/api/sticker.rs` — typed API wrappers and request/response
|
||
|
|
structs. Use the `serde_util::deserialize_null_to_default` helper
|
||
|
|
for fields that Forgejo returns as `null` when empty.
|
||
|
|
2. `src/cli/sticker.rs` — clap `Args` / `Subcommand` definitions and
|
||
|
|
the `run` dispatch.
|
||
|
|
3. `src/api/mod.rs` — `pub mod sticker;`
|
||
|
|
4. `src/cli/mod.rs` — `pub mod sticker;`, add to `Command`, add the
|
||
|
|
dispatch arm in `dispatch()`.
|
||
|
|
5. `src/main.rs` — add `"sticker"` to `KNOWN_SUBCOMMANDS` so plugin
|
||
|
|
discovery doesn't shadow it.
|
||
|
|
6. Add inline `#[cfg(test)] mod tests` for any non-trivial pure code.
|
||
|
|
7. If you touched HTTP behavior, add a wiremock test in
|
||
|
|
`src/client/integration_tests.rs`.
|
||
|
|
|
||
|
|
## Code style
|
||
|
|
|
||
|
|
- See `CLAUDE.md` for in-tree conventions.
|
||
|
|
- One small line of comment max per non-obvious thing. Don't narrate
|
||
|
|
what code does, only why.
|
||
|
|
- No `.unwrap()` / `.expect()` in non-test code paths. Use `?` and
|
||
|
|
`anyhow::Error::context` to attach actionable messages.
|
||
|
|
- Prefer `Result` over panics. The one exception is `unreachable!()`
|
||
|
|
for genuinely impossible match arms, but flag it in review.
|
||
|
|
|
||
|
|
## Releasing
|
||
|
|
|
||
|
|
```sh
|
||
|
|
cargo build --release
|
||
|
|
./target/release/fj completion zsh > ~/.zfunc/_fj
|
||
|
|
./target/release/fj man -o ./man
|
||
|
|
```
|
||
|
|
|
||
|
|
No cargo-dist or Homebrew tap yet. Binary lives at `target/release/fj`;
|
||
|
|
symlink into a user-level bin dir.
|
||
|
|
|
||
|
|
## License
|
||
|
|
|
||
|
|
MIT. By contributing you agree to the same license.
|