Ctrl K
ComunidadGuías…

CONTRIBUTING.md

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

Archivo original ↗Preguntar a KiBot
# Contributing to Mole

## Setup

```bash
# Install development tools
brew install shfmt shellcheck bats-core golangci-lint

# Install goimports for better Go formatting
go install golang.org/x/tools/cmd/goimports@latest

# Install pre-commit hook (runs format/lint checks on every commit)
git config core.hooksPath .githooks
```

## Development

Run quality checks before committing (auto-formats code):

```bash
./scripts/check.sh
```

Run tests:

```bash
./scripts/test.sh
```

## Code Style

### Basic Rules

- Bash 3.2+ compatible (macOS default)
- 4 spaces indent
- Use `set -euo pipefail` in all scripts
- Quote all variables: `"$variable"`
- Use `[[ ]]` not `[ ]` for tests
- Use `local` for function variables, `readonly` for constants
- Function names: `snake_case`
- BSD commands not GNU (e.g., `stat -f%z` not `stat --format`)

Config: `.editorconfig` and `.shellcheckrc`

### File Operations

**Always use safe wrappers, never `rm -rf` directly:**

```bash
# Single file/directory
safe_remove "/path/to/file"

# Purge files older than 7 days
safe_find_delete "$dir" "*.log" 7 "f"

# With sudo
safe_sudo_remove "/Library/Caches/com.example"
```

See `lib/core/file_ops.sh` for all safe functions.

### Pipefail Safety

All commands that might fail must be handled:

```bash
# Correct: handle failure
find /nonexistent -name "*.cache" 2>/dev/null || true

# Correct: check array before use
if [[ ${#array[@]} -gt 0 ]]; then
    for item in "${array[@]}"; do
        process "$item"
    done
fi

# Correct: arithmetic operations
((count++)) || true
```

### Error Handling

```bash
# Network requests with timeout
result=$(curl -fsSL --connect-timeout 2 --max-time 3 "$url" 2>/dev/null || echo "")

# Command existence check
if ! command -v brew >/dev/null 2>&1; then
    log_warning "Homebrew not installed"
    return 0
fi
```

### UI and Logging

```bash
# Logging
log_info "Starting cleanup"
log_success "Cache cleaned"
log_warning "Some files skipped"
log_error "Operation failed"

# Spinners
with_spinner "Cleaning cache" rm -rf "$cache_dir"

# Or inline
start_inline_spinner "Processing..."
# ... work ...
stop_inline_spinner "Complete"
```

### Debug Mode

Enable debug output with `--debug`:

```bash
mo --debug clean
./bin/clean.sh --debug
```

Modules check the internal `MO_DEBUG` variable:

```bash
if [[ "${MO_DEBUG:-0}" == "1" ]]; then
    echo "[MODULE] Debug message" >&2
fi
```

Format: `[MODULE_NAME] message` output to stderr.

## Requirements

- macOS 12 or newer, works on Intel and Apple Silicon
- Default macOS Bash 3.2+; administrator privileges are required for system-level cleanup tasks
- Command Line Tools (`xcode-select --install`) for curl, tar, and standard utilities
- Go 1.26+ is required to build the `mo status` or `mo analyze` TUI binaries locally.

## Go Components

`mo status` and `mo analyze` use Go with Bubble Tea for interactive dashboards.

**Code organization:**

- Each module is split into focused files by responsibility.
- `cmd/analyze/` owns disk traversal, caching, deletion, navigation, and rendering.
- `cmd/status/` keeps collection, automation output, preferences, and rendering separate.

**Development workflow:**

- Format code with `./scripts/check.sh --format`
- Run `go vet ./cmd/...` to check for issues
- Build with `go build ./...` to verify all packages compile

**Building Go Binaries:**

For local development:

```bash
# Build binaries for current architecture
make build

# Or run directly without building
go run ./cmd/analyze
go run ./cmd/status
```

For releases, GitHub Actions builds architecture-specific binaries automatically.

**Guidelines:**

- Keep files focused on a single responsibility
- Use named constants instead of magic numbers
- Use context for timeout control on external commands
- Add comments explaining the **why** behind non-obvious logic, not just what the code does

## Pull Requests

1. Fork and create branch from `main`
2. Make changes
3. Run checks: `./scripts/check.sh`
4. Commit and push
5. Open PR targeting `main`

CI will verify formatting, linting, and tests.

## Licensing

Mole is GPL-3.0, and that is the licence your contribution carries. There is no CLA. You keep your copyright and I get only what the licence gives me, which means I cannot put your code under a different one.

I also sell a closed-source Mac app at [mole.fit](https://mole.fit). It is a separate codebase rather than a build of this one, and neither program calls the other. What the two share is what anyone can observe about macOS: where a cache lives, what an app leaves behind. If you would rather not contribute alongside a paid product, that is a fair call, and I would rather you made it now than later.