unsafe-budget 0.4.0

keeps the unsafety demons out. an unsafe code budget gate for CI pipelines.
Documentation
# usage guide

## commands

### scan

run analyzers and print results:

```bash
unsafe-budget scan [OPTIONS]
```

options:

| flag | description |
|------|-------------|
| `--format <text\|json\|sarif>` | output format (default: text) |
| `--analyzer <id>` | analyzer to use (default: auto) |
| `--workspace-only` | skip dependencies |
| `--include-deps` | include dependencies (default) |
| `--no-deps` | exclude dependencies |
| `--details` | show line-level occurrences |
| `--features <f1,f2>` | cargo features to enable |
| `--all-features` | enable all features |
| `--no-default-features` | disable default features |
| `--all-targets` | build all targets |
| `--manifest-path <path>` | path to Cargo.toml, go.mod, or .sarif file |
| `--config <path>` | path to config file |

### check

compare against baseline/caps and exit non-zero on violation:

```bash
unsafe-budget check [OPTIONS]
```

same options as `scan`. exit codes:

- 0: check passed
- 1: runtime error
- 2: budget violation

when warnings are configured, near-budget units are reported as warnings without
changing the exit code.

### update

write/update baseline from current scan:

```bash
unsafe-budget update [OPTIONS]
```

creates or overwrites `unsafe-budget.lock`.

### plugins

list available analyzers:

```bash
unsafe-budget plugins [--format json]
```

## configuration file

`unsafe-budget.toml`:

```toml
# mode: "ratchet" (default) or "caps"
mode = "ratchet"

# include dependencies in scan
include_deps = true

# only scan workspace crates
workspace_only = false

# units to ignore in budget checks
ignore_units = ["test_helpers", "benches"]

# caps mode configuration
[caps]
default = 100  # default cap for dependencies

[caps.workspace]
my_crate = 10
other_crate = 5

[caps.deps]
libc = 500  # override default for specific dep

# warning configuration (optional)
[warnings]
threshold = 0.8  # warn when usage reaches 80% of budget
```

## baseline file

`unsafe-budget.lock` (auto-generated):

```toml
# Auto-generated by unsafe-budget. Do not edit manually.

tool_version = "0.3.0"
analyzer_id = "rustc_unsafe_lint"

[scope]
workspace_only = false
include_deps = true

[totals]
workspace_unsafe = 10
deps_unsafe = 42

[[units]]
name = "my_crate"
kind = "workspace"
unsafe_count = 10
```

## examples

### ci pipeline

```yaml
- name: check unsafe budget
  run: unsafe-budget check
```

### json processing

```bash
unsafe-budget scan --format json | jq '.units[] | select(.unsafe_count > 10)'
```

### specific analyzer

```bash
unsafe-budget scan --analyzer cargo_geiger
unsafe-budget scan --analyzer go_geiger
unsafe-budget scan --analyzer sarif --manifest-path results.sarif
```

### sarif output

```bash
# emit sarif from a scan (use --details for line-level results)
unsafe-budget scan --format sarif --details

# emit sarif from a check (violations become error-level results)
unsafe-budget check --format sarif --details

# ingest sarif, apply budget, emit sarif
unsafe-budget check --analyzer sarif --manifest-path results.sarif --format sarif --details
```

### go project

```bash
# auto-detected from go.mod
cd my-go-project
unsafe-budget scan

# explicit
unsafe-budget scan --analyzer go_geiger --details
```