feat: initial commit — unarr CLI
Search, inspect, stream, and download torrents from the terminal. Replaces the entire *arr stack with a single binary.
This commit is contained in:
commit
29cf0a0126
85 changed files with 10178 additions and 0 deletions
200
CONTRIBUTING.md
Normal file
200
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
# Contributing to unarr
|
||||
|
||||
Thank you for your interest in contributing! This guide will help you get started.
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. **Fork** the repository on GitHub
|
||||
2. **Clone** your fork locally:
|
||||
```bash
|
||||
git clone https://github.com/YOUR-USERNAME/torrentclaw-cli.git
|
||||
cd torrentclaw-cli
|
||||
```
|
||||
3. **Set up the Go client** (local dependency):
|
||||
```bash
|
||||
# Clone the go-client next to the CLI
|
||||
cd ..
|
||||
git clone https://github.com/torrentclaw/go-client.git
|
||||
cd torrentclaw-cli
|
||||
```
|
||||
4. **Create a branch** for your change:
|
||||
```bash
|
||||
git checkout -b feature/my-feature
|
||||
```
|
||||
5. **Make your changes**, write tests, and ensure everything passes
|
||||
6. **Commit** with a clear message (see [Commit Messages](#commit-messages))
|
||||
7. **Push** to your fork and [open a Pull Request](https://github.com/torrentclaw/torrentclaw-cli/compare)
|
||||
|
||||
## Development Setup
|
||||
|
||||
You need **Go 1.22+** installed.
|
||||
|
||||
### Build and Run
|
||||
|
||||
```bash
|
||||
make build # Build the binary
|
||||
./unarr --help # Test it
|
||||
|
||||
# Or install to GOPATH/bin
|
||||
make install
|
||||
```
|
||||
|
||||
### Git Hooks (Lefthook)
|
||||
|
||||
This project uses [Lefthook](https://github.com/evilmartians/lefthook) to run pre-commit checks and validate commit messages automatically.
|
||||
|
||||
```bash
|
||||
# Install lefthook (pick one):
|
||||
brew install lefthook # macOS
|
||||
go install github.com/evilmartians/lefthook@latest # Go
|
||||
npm install -g lefthook # npm
|
||||
|
||||
# Activate hooks in your local clone:
|
||||
make install-hooks
|
||||
# or: lefthook install
|
||||
```
|
||||
|
||||
Once installed, every commit will automatically:
|
||||
- **pre-commit**: check `gofmt`, run `go vet`, build, and run `golangci-lint` (if installed)
|
||||
- **commit-msg**: validate the message follows [Conventional Commits](#commit-messages)
|
||||
|
||||
### Make Targets
|
||||
|
||||
```bash
|
||||
make build # Build the binary
|
||||
make test # Run tests
|
||||
make coverage # Run tests with coverage
|
||||
make lint # Run golangci-lint
|
||||
make fmt # Format code (gofmt -s -w)
|
||||
make check # Verify formatting (no write, CI-friendly)
|
||||
make vet # Run go vet
|
||||
make install # Install to GOPATH/bin
|
||||
make all # fmt + vet + lint + test + build
|
||||
make install-hooks # Install lefthook git hooks
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
torrentclaw-cli/
|
||||
├── cmd/unarr/ # Entry point
|
||||
│ └── main.go
|
||||
├── internal/
|
||||
│ ├── cmd/ # Cobra command definitions
|
||||
│ │ ├── root.go # Root command + global flags
|
||||
│ │ ├── search.go # Search command
|
||||
│ │ ├── inspect.go # Inspect (TrueSpec) command
|
||||
│ │ ├── watch.go # Watch (streaming + torrents)
|
||||
│ │ ├── popular.go # Popular/recent content
|
||||
│ │ ├── config.go # Interactive configuration
|
||||
│ │ ├── setup.go # First-time setup wizard
|
||||
│ │ ├── daemon.go # Daemon mode (start/stop)
|
||||
│ │ ├── download.go # One-shot download
|
||||
│ │ ├── stream.go # Stream to media player
|
||||
│ │ ├── doctor.go # Diagnostics
|
||||
│ │ ├── status.go # Daemon status
|
||||
│ │ └── stubs.go # Stub commands (future)
|
||||
│ ├── config/ # Configuration management
|
||||
│ │ ├── config.go # Config struct + TOML parsing
|
||||
│ │ └── paths.go # XDG-compliant paths
|
||||
│ ├── engine/ # Download engine
|
||||
│ │ ├── manager.go # Download orchestration
|
||||
│ │ ├── task.go # Task state machine
|
||||
│ │ ├── torrent.go # BitTorrent downloader
|
||||
│ │ ├── stream.go # Streaming engine
|
||||
│ │ ├── organize.go # File organization
|
||||
│ │ └── ... # Verify, resolve, notify, etc.
|
||||
│ ├── agent/ # API client + daemon
|
||||
│ │ ├── client.go # HTTP client
|
||||
│ │ └── daemon.go # Daemon lifecycle
|
||||
│ ├── ui/ # Output formatting
|
||||
│ │ ├── table.go # Table rendering
|
||||
│ │ └── format.go # Size, rating, time formatting
|
||||
│ └── parser/ # Torrent parsing
|
||||
│ └── torrent.go # Magnet URI, hash, name parsing
|
||||
├── go.mod
|
||||
├── Makefile
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Code Style
|
||||
|
||||
- Run `gofmt` on all code (or `make fmt`)
|
||||
- Run `golangci-lint` (or `make lint`)
|
||||
- Follow existing patterns in the codebase
|
||||
- Keep commands in separate files under `internal/cmd/`
|
||||
- Keep output formatting in `internal/ui/`
|
||||
|
||||
## Running Tests
|
||||
|
||||
```bash
|
||||
# All tests
|
||||
make test
|
||||
|
||||
# Specific test
|
||||
go test -run TestParse -v ./internal/parser/...
|
||||
|
||||
# With coverage report
|
||||
make coverage
|
||||
```
|
||||
|
||||
## Commit Messages
|
||||
|
||||
This project enforces [Conventional Commits](https://www.conventionalcommits.org/) via a git hook. Format:
|
||||
|
||||
```
|
||||
<type>[optional scope]: <description>
|
||||
```
|
||||
|
||||
Allowed types: `feat`, `fix`, `docs`, `test`, `chore`, `refactor`, `ci`, `style`, `perf`, `build`
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
feat: add search by genre
|
||||
feat(inspect): add HDR detection
|
||||
fix(search): handle empty results
|
||||
docs: update README
|
||||
test: add parser edge case tests
|
||||
chore: update CI matrix to Go 1.24
|
||||
```
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
- Keep PRs focused — one feature or fix per PR
|
||||
- Include tests for new functionality
|
||||
- Update documentation if the public API changes
|
||||
- Ensure all CI checks pass before requesting review
|
||||
- Link related issues in the PR description
|
||||
|
||||
## Adding a New Command
|
||||
|
||||
1. Create `internal/cmd/mycommand.go`
|
||||
2. Define a `newMyCommandCmd() *cobra.Command` function
|
||||
3. Add it to `rootCmd.AddCommand(...)` in `root.go`
|
||||
4. Add any UI rendering helpers to `internal/ui/table.go`
|
||||
|
||||
## Reporting Bugs
|
||||
|
||||
[Open an issue](https://github.com/torrentclaw/torrentclaw-cli/issues/new?labels=bug) with:
|
||||
|
||||
- **Description** — what went wrong
|
||||
- **Steps to reproduce** — minimal commands to trigger the bug
|
||||
- **Expected behavior** — what you expected to happen
|
||||
- **Actual behavior** — what actually happened
|
||||
- **Environment** — Go version, OS, CLI version (`unarr version`)
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project follows the [Contributor Covenant v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
|
||||
|
||||
In short:
|
||||
|
||||
- **Be respectful** — treat everyone with dignity regardless of background or experience level
|
||||
- **Be constructive** — focus on what's best for the project and community
|
||||
- **Be collaborative** — welcome newcomers, help others learn
|
||||
- **No harassment** — unacceptable behavior includes trolling, insults, and unwelcome attention
|
||||
|
||||
---
|
||||
|
||||
Thank you for helping make unarr better!
|
||||
Loading…
Add table
Add a link
Reference in a new issue