# feature-manifest

[![Crates.io](https://img.shields.io/crates/v/feature-manifest.svg)](https://crates.io/crates/feature-manifest)
[![Docs.rs](https://docs.rs/feature-manifest/badge.svg)](https://docs.rs/feature-manifest)
[![CI](https://github.com/funwithcthulhu/feature-manifest/actions/workflows/ci.yml/badge.svg)](https://github.com/funwithcthulhu/feature-manifest/actions/workflows/ci.yml)
[![License](https://img.shields.io/crates/l/feature-manifest.svg)](LICENSE-MIT)

`feature-manifest` is a Rust crate plus Cargo subcommand for documenting, validating, and rendering Cargo feature flags.

It gives crate authors a structured layer on top of `[features]`, so feature intent can live in `Cargo.toml` while still powering docs, CI, editor tooling, workspace audits, and release automation.

## Why it exists

Cargo features are powerful, but feature intent is often trapped in a raw `[features]` table. `feature-manifest` helps maintainers:

- keep every feature documented in one place,
- fail CI when metadata drifts out of sync,
- scaffold missing metadata automatically,
- generate Markdown for docs and READMEs,
- emit stable JSON and SARIF for tooling,
- visualize feature relationships with Mermaid,
- work across whole Cargo workspaces.

## Installation

From crates.io:

```text
cargo install feature-manifest
```

This installs both `cargo-feature-manifest` and the short alias `cargo-fm`.

Recommended usage:

```text
cargo fm
```

The original long form still works:

```text
cargo feature-manifest
```

From source:

```text
git clone https://github.com/funwithcthulhu/feature-manifest.git
cd feature-manifest
cargo install --path .
```

## Commands

```text
cargo fm
cargo fm init --ci
cargo fm init --dry-run
cargo fm doctor --explain
cargo fm c --format json
cargo fm md -o FEATURES.md
cargo fm md --check -i README.md
cargo fm md -i README.md
cargo fm j
cargo fm g
cargo fm s --diff
cargo fm show <feature>
cargo fm lints
cargo fm lints --markdown
cargo fm schema metadata
cargo fm completions powershell
```

The default command is still `check`, so `cargo fm` and `cargo feature-manifest` are both valid shorthand.

Short aliases:

- `check` -> `c`, `chk`
- `markdown` -> `md`, `m`
- `json` -> `j`
- `graph` -> `g`, `viz`
- `sync` -> `s`
- `explain` -> `show`, `x`
- `list-lints` -> `lints`

## Quick Workflow

1. Add or change features in `Cargo.toml`.
2. Run `cargo fm init --ci` to scaffold metadata, README markers, and CI.
3. Fill in real descriptions, visibility, and status flags.
4. Run `cargo fm doctor` to confirm the project is wired up.
5. Run `cargo fm` locally and in CI.

## Workspace Support

Point the tool at a workspace root or a single crate:

```text
cargo fm -w c -m path/to/workspace
cargo fm -p my-crate show serde -m path/to/workspace
cargo fm md -m path/to/crate
```

When a workspace has multiple members, the default behavior is intentionally strict: you must choose `--workspace` or `--package <name>`.

## Markdown Output and Injection

Write a generated document directly:

```text
cargo fm md -o FEATURES.md
```

Inject generated Markdown into an existing README using markers:

```markdown
<!-- feature-manifest:start -->

# feature-manifest feature manifest

Default feature set: _none_

| Feature | Default | Visibility | Status | Category | Enables | Description |
| --- | --- | --- | --- | --- | --- | --- |
<!-- feature-manifest:end -->
```

Then run:

```text
cargo fm md -i README.md
```

Check whether generated docs are stale:

```text
cargo fm md --check -i README.md
```

Custom markers are supported with `--start-marker` and `--end-marker`.

## Validation Output Formats

`check` supports multiple output formats:

- `text`: default human-readable output
- `json`: machine-readable structured report
- `github`: GitHub Actions workflow commands
- `sarif`: SARIF 2.1.0 for code scanning pipelines

Example:

```text
cargo fm c -f sarif > feature-manifest.sarif
```

GitHub annotations include manifest line numbers when the relevant feature,
metadata entry, or group can be located.

## Lint Configuration

Feature-manifest lints can be configured in `Cargo.toml`:

```toml
[package.metadata.feature-manifest.lints]
missing-description = "deny"
small-group = "allow"
private-enabled-by-public = "warn"
```

For gradual adoption or strict CI defaults:

```toml
[package.metadata.feature-manifest]
preset = "adopt"
```

You can also override them per-run:

```text
cargo fm c -l missing-description=warn
cargo fm c --preset strict
```

For stricter project setup checks:

```text
cargo fm doctor --strict
cargo fm doctor --explain
```

See [docs/lints.md](docs/lints.md) for the generated lint reference.

## More Documentation

- [Metadata format](docs/metadata-format.md)
- [Lint reference](docs/lints.md)
- [JSON schema](docs/json-schema.md)
- [Generated CLI reference](docs/cli.md)
- [Getting started](docs/getting-started.md)
- [CI setup](docs/ci.md)
- [Adoption recipes](docs/adoption-recipes.md)
- [Before and after adoption](docs/before-after-adoption.md)
- [Architecture](docs/architecture.md)
- [Supply-chain trust](docs/supply-chain-trust.md)
- [Cookbook](docs/cookbook.md)
- [Compatibility and migration](docs/compatibility-and-migration.md)
- [Real-world patterns](docs/real-world-patterns.md)
- [Release process](docs/releasing.md)
- [1.0 roadmap](docs/roadmap-1.0.md)
- [Security policy](SECURITY.md)
- [Contributing guide](CONTRIBUTING.md)
- [Support](SUPPORT.md)

Example metadata snippets live in [examples](examples).

## Fixtures and Tests

The repo includes valid Cargo fixtures for both single-package and workspace flows:

- [`fixtures/basic/Cargo.toml`](fixtures/basic/Cargo.toml)
- [`fixtures/edge/Cargo.toml`](fixtures/edge/Cargo.toml)
- [`fixtures/messy/Cargo.toml`](fixtures/messy/Cargo.toml)
- [`fixtures/workspace/Cargo.toml`](fixtures/workspace/Cargo.toml)
- [`fixtures/compat`](fixtures/compat) for curated real-world Cargo layout patterns

The test suite includes:

- unit tests for parsing and validation,
- integration tests for CLI workflows,
- snapshot tests for Markdown, JSON, and Mermaid output,
- property tests for sync and generated documentation edge cases,
- generated-doc tests that keep `docs/cli.md` and JSON schemas honest.
- compatibility tests for workspace-style, TLS, runtime, small-crate, and no_std layouts.

Run everything with:

```text
cargo test --all-targets
```

## Publish Readiness

Before publishing:

```text
cargo fmt
cargo test --all-targets
cargo deny check advisories bans licenses sources
cargo publish --dry-run
```

For the project’s automated release flow, see [docs/releasing.md](docs/releasing.md).

GitHub releases and tags are kept aligned with crates.io versions.

## License

Licensed under either of the following, at your option:

- Apache License, Version 2.0
- MIT license
