Metadata-Version: 2.4
Name: misch
Version: 0.1.0
Summary: Config-driven MISRA C:2023 static-analysis harness for arbitrary C projects (cppcheck-backed, bring-your-own rule texts).
Project-URL: Repository, https://github.com/aajll/misch
Project-URL: Changelog, https://github.com/aajll/misch/blob/master/CHANGELOG.md
Project-URL: Issues, https://github.com/aajll/misch/issues
Author: Aaron James Long
License-Expression: MIT
License-File: LICENSE
Keywords: c,cppcheck,embedded,misra,safety,static-analysis
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: C
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.11
Requires-Dist: rich-argparse>=1.5
Requires-Dist: rich>=13.0
Description-Content-Type: text/markdown

# misch

[![CI](https://github.com/aajll/misch/actions/workflows/ci.yml/badge.svg)](https://github.com/aajll/misch/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/misch)](https://pypi.org/project/misch/)
[![Python](https://img.shields.io/pypi/pyversions/misch)](https://pypi.org/project/misch/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

**Point it at any C project and ratchet it toward MISRA C:2023.** `misch` (MISra-CHeck) is a config-driven static-analysis harness: it wraps [cppcheck](https://cppcheck.sourceforge.io/) and its `misra.py` addon, drives them off a real `compile_commands.json`, and turns per-project difference into a small `misra.toml` instead of a forked shell script.

- **Bring-your-own rule texts:** ships no copyrighted MISRA material (see [`docs/rule-texts.md`](docs/rule-texts.md)).
- **Baseline / ratchet:** adopt MISRA on an existing codebase without a day-one wall of findings; fail CI only on _new_ ones.
- **Deviation records:** harvests every `cppcheck-suppress`, enforces a justification, and emits an audit-ready record.
- **No silent scope creep:** every file is consciously analysed or excluded, or the run fails.

> `misch` is a **guidance + ratchet** tool, not a compliance-certification tool: cppcheck's addon covers a subset of MISRA C:2023. The engine sits behind an interface so a certified analyser can slot in later. See [`docs/DESIGN.md`](docs/DESIGN.md).

## Install

Requires Python ≥ 3.11 and `cppcheck` (with its bundled `misra.py` addon) on `PATH`. Tested with cppcheck 2.21; any recent release with the `misra.py` addon should work.

```sh
uv tool install misch        # or: pipx install misch / pip install misch
```

From a checkout: `uv tool install .` (or `uv sync && uv run misch ...`).

## Quick start

```sh
cd /path/to/your/c-project
misch init                 # write a commented misra.toml (flags pre-fill it)
misch run                  # analyse; categorised report; non-zero exit on findings
misch baseline             # accept current findings as the baseline
misch run --baseline       # from now on, fail only on NEW findings
misch deviations           # audit every suppression + its justification
```

Bring your own rule texts (optional, for headlines + Mandatory/Required/Advisory):

```sh
export MISRA_RULE_TEXTS=/path/to/misra_c_2023_headlines_for_cppcheck.txt
```

A run against a project with findings looks like this (headline text comes from your own rule-texts file):

```text
──────────────────────────────── MISRA analysis ────────────────────────────────
scope: 1 analysed  0 excluded  files with findings: 1

Findings by rule
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Rule             ┃ Category ┃ Count ┃ Headline                               ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ misra-c2012-8.4  │ required │     2 │ Headline from your licensed MISRA copy │
│ misra-c2012-17.7 │ required │     1 │ Headline from your licensed MISRA copy │
│ misra-c2012-21.6 │ required │     1 │ Headline from your licensed MISRA copy │
│ misra-c2012-15.5 │ advisory │     1 │ Headline from your licensed MISRA copy │
│ misra-c2012-8.7  │ advisory │     1 │ Headline from your licensed MISRA copy │
└──────────────────┴──────────┴───────┴────────────────────────────────────────┘

Run with -v/--verbose for the per-location listing.

6 MISRA finding(s): 4 required  2 advisory
```

## Commands

| Command            | Purpose                                                                                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `misch init`       | Generate a commented `misra.toml`; flags (`--db`, `--scope`, `--exclude`, `--platform`, `--rule-texts`, …) pre-fill each section.                               |
| `misch run`        | Analyse. Rule table + summary (add `-v` for per-location detail, or `--format json`/`--format sarif`). Exit 1 on findings; `--baseline` fails only on new ones. |
| `misch baseline`   | Snapshot the current findings as the accepted baseline.                                                                                                         |
| `misch deviations` | Harvest `cppcheck-suppress*`, enforce justifications, validate rule ids, emit a Markdown deviation record (`--format md`).                                      |

Exit codes are CI-friendly and format-independent: `0` clean (or no new findings under `--baseline`), `1` findings (or unjustified/unknown deviations), `2` config, compile-DB, scope, or engine error.

## Configuration

`misch init` writes a documented `misra.toml`; the essentials:

```toml
[project]
scope   = ["src/", "include/"]                 # analysed
exclude = ["tests/", "subprojects/"]           # explicitly out of scope

[db]
source = "meson"                               # meson | cmake | existing
# Plain-Make projects: generate a DB (e.g. `bear -- make`) and use "existing".

[platform]
preset = "unix64"                              # cppcheck built-in, or [platform].xml

[rules]
texts = "${MISRA_RULE_TEXTS}"                  # bring-your-own; optional
```

## How it works

`compile_commands.json` is the universal seam: every build-system and toolchain concern collapses into "produce a normalised compile DB". A single internal Finding model backs every output (terminal, JSON, baseline diff, deviation record), so they can never disagree. Full architecture and rationale in [`docs/DESIGN.md`](docs/DESIGN.md).

## Documentation

- [`docs/DESIGN.md`](docs/DESIGN.md): architecture, the scope and deviation strategy.
- [`docs/rule-texts.md`](docs/rule-texts.md): bringing your own MISRA headlines.
- [`CONTRIBUTING.md`](CONTRIBUTING.md): dev setup, tests, adding engines/normalisers.
- [`CHANGELOG.md`](CHANGELOG.md): release notes.

## License

MIT (see [`LICENSE`](LICENSE)). `misch` contains and ships no MISRA material; rule texts are bring-your-own from your licensed copy.
