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-alpha.3"
min_inclean_version = "0.3.0-alpha.3"

[[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.0a3.tar.gz (105.3 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.0a3-py3-none-win_amd64.whl (1.7 MB view details)

Uploaded Python 3Windows x86-64

inclean-0.3.0a3-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.0a3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

inclean-0.3.0a3-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.0a3.tar.gz.

File metadata

  • Download URL: inclean-0.3.0a3.tar.gz
  • Upload date:
  • Size: 105.3 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.0a3.tar.gz
Algorithm Hash digest
SHA256 bcee155d5c80cabd28ad52793728194f0ad3d82bffaa9c8f1cc490c89141cece
MD5 2b8391e92ecb775de214f4657d6d170f
BLAKE2b-256 659fd5ab38bb308e003cf224c0c896ea656fc10579ba9ff093de7a589fb500f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0a3.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.0a3-py3-none-win_amd64.whl.

File metadata

  • Download URL: inclean-0.3.0a3-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.0a3-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 c2967a9112c4f075a48a6d8f1891fcaf51cee6a8a91ec0ecd4aa5c0469cbe5b1
MD5 4e63048cda1bf5a81febba5a4e80932a
BLAKE2b-256 deb3522ab26982aaa8b5f34ffa5be318d5ef106245315e37b344e918aaa8db1f

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0a3-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.0a3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for inclean-0.3.0a3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4d6e7bf01004fc19548b048411fe486a6320689d0a21d7b8c1f061937346a01b
MD5 6126ff82f8870871cb6a196ee3ecdab7
BLAKE2b-256 97b4f73cfeb152f0ab34a2366553a54b40f28847f8bfe66fc9115cf25daa268a

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0a3-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.0a3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for inclean-0.3.0a3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 cee79270f2accc67b28536b09f05165e7e750563f38e04773c9c4bddda21825f
MD5 1eb16fcb8df8d4ce94b2f2b93ac09e2a
BLAKE2b-256 400e943c4166fd6ad245c168027734f83b80aa0d863613ba1c3d1d0b224d22d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0a3-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.0a3-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for inclean-0.3.0a3-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 49df730b6953912ca0be92e20c23e08ca8192a897e68535b3748deff5d050d77
MD5 6ac799fee0c84bb66effd0750b442e96
BLAKE2b-256 18818350e0ff31fa946d98077ad4af2d4dfb329a8ffc039bcfabbe39179335d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0a3-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.0a3-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for inclean-0.3.0a3-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 25a47d4e32a06cba7a2c1f135d9a2b1480852e1027e58b516a27bbf641d7fabf
MD5 c3bb5e9eb4d8b2599d5964e232cf7a09
BLAKE2b-256 1909e7b17cad7047f8e6fd652f68f7d0d913e112eeee9eea73082721f2e926ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for inclean-0.3.0a3-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