diff --git a/AGENTS.md b/AGENTS.md index 14bf07a..2d6bf56 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,14 +1,14 @@ # AGENTS.md -Development guide for gitclaw agents and contributors. +Development guide for gitclaw contributors and agents. ## Architecture -- **Nested `src/` structure** — modules are organized under `src/core/`, `src/network/`, `src/cli/`, and `src/output/` -- **Two binaries, one source** — `gitclaw` and `gcw` both compile from `src/main.rs` -- **`src/lib.rs`** re-exports all modules publicly; integration tests consume the crate as a library -- **Integration tests in `tests/`** — one file per module, flat structure, no subdirectories -- **No in-module unit tests** — all tests live in `tests/` +- Nested `src/` structure: `core/`, `network/`, `cli/`, `output/` +- Two binaries, one source: `gitclaw` and `gcw` both compile from `src/main.rs` +- `src/lib.rs` re-exports all modules publicly; integration tests consume the crate as a library +- Integration tests in `tests/` (flat, no subdirectories, one file per module) +- Unit tests can stay in source files with `#[cfg(test)]`, integration tests go in `tests/` ## Source Modules @@ -28,60 +28,25 @@ Development guide for gitclaw agents and contributors. | `network/github.rs` | `GithubClient`, `Release`, `Asset`, `Platform`, `GithubError`, `parse_package`, `find_matching_asset` | | `network/platform.rs` | `Arch`, `PlatformError`, `detect_arch`, `current_platform`, `score_asset`, `find_best_asset` | -## Test Structure - -Integration tests live in `tests/` (flat, no subdirectories): - -``` -tests/ - checksum.rs - config.rs - extract.rs - github.rs - platform.rs - registry.rs - util.rs -``` - -Each file covers the corresponding module's public API. Tests that validate error paths are kept in the same file as the feature they test. - -## Workflow - -1. Pull `main` before starting -2. Branch prefix: `fix/`, `feat/`, `docs/`, `chore/` -3. Commit format: `type: description` (lowercase, imperative) -4. Verify locally before pushing: - ```bash - cargo fmt -- --check - cargo clippy -- -D warnings - cargo test - ``` -5. Open PR → squash merge into `main` - -## Code Style - -- No comments or docstrings anywhere in `.rs` files — code should be self-explanatory -- Use `?` for error propagation; no `unwrap()` in production code -- Opening brace on same line -- Blank line after multi-line blocks -- `#[serde(default)]` on any new optional struct fields for backward compatibility -- New `InstalledPackage` fields must use `#[serde(default)]` to stay compatible with existing registry TOML -- Imports sorted alphabetically within groups (stdlib / external / crate-internal), blank line between groups; run `cargo fmt` before committing -- All tests go in `tests/` — no `#[cfg(test)]` blocks in source files - ## Output Conventions -- Success messages: `[EXEC]` prefix, bold green — via `output::print_success` -- Info messages: `[INFO]` prefix, cyan — via `output::print_info` -- Warning messages: `[WARN]` prefix, bold yellow — via `output::print_warn` -- Error messages: `[ERR]` prefix, bold red, stderr — via `output::print_error` +- Success: `[EXEC]` prefix, bold green, via `output::print_success` +- Info: `[INFO]` prefix, cyan, via `output::print_info` +- Warning: `[WARN]` prefix, bold yellow, via `output::print_warn` +- Error: `[ERR]` prefix, bold red, stderr, via `output::print_error` - Key-value pairs: via `output::print_kv` - No horizontal separator lines - `NO_COLOR` env var disables all color output -## CI Flow +## Code Style -Verify → Test → Build +- No comments or docstrings anywhere in `.rs` files +- Use `?` for error propagation, no `unwrap()` in production code +- Opening brace on same line +- Blank line after multi-line blocks +- `#[serde(default)]` on any new optional struct fields for backward compatibility +- Imports sorted alphabetically within groups (stdlib / external / crate-internal), blank line between groups +- Integration tests go in `tests/`, unit tests can stay in source files ## Spec-Driven Development @@ -90,34 +55,15 @@ Verify → Test → Build 3. Features: full spec with acceptance criteria 4. Review spec with user before implementation 5. Checkpoints tied to deliverables, not percentages -6. Specs are temporary planning artifacts — delete after merge +6. Specs are temporary planning artifacts, delete after merge 7. Post-mortem lessons go to AGENTS.md, not the spec -## PR Discipline - -- Always branch: `feat/`, `fix/`, `docs/`, `chore/` -- Never push to main directly -- Squash merge after review -- Include tests and documentation updates - -## Definition of Done +## CI Flow -- [ ] Code complete -- [ ] `cargo test` passes -- [ ] `cargo clippy -- -D warnings` clean -- [ ] `cargo fmt --check` clean -- [ ] Run all three locally before pushing -- [ ] Documentation updated (CHANGELOG, README if needed) -- [ ] Manual verification done -- [ ] PR opened and reviewed +Verify, Test, Build ## Post-Mortems -After rework or significant issues: -- What went wrong -- Root cause -- Prevention -- Add to AGENTS.md so it persists - -*Last updated: 2026-04-23* +After rework or significant issues, document: what went wrong, root cause, prevention. Add to this file so it persists. +*Last updated: 2026-04-24* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f0dbca7..0bab334 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,101 +11,74 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Install channel persisted in registry: `--channel` stored per package -- `gitclaw update` respects stored channel when checking for newer releases +- `update` respects stored channel when checking for newer releases - Optional `channel` field on `InstalledPackage` (backward compatible) - New tests in `tests/channel_persist.rs` ## [0.6.0] - 2026-04-23 ### Added -- Release channels: `gitclaw install user/repo --channel nightly|beta|stable` -- `gitclaw search user/repo --channel ` filters releases by channel +- Release channels: `install --channel nightly|beta|stable` +- `search --channel ` filters releases by channel - Channel pattern overrides in `.gitclaw.toml` under `[channels]` -- `gitclaw export` outputs installed packages as TOML to stdout -- `gitclaw export -o deps.toml` writes to file -- `gitclaw import deps.toml` installs all packages from a TOML file +- `export` outputs installed packages as TOML to stdout +- `export -o deps.toml` writes to file +- `import deps.toml` installs all packages from a TOML file - Import skips already-installed packages unless `--force` is set - Export output is deterministic: sorted by owner then repo -- New modules: `src/core/channel.rs`, `src/core/export.rs` ## [0.5.0] - 2026-04-23 ### Added - Asset caching: downloaded archives cached to `~/.gitclaw/cache/`, reused on subsequent installs -- `gitclaw cache clean` — remove all cached archives -- `gitclaw cache size` — show total cache size on disk -- `gitclaw list --outdated` — compare installed versions against latest GitHub releases -- Local installs: `gitclaw install --local user/repo` installs to `./.gitclaw/` -- `gitclaw uninstall --local` — uninstall from local project directory -- `sha2` crate dependency for cache integrity verification +- `cache clean` and `cache size` commands +- `list --outdated` compares installed versions against latest GitHub releases +- Local installs: `install --local user/repo` installs to `./.gitclaw/` +- `uninstall --local` for local project directory ## [0.4.0] - 2026-04-23 ### Added -- Semver range support for install: `gitclaw install user/repo "^1.2.3"` -- Lockfile: `gitclaw lock` generates `gitclaw.lock` from installed packages -- Locked install: `gitclaw install --locked` reproduces exact versions from lockfile -- Package aliases: `gitclaw alias add rg BurntSushi/ripgrep` then `gitclaw install rg` -- `gitclaw alias list` and `gitclaw alias remove` commands -- `semver` crate dependency for version constraint parsing +- Semver range support: `install user/repo "^1.2.3"` +- Lockfile: `lock` generates `gitclaw.lock`, `install --locked` reproduces exact versions +- Package aliases: `alias add rg BurntSushi/ripgrep` then `install rg` +- `alias list` and `alias remove` commands ## [0.3.2] - 2026-04-23 ### Added -- `.deb` archive extraction support with ar format parsing -- `zstd` decompression support for `.tar.zst` archives -- Support for both GNU (10-byte) and BSD (8-byte) ar header size fields - -### Changed -- `identifier` field on `InstalledPackage` — set to the repo name at install time -- `uninstall` now accepts short name (repo or identifier) in addition to `owner/repo` -- `list` shows an `Identifier` column (cyan) in both normal and verbose modes -- 74 new integration tests across `tests/checksum.rs`, `tests/config.rs`, `tests/extract.rs`, `tests/github.rs`, `tests/platform.rs`, `tests/registry.rs` +- `.deb` archive extraction with ar format parsing +- `zstd` decompression for `.tar.zst` archives +- GNU and BSD ar header size field support - `gcw` short alias binary -- AGENTS.md and README.md simplified to essential content - -### Fixed -- `gcw list` crash when registry TOML was written before `identifier` field existed — `#[serde(default)]` applied -- Platform asset matching now correctly selects platform-specific assets -- Added Rust target triple aliases for ripgrep and similar Rust projects -- Symlinks in bin/ now use absolute paths -- Success prefix changed from `[OK]` to `[EXEC]` (bold green) -- Info prefix is now cyan -- Removed all horizontal separator lines from output - -### Removed -- `tests/unit/` folder dissolved — all integration tests now live directly under `tests/` -- `assert_cmd` moved to `[dev-dependencies]` -- Unused dependencies: `base64`, `base64ct`, `indexmap`, `url`, `time` +- 74 new integration tests -## [0.3.1] - 2026-04-22 +### Changed +- `identifier` field set to repo name at install time +- `uninstall` accepts short name (repo or identifier) in addition to `owner/repo` +- `list` shows an `Identifier` column +- `#[serde(default)]` applied to `identifier` field for backward compatibility ### Fixed - Platform asset matching now correctly selects platform-specific assets -- Added Rust target triple aliases for ripgrep and similar Rust projects -- Symlinks in bin/ now use absolute paths +- Rust target triple aliases added for ripgrep and similar projects +- Symlinks in `bin/` now use absolute paths ## [0.3.0] - 2026-04-21 ### Added -- Self-update command (`gitclaw self-update`, `gitclaw self-update --check`) +- Self-update command (`self-update`, `self-update --check`) - Checksum verification for downloaded assets (`--verify` flag) -- Parallel install support (`gitclaw install pkg1 pkg2 pkg3`) - -### Changed -- Install command now accepts multiple package arguments +- Parallel install support (`install pkg1 pkg2 pkg3`) ## [0.2.0] - 2026-04-21 ### Added -- Configuration file support with multiple config sources (env, project-local, XDG, legacy) +- Configuration file support with multiple config sources - `--dry-run` flag for install command -- `completions` command for shell completions (bash, zsh, fish, powershell, elvish) +- `completions` command for shell completions - Config options: `install_dir`, `show_progress`, `prefer_strip`, `verify_checksums`, `color`, `quiet`, `verbose` -### Changed -- Config values are now wired throughout the codebase - ## [0.1.0] - 2026-04-21 ### Added @@ -114,7 +87,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Archive support: tar.gz, tar.bz2, tar.xz, zip - Automatic architecture detection (Linux x86_64, aarch64) - Package registry for tracking installed packages -- List, update, and uninstall commands -- Search command for browsing releases +- List, update, uninstall, and search commands - Progress bars for downloads -- GitHub Actions CI/CD +- GitHub Actions CI/CD \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e3c5837..748598c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to gitclaw -## Development Setup +## Setup ```bash git clone https://github.com/clawdeeo/gitclaw.git @@ -12,15 +12,15 @@ cargo test ## Code Style - No comments or docstrings in `.rs` files -- Use `?` for error propagation; no `unwrap()` in production code +- Use `?` for error propagation, no `unwrap()` in production code - Run `cargo fmt` before committing - All clippy warnings must be resolved: `cargo clippy -- -D warnings` +- New `InstalledPackage` fields must use `#[serde(default)]` for registry compatibility ## Testing -- New features require integration tests in `tests/.rs` -- All tests go in `tests/` — no `#[cfg(test)]` blocks in source files -- New `InstalledPackage` fields must use `#[serde(default)]` for registry compatibility +- Integration tests go in `tests/.rs` +- Unit tests can stay in source files with `#[cfg(test)]` modules ## Submitting Changes @@ -31,9 +31,9 @@ cargo test cargo clippy -- -D warnings cargo test ``` -3. Open a PR — squash merge into `main` +3. Open a PR, squash merge into `main` -## Commit Message Convention +## Commit Messages ``` feat: add short description @@ -42,4 +42,4 @@ docs: update readme chore: bump dependency ``` -Lowercase, imperative, no period at end. +Lowercase, imperative, no period. \ No newline at end of file diff --git a/README.md b/README.md index e9b608c..7649b95 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # gitclaw -[![Main](https://github.com/clawdeeo/gitclaw/actions/workflows/main.yml/badge.svg)](https://github.com/clawdeeo/gitclaw/actions/workflows/main.yml) +[![CI](https://github.com/clawdeeo/gitclaw/actions/workflows/main.yml/badge.svg)](https://github.com/clawdeeo/gitclaw/actions/workflows/main.yml) -Install software from GitHub releases. -Also available as `gcw` — a shorter alias for the same binary. +Install software from GitHub releases. -## Installation +Also available as `gcw`. + +## Install ```bash cargo install --path . @@ -15,35 +16,45 @@ cargo install --path . ```bash gcw install sharkdp/bat - -gcw install BurntSushi/ripgrep "^14" -gcw lock -gcw install --locked -gcw alias add rg BurntSushi/ripgrep -gcw install rg gcw list -gcw list --outdated -gcw update sharkdp/bat -gcw uninstall bat - -gcw cache size -gcw cache clean - -gcw install --local sharkdp/bat # project-local install -gcw uninstall --local bat - -gcw install BurntSushi/ripgrep --channel nightly -gcw search sharkdp/fd --channel beta - -gcw export -o deps.toml -gcw import deps.toml ``` +See the [full command reference](#commands) below. + +## Commands + +| Command | Description | +|---------|-------------| +| `install ` | Install a package from GitHub releases | +| `install "^14"` | Install with a semver range | +| `install --locked` | Install exact versions from the lockfile | +| `install --local ` | Install to the project-local `.gitclaw/` directory | +| `install --channel nightly ` | Install from a specific release channel | +| `list` | List installed packages | +| `list --outdated` | Show packages with newer versions available | +| `list --verbose` | Show detailed package information | +| `update [package]` | Update a package (or all if none specified) | +| `uninstall ` | Uninstall a package | +| `search ` | Browse available releases | +| `lock` | Generate a lockfile from installed packages | +| `alias add ` | Create a short name for a package | +| `alias remove ` | Remove an alias | +| `alias list` | List all aliases | +| `cache size` | Show total cache size on disk | +| `cache clean` | Remove all cached archives | +| `export [-o file]` | Export installed packages as TOML | +| `import ` | Install packages from a TOML file | +| `self-update` | Update gitclaw to the latest version | +| `self-update --check` | Check for updates without installing | +| `completions ` | Generate shell completions | +| `platform` | Show platform information | +| `run [args...]` | Run an installed package | + ## Configuration Config files (TOML) are merged in order of precedence: -1. `$GITCLAW_CONFIG` env var +1. `$GITCLAW_CONFIG` environment variable 2. `./.gitclaw.toml` 3. `~/.config/gitclaw/config.toml` 4. `~/.gitclaw.toml` @@ -63,19 +74,17 @@ verbose = false ## How It Works -1. Query GitHub API for release metadata -2. Match asset to current OS/architecture -3. Download with progress bar -4. Extract — supports tar.gz, zip, tar.bz2, tar.xz, tar.zst, .deb, and plain binaries -5. Install binary to `~/.gitclaw/bin/` +1. Query the GitHub API for release metadata +2. Match the asset to the current OS and architecture +3. Download with a progress bar +4. Extract the archive (tar.gz, zip, tar.bz2, tar.xz, tar.zst, .deb, or plain binary) +5. Install the binary to `~/.gitclaw/bin/` ## Supported Platforms | OS | x86_64 | aarch64 | |----|--------|---------| | Linux | yes | yes | -| macOS | no | no | -| Windows | no | no | ## Development @@ -83,11 +92,10 @@ verbose = false cargo fmt -- --check cargo clippy -- -D warnings cargo test -cargo run -- install owner/repo ``` -See [AGENTS.md](AGENTS.md) for contribution guidelines. +See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. ## License -MIT License — Copyright (c) 2026 Francesco Sardone (Airscript) +MIT -- Copyright (c) 2026 Francesco Sardone (Airscript)