# Contribution guidelines
First off, thank you for considering contributing to config-disassembler.
If your contribution is not straightforward, please first discuss the change you
wish to make by creating a new issue before making the change.
## Reporting issues
Before reporting an issue on the
[issue tracker](https://github.com/mcarvin8/config-disassembler/issues),
please check that it has not already been reported by searching for some related
keywords.
## Pull requests
Try to do one pull request per change.
### Releasing
Releases and changelog generation are automated using release-plz.
To ensure your changes are properly categorized in the changelog, please follow
[conventional commit messages](https://www.conventionalcommits.org/en/v1.0.0/).
### CI/CD and code coverage
All pull requests run automated checks:
- The test suite runs with all features on Ubuntu, Windows, and macOS.
- Ubuntu also generates coverage using cargo-llvm-cov and uploads the report to
Codecov.
- Rustfmt checks formatting with `cargo fmt --all --check`.
- Clippy runs with `cargo clippy --all-targets --all-features --workspace -- -D warnings`.
- Documentation builds with warnings denied using `cargo doc`.
- A RustSec audit runs on pull requests, dependency changes, and a daily schedule.
- Mutation testing runs via `cargo-mutants` against the lines changed by the
pull request. If the diff only touches `#[cfg(test)] mod tests` blocks (a
common shape for PRs that close coverage gaps), the workflow falls back to
mutating every changed Rust file in full so the new tests get a chance to
kill the existing surviving mutants. A full-suite run is available on
demand via the `Mutation Testing` workflow's `workflow_dispatch` trigger.
Releases are automated after changes land on `main`:
- release-plz publishes crate releases and opens release PRs for version and
changelog updates.
- Published GitHub releases trigger binary artifact uploads for macOS, Linux,
and Windows targets.
You can optionally run this command locally to run tests and generate coverage:
```bash
cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info --ignore-filename-regex 'main\.rs'
```
## Developing
### Set up
This is no different than other Rust projects.
```shell
git clone https://github.com/mcarvin8/config-disassembler
cd config-disassembler
cargo test --all-features --workspace
```
## Testing
Run all tests:
```bash
cargo test --all-features --workspace
```
- **Unit tests** - In-module tests for format parsing, disassembly,
reassembly, XML builders, parsers, and transformers.
- **Integration tests** - Tests under `tests/` cover CLI behavior, fixture
round trips, cross-format conversions, TOML restrictions, and XML
disassemble/reassemble workflows.
## Git hooks
This repository uses cargo-husky to install a pre-commit hook from
`.cargo-husky/hooks/pre-commit`.
Before a commit is created, the hook:
- Runs `cargo fmt --all`.
- Re-stages any already-staged Rust files that were rewritten by rustfmt.
- Runs `cargo clippy --all-targets --all-features --workspace -- -D warnings`.
If formatting or Clippy fails, the commit is blocked. These checks intentionally
match the CI formatting and lint expectations.
### Useful Commands
- Build and run release version:
```shell
cargo build --release && cargo run --release
```
- Run Clippy:
```shell
cargo clippy --all-targets --all-features --workspace
```
- Run all tests:
```shell
cargo test --all-features --workspace
```
- Run all tests with code coverage (install cargo-llvm-cov first):
```shell
cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info --ignore-filename-regex 'main\.rs'
```
- Run mutation testing locally (install `cargo-mutants` first):
```shell
# Full run (long)
cargo mutants
# Scoped to a single file (fast)
cargo mutants -f src/xml/handlers/disassemble.rs
# Mutate only what your branch changed vs main (matches CI)
git diff "$(git merge-base HEAD origin/main)" HEAD -- src tests > mutation.diff
cargo mutants --in-diff mutation.diff
```
Configuration lives in `.cargo/mutants.toml`. The HTML/text report is written
to `mutants.out/` (gitignored).
The config excludes a few function families from mutation testing:
- `impl Debug for ...`, `impl From<...> for Error`, and `fn source`: pure
delegations / typically-equivalent mutants.
- `fn print_help`, `fn print_format_help`, `fn print_same_format_help`,
`fn print_cross_format_help`, `fn format_list`, `fn display_name`, and
`fn supported_format_list`: human-facing help / format-label strings
where the only way to "kill" a mutant is a snapshot test whose only job
is to fail when the help text is intentionally edited.
If you find yourself adding similar pure-text functions, extend
`exclude_re` in `.cargo/mutants.toml` rather than writing a snapshot
test purely to satisfy mutation testing.
- Check to see if there are code formatting issues
```shell
cargo fmt --all -- --check
```
- Format the code in the project
```shell
cargo fmt --all
```