Architecture
September 30, 2025 ยท View on GitHub
Before you get started, you might want to read about the architecture.
Getting started
Just clone the repo. Then you can make changes and simulate CI locally:
git clone https://github.com/cargo-public-api/cargo-public-api.git ; cd cargo-public-api
./scripts/run-ci-locally.sh
Note that you can run ./scripts/run-ci-locally.sh from from within your IDE. Then you can simply click on errors to navigate to the proper file, line number, and column. See .vscode/tasks.json for an example configuration.
Also note that for convenience there is a VS Code workspace you can use for out-of-the box code navigation etc, namely cargo-public-api.code-workspace.
Blessing new expected output
To make your changes become the expected output, run
UPDATE_SNAPSHOTS=yes ./scripts/cargo-test.sh
Expected Output
Output aims to be character-by-character identical to the textual parts of the regular cargo doc HTML output. For example, this item has the following textual representation in the rendered HTML:
pub fn input_files<I, P>(&mut self, paths: I) -> &mut Self
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
and cargo public-api renders this item in the following way:
pub fn bat::PrettyPrinter::input_files<I, P>(&mut self, paths: I) -> &mut Self where I: IntoIterator<Item = P>, P: AsRef<Path>
If we remove newline characters and add some whitespace padding to get the alignment right for side-by-side comparison, we can see that they are exactly the same, except an irrelevant trailing comma:
pub fn input_files<I, P>(&mut self, paths: I) -> &mut Self where I: IntoIterator<Item = P>, P: AsRef<Path>,
pub fn bat::PrettyPrinter::input_files<I, P>(&mut self, paths: I) -> &mut Self where I: IntoIterator<Item = P>, P: AsRef<Path>
Constraints
Minimum required stable Rust version
This project is guaranteed to build with the latest stable Rust toolchain. More specifically, the toolchain that is installed by default on GitHub's ubuntu-latest runner. You can see here what version that currently is.
Note that the toolchain required to build this project is distinct from the toolchain required to build the rustdoc JSON that this project relies on. See below for more info.
Minimum required nightly Rust version
Since the rustdoc JSON format still changes in incompatible ways, there is a lower bound on what nightly version you can use. For regular users, that minimal nightly version is mentioned in the README.md. For developers however, a more recent version can be needed. This is because even though the rustdoc JSON format is unchanged, its output can change. See this PR for just one example.
Our CI runs every night, so any problems are generally detected quickly. If cargo test fails, make sure you have a recent enough nightly toolchain installed.
Tips to work on this tool
Run local copy of cargo-public-api on an arbitrary crate
There are two ways. You can either do:
% cd ~/src/arbitrary-crate
% cargo run --manifest-path ~/src/cargo-public-api/cargo-public-api/Cargo.toml
or you can do
% cd ~/src/cargo-public-api
% cargo run --bin cargo-public-api -- --manifest-path ~/src/arbitrary-crate/Cargo.toml
In the first case --manifest-path is interpreted by cargo itself, and in the second case --manifest-path is interpreted by cargo-public-api.
You can also combine both ways:
% cd /does/not/matter
% cargo run --manifest-path ~/src/cargo-public-api/cargo-public-api/Cargo.toml -- --manifest-path ~/src/arbitrary-crate/Cargo.toml
Use custom rustdoc JSON toolchain
If you have built rustdoc yourself to try some rustdoc JSON fix, you can run cargo public-api with your custom toolchain like this:
cargo +custom public-api
Another option is the RUSTDOC_JSON_OVERRIDDEN_TOOLCHAIN_HACK env var. Use it like this:
RUSTDOC_JSON_OVERRIDDEN_TOOLCHAIN_HACK=custom ./scripts/run-ci-locally.sh
How to adapt to rustdoc JSON format changes
It is usually straightforward.
- Bump
[dependencies.rustdoc-types] versionin./public-api/Cargo.toml - Update
scripts/release-helper/src/version_info.rs - Run
cargo run --bin update-version-info - Make
cargo buildbuild - Make
./scripts/run-ci-locally.shpass, possibly afterUPDATE_SNAPSHOTS=yes ./scripts/cargo-test.sh
Once all of the above commands completes successfully, the upgrade is usually complete. See RELEASE.md for info about other preparations needed to make a release with the changes.
Automated tests
All features and bugfixes needs automated tests. The only way to make sure no regressions creep in in software that is constantly changed, is to test for it. But manually testing quickly becomes unmanageable. Therefore, automated tests are needed.
Maintainer guidelines
Please see MAINTAINER.md.