# Contributing

Contributions are welcome.

## Cache invalidation between builds

If you notice rebuilds happening when switching between `cargo clippy`, `cargo test`, and `cargo run`, it's likely due to environment variable changes (especially `CC`, `CXX`, etc.).

The `.envrc` file unsets compiler-related variables that can invalidate cargo's fingerprint cache. Make sure to reload your direnv environment:

```bash
direnv allow
```

If that does not work, have a look using this environment variable:

```bash
CARGO_LOG=cargo::core::compiler::fingerprint=info cargo build
```

## Adding new lints

The first thing you might want to do for a new rule is investigate how Nu parses the fragment. Nu has a built-in command that allows you to interactively explore

```bash
ast --json benches/fixtures/small_file.nu | get block | from json | explore
```

If you are using Bash (or Claude is calling Bash), call the Nu interpreter from a Bash shell to show a JSON representation. This JSON representation is easier to read:

```bash
nu -c 'ast --json benches/fixtures/small_file.nu | get block'
```

Please follow a somewhat predictable test file structure. Currently the convention is to have three different test files for each new rule:

- `detect_bad.rs`: for the `assert_detects` assertions
- `ignore_good.rs`: for the `assert_ignores` assertions
- `generated_fix.rs`: for assertions about the contents of the replacement text or help text (optional if it is too hard to provide fixes, but recommended)

## Debugging

Use `lldb` extension to step through code.

You should call the free function `instrument()` inside, at the beginning of a test to show simple debug output generated by the macros of the `log` crate in the library code.

Then run the tests with the RUST_LOG environment variable:

```bash
RUST_LOG=debug cargo test test_detect_unnecessary_variable_simple -- --nocapture
```

(It would be possible to use the [test-log](https://crates.io/crates/test-log) crate but I prefered a custom formatter displaying file links.)

## Testing

Debugging is primarily done with the tests.

```bash
cargo test
```

Tests follow a pattern where each rule has 'detect', 'fix' and 'ignore' tests.

## Linting

Please run linter and formatter before submitting PRs. Many optional and restrictive rules of Clippy have been turned on.

This will attempt to auto-fix violations in the Rust code.

```bash
cargo clippy --fix --allow-dirty --all-targets
```

Check if everything was fixed:

```bash
cargo clippy --all-targets
```

```bash
cargo +nightly fmt
```

## Benchmarks

Quick benchmark for performance testing:

```bash
cargo bench --bench lint_performance lint_small_file
```

Comparative benchmarks

```bash
git checkout main
cargo bench --bench lint_performance lint_with_violations -- --save-baseline main
git checkout branch
cargo bench --bench lint_performance lint_with_violations -- --baseline main
```
