Ctrl K
ComunidadGuías…

CONTRIBUTING.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# 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/unarr.git
   cd unarr
   ```
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 unarr
   ```
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/Unarr-app/unarr-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 test-e2e   # Run the build-tagged end-to-end suites (test/e2e)
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

```
unarr/
├── 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
```

### End-to-end tests

The suites under `test/e2e/` drive the log ring, the config round-trip and the
`unarr logs` CLI over real files and a real process. They are behind
`//go:build e2e`, so **`make test` and plain `go test ./...` do not run them** —
`go test ./test/...` reports "matched no packages". The tag is the only way in:

```bash
make test-e2e                                   # what CI runs
go test -tags e2e -race -count=1 ./test/e2e/... # the same thing, spelled out
go test -tags e2e -run TestRotation ./test/e2e/...

# Keep the workspaces (and their rotated logs) around to inspect afterwards:
UNARR_E2E_DIR=/tmp/unarr-e2e go test -tags e2e ./test/e2e/...
```

They run as a dedicated **E2E** job in CI, not as part of `make test` and not in
the pre-commit hook: the suite compiles the CLI binary, so it takes ~4s with a
warm build cache but ~50s cold, and a hook that can stall for a minute is a hook
people turn off. Run `make test-e2e` yourself when you touch `internal/logging`,
the daemon log wiring, or the `unarr logs` command.

Windows-specific daemon behaviour is **not** covered here — that needs the real
VM harness in [`test/windows/`](test/windows/README.md).

## 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/Unarr-app/unarr-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!