Crate ingredients

Crate ingredients 

Source
Expand description

§Check ingredients of published Rust crates

This crate implements two modes for checking ingredients of Rust crates:

  • report: Comparing published crate sources from crates.io with the associated contents of the project’s version control system.
  • diff: Compare contents of two different, published versions of the same crate.

§report mode

This comparison mode reads crate metadata (from Cargo.toml and from the .cargo_vcs_info.json file that is embedded by cargo during the publishing process), fetches the corresponding git repository, and compares the contents of the published crate with the contents of the project repository at the ref that is recorded in .cargo_vcs_info.json.

Any actual differences in file contents or crate metadata are considered to be errors. Issues that prevent checking for differences (like missing metadata or an invalid git repository) are considered fatal.

Example using the Rust API:

use ingredients::Crate;

#[tokio::main]
async fn main() {
    let krate = Crate::download("syn", "2.0.111").await.unwrap();
    let report = krate.report().await.unwrap();
    println!("{report}");
}

Example using the CLI:

ingredients report syn 2.0.111

Some differences are “expected” and are not reported:

  • The Cargo.toml file is processed and rewritten during the publishing process. Instead, the Cargo.toml contents from the repository is compared to Cargo.toml.orig, which contains the original, unmodified file contents.
  • Instead, crate metadata is compared by parsing Cargo.toml contents and checking for semantic equivalence instead of byte-for-byte equivalence.
  • Dependencies that are “path”-based are stripped by cargo during the publishing process. Differences in crate dependencies that are solely due to “path”-based dependencies having been stripped are ignored and not reported.
  • Symbolic links present in the project repository are resolved during the publishing process, cargo includes actual files in published crates instead.

§diff mode

This mode compares crate metadata and contents between two source archives that were published to crates.io. It is much less strict than the “report” mode (because differences are expected when comparing two different versions of a crate), but will report differences with more granularity than just reporting an error on any difference. As such, the only difference that actually triggers a lint with “error” severity is if the crate name is different. This should only ever happen when comparing two different crates (but which might be useful to do in cases where a crate is “renamed”, i.e. new versions are published under a different name).

Example using the Rust API:

use ingredients::Crate;

#[tokio::main]
async fn main() {
    let old_krate = Crate::download("syn", "2.0.110").await.unwrap();
    let new_krate = Crate::download("syn", "2.0.111").await.unwrap();
    let diff = old_krate.diff(&new_krate).unwrap();
    println!("{diff}");
}

Example using the CLI:

ingredients diff syn 2.0.110 2.0.111

§Features

  • cli (disabled by default)

Almost all functionality from the crate API is also available from the command-line interface. To build the ingredients command-line program, compile with the cli feature enabled.

§Installation

From crates.io: cargo install -F cli ingredients

§External dependencies

Building:

  • cargo (refer to package.rust-version in Cargo.toml for the minimum supported Rust version)
  • openssl development headers must be available (for reqwest/native-tls)

Runtime:

  • cargo must be available in $PATH

Loading and parsing crate metadata is implemented based on the cargo_metadata crate, which calls cargo metadata internally.

  • git must be available in $PATH for “report” mode

The git command is used for checking out git repositories in Crate::report, and in turn, it is also required by the ingredients report subcommand.

Moving to a solution for cloning / checkout out git repositories that does not rely on an external git command is planned, but currently blocked by missing support for shallow clones / cloning non-branch refs in gitoxide (see https://github.com/GitoxideLabs/gitoxide/discussions/2309), among other issues.

Structs§

Crate
Crate archive
Diff
List of differences between two crates
Report
List of differences between a published crate and the associated state of the upstream version control system
ReportOptions
Additional options for report generation

Enums§

DiffItem
A specific difference between two crates
Error
Error enum representing different errors that can occur in this crate.
ReportItem
A specific difference between a published crate and the associated state of the upstream version control system
Severity
Severity associated with report and diff items