Skip to main content

A C/C++ #include path normalizer that rewrites includes to resolve cleanly against a minimal -I set.

Project description

inclean

English | 简体中文

A C/C++ #include path normalizer.

Many legacy C/C++ libraries #include headers by bare filename (#include "bar.h") even though the actual header lives several directories deep (src/internal/bar.h). To consume such a library a caller must add every internal directory to their -I list — which pollutes their include namespace and breaks the library's encapsulation.

inclean does a one-shot, source-level normalization. It scans every source file in the library and rewrites each #include so it resolves cleanly against a small, explicit set of allowed include directories. After running inclean, consumers only -I the allowed directories.


Install

inclean is published to crates.io, PyPI, and as prebuilt binaries on GitHub Releases. Pick whichever ecosystem you already have on your machine.

Via PyPI (Python wheels — no Rust toolchain needed)

Three options:

uv tool install inclean      # isolated, fastest
pipx install inclean         # isolated
pip install inclean          # into the current environment

The wheels ship the native binary built by maturin; inclean lands on your PATH the same way ruff or uv do. Requires Python ≥ 3.8.

Via cargo

Two options:

cargo binstall inclean       # prebuilt binary from GitHub Releases (no compilation)
cargo install inclean        # build from crates.io

cargo binstall fetches inclean's binstall metadata from crates.io and downloads the matching prebuilt archive from this repo's GitHub Releases (no compilation). cargo binstall is a third-party cargo subcommand — install it first via cargo-bins/cargo-binstall if you don't already have it.

cargo install downloads the source from crates.io and compiles it locally.

Prebuilt binaries (no package manager)

Download a tarball for your platform from the latest GitHub Release and put inclean (or inclean.exe) on your PATH.

From repo source

Clone this repo and build from source:

git clone https://github.com/inaku-Gyan/inclean.git
cd inclean
cargo install --path .

Quick start

inclean is driven by an inclean.toml placed at the root of the library you want to clean up. A typical workflow:

inclean init                # write a documented starter inclean.toml
$EDITOR inclean.toml        # tell it where your headers live
inclean check               # dry-run: report every proposed change
inclean diff                # see the rewrites as a unified diff
inclean apply               # write the rewrites in place

check / diff / apply optionally take [PATHS...] to restrict which files are processed; with no paths they consider every source file under the project root. -c PATH overrides the upward inclean.toml walk; -j N sets the worker thread count.

Rule matching first checks file_paths, file_suffixes, include_forms, and include_match. Globs are anchored and use literal separators: foo.h only matches foo.h, while **/foo.h matches at any depth. Glob lists are ordered: a leading unescaped ! excludes, and the last matching pattern wins. Use TOML single quotes for a literal leading bang, for example '\!weird.h'; in double quotes, write "\\!weird.h". When include_directories is set, inclean then probes those literal directories and applies include_on_unresolved (error / skip / allow) and include_on_ambiguous (error / skip / first). For rules that are meant to affect only one side of a rewrite, the whole field values action = "skip" and trailing_comment = "skip" make that side opt out of conflict detection. keep still participates in conflict checks; skip does not. For a rule without copied_from, both fields default to skip when omitted.

Example

A simple replace-action config that rewrites #include "foo.h" to #include "lib/foo.h":

[project]
root = "."
version = "0.3.0"
min_inclean_version = "0.3.0"

[[rule]]
name = "lib-prefix"
file_paths = ["src/**/*"]
include_match = ["foo.h", "bar.h"]
action = { type = "replace", with = "lib/${original}" }

See tests/golden_tests/ for runnable end-to-end examples.

Editor support

inclean.toml ships with a JSON Schema for editor completion and validation. Editors that understand the #:schema directive (VS Code with Even Better TOML, Helix, Zed) automatically pick it up:

#:schema https://raw.githubusercontent.com/inaku-Gyan/inclean/v1.2.3/schemas/inclean.toml.schema.json

[project]
root = "."
version = "1.2.3"
min_inclean_version = "1.1.0"

(The above version numbers are just examples.)

inclean init writes both the #:schema line (for the editor) and the [project].version + [project].min_inclean_version fields, each pinned to the CLI version that generated the file. To upgrade schema validation, edit the version segment in the URL to a newer release tag.

#:schema and the [project] version fields are independent. The #:schema URL is purely for editor tooling; the CLI runs its own two-direction compatibility check (CLI_COMPAT_MIN <= cfg.version AND cfg.min_inclean_version <= CLI_CURRENT). inclean is pre-1.0 and does not ship migration shims for breaking schema changes — see CLAUDE.md.

You can also dump a local copy:

inclean config schema --output inclean.toml.schema.json

Documentation

  • inclean init writes the most complete user-facing configuration reference into the generated inclean.toml.
  • schemas/inclean.toml.schema.json — editor schema generated from the Rust config structs.
  • tests/golden_tests/ — runnable examples for replacement, resolution, copy semantics, suppression, trailing comments, conflicts, and encoding preservation.
  • CONTRIBUTING.md — toolchain, dev workflow, conventions, scope.

License

BSD 3-Clause.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

inclean-0.3.0.tar.gz (105.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

inclean-0.3.0-py3-none-win_amd64.whl (1.7 MB view details)

Uploaded Python 3Windows x86-64

inclean-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

inclean-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

inclean-0.3.0-py3-none-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

inclean-0.3.0-py3-none-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file inclean-0.3.0.tar.gz.

File metadata

  • Download URL: inclean-0.3.0.tar.gz
  • Upload date:
  • Size: 105.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for inclean-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1e89c9e77406678978a0fc6af73f4727d07992149e6292917008280bade0180a
MD5 8913e3a6fbf7e166b609b3fadd869bdd
BLAKE2b-256 92b3891bc8908f00ab759751c93a6ac4697601bf614fa7f43217e46daf439659

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0.tar.gz:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.3.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: inclean-0.3.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for inclean-0.3.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 a42204bc6469798e82dbfaba42c2dc1f93b3b95cbf32560f6881767fe0b615f1
MD5 87f159c926176913ce83eb559f119cfa
BLAKE2b-256 95ba6dd5295e1715f2c127896358335bf512ae59d3e499e1f63c12411e114305

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0-py3-none-win_amd64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for inclean-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e85a8b05811dc6a8ce181f868e39204e08c435d3a1f40c231ac4e4fb9441a2de
MD5 4bab9238708f1d885327f98f781620f3
BLAKE2b-256 5642662becfc736996e19673be92b31468d41bc1e0fc9dfc1c4e43215729f117

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for inclean-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4d471edeb1362f2882af2d101e416cc997547c6eb72fc6c48b70fefc4704c0b9
MD5 4430dd8a1c188938f96d95780b2704dd
BLAKE2b-256 a2eb2b3c673a2e730d84f00274b85956309c66df92da37e7f6028d4aaa196c69

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.3.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for inclean-0.3.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c6de8d2176ffc3c5f9d9f6de6d21b1fe6b2779a1b4e9fbf5abcb32996c38f3f4
MD5 ab153a2da874c9b3d36d5f9aef0d4b08
BLAKE2b-256 5b8f7d118683f6c5cca60f18aaef1c128684f2e8e1b829056831580ffc0e3436

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inclean-0.3.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for inclean-0.3.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 402196fd7363553f0e2e6693b75330e112c7061d0253f82b47f13e9bb9121e51
MD5 cabdd368c7fa43bfb969776902c3022c
BLAKE2b-256 4cc962c5fa37b2e664453b9b85aa667bfae17a54e2ef3c99b1ab0fe517f72e56

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on inaku-Gyan/inclean

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page