cargo-public-api 0.14.0

List and diff the public API of Rust library crates between releases and commits. Detect breaking API changes and semver violations.
Documentation

cargo-public-api

List and diff the public API of Rust library crates between releases and commits. Detect breaking API changes and semver violations. Relies on and automatically builds rustdoc JSON, for which a recent version of the Rust nightly toolchain must be installed.

Installation

# Install cargo-public-api with a recent regular stable Rust toolchain
cargo install cargo-public-api

# Ensure nightly-2022-08-15 or later is installed so cargo-public-api can build rustdoc JSON for you
rustup install nightly

Usage

List the public API

This example lists the public API of the ubiquitous regex crate. First let's clone the repo:

git clone https://github.com/rust-lang/regex
cd regex

Now we can list the public API of regex by doing

cargo public-api

which will print the public API of regex with one line per public item in the API:

Diff the public API

To diff the API between say 0.2.2 and 0.2.3 of regex, use --diff-git-checkouts 0.2.2 0.2.3 while standing in the git repo. Like this:

cargo public-api --diff-git-checkouts 0.2.2 0.2.3

and the API diff will be printed:

You can also manually do a diff by writing the full list of items to a file for two different versions of your library and then do a regular diff between the files.

As a CI check

Via CI you can ensure the public API is not changed for your crate by using --deny=all together with --diff-git-checkouts. For example, a GitHub Actions job to do this would look something like this:

jobs:
  deny-public-api-changes:
    runs-on: ubuntu-latest
    steps:
      # Full git history needed
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0

      # Install nightly (stable is already installed)
      - uses: actions-rs/toolchain@v1
        with:
          toolchain: nightly
          profile: minimal

      # Install and run cargo public-api and deny any API diff
      - run: cargo install cargo-public-api
      - run: cargo public-api --diff-git-checkouts ${GITHUB_BASE_REF} ${GITHUB_HEAD_REF} --deny=all

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 represents this item in the following manner:

pub fn bat::PrettyPrinter::input_files<I, P>(&mut self, paths: I) -> &mut Self where I: IntoIterator<Item = P>, P: AsRef<Path>

If we normalize by removing newline characters and adding 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>

Blanket implementations

By default, blanket implementations such as impl<T> Any for T, impl<T> Borrow<T> for T, and impl<T, U> Into<U> for T where U: From<T> are omitted from the list of public items of a crate. For the vast majority of use cases, blanket implementations are not of interest, and just creates noise.

Use --with-blanket-implementations if you want to include items of blanket implementations in the output:

cargo public-api --with-blanket-implementations

Compatibility matrix

cargo-public-api Understands the rustdoc JSON output of
v0.14.x nightly-2022-08-15 —
v0.13.x nightly-2022-08-10 — nightly-2022-08-14
v0.12.x nightly-2022-05-19 — nightly-2022-08-09
v0.10.x nightly-2022-03-14 — nightly-2022-05-18
v0.5.x nightly-2022-02-23 — nightly-2022-03-13
v0.2.x nightly-2022-01-19 — nightly-2022-02-22
v0.0.5 nightly-2021-10-11 — nightly-2022-01-18

Contributing

See CONTRIBUTING.md.

Maintainers