Expand description
hakari is the library underlying cargo hakari, a tool to
manage workspace-hack packages.
§Examples
use guppy::MetadataCommand;
use hakari::{HakariBuilder, HakariOutputOptions};
// Use this workspace's PackageGraph for these tests.
let package_graph = MetadataCommand::new()
.build_graph()
.expect("obtained cargo-guppy's PackageGraph");
// The second argument to HakariBuilder::new specifies a Hakari (workspace-hack) package.
// In this repository, the package is called "guppy-workspace-hack".
let hakari_package = package_graph.workspace().member_by_name("guppy-workspace-hack").unwrap().id();
let hakari_builder = HakariBuilder::new(&package_graph, Some(hakari_package))
.expect("HakariBuilder was constructed");
// HakariBuilder has a number of config options. For this example, use the defaults.
let hakari = hakari_builder.compute();
// hakari can be used to build a TOML representation that forms part of a Cargo.toml file.
// Existing Cargo.toml files can be managed using Hakari::read_toml.
let toml = hakari.to_toml_string(&HakariOutputOptions::default()).expect("TOML output was constructed");
// toml contains the Cargo.toml [dependencies] that would go in the Hakari package. It can be
// written out through `HakariCargoToml` (returned by Hakari::read_toml) or manually.
println!("Cargo.toml contents:\n{}", toml);The cargo-guppy repository uses a workspace-hack crate managed by cargo hakari. See the
generated Cargo.toml.
The cargo-guppy repository also has a number of fixtures that demonstrate Hakari’s output.
Here is an example.
§How hakari works
Hakari follows a three-step process.
§1. Configuration
A HakariBuilder provides options to configure how a Hakari computation is done. Options supported
include:
- the location of the
workspace-hackpackage - platforms to simulate Cargo builds on
- the version of the Cargo resolver to use
- packages to be excluded during computation
- packages to be excluded from the final output
With the optional cli-support feature, HakariBuilder options can be
read from or written to
a file as TOML or some other format.
§2. Computation
Once a HakariBuilder is configured, its compute method can be
called to create a Hakari instance. The algorithm runs in three steps:
- Use guppy to simulate a Cargo build for every workspace package and every given platform, with no features, default features and all features. Collect the results into a map indexed by every dependency and the different sets of features it was built with.
- Scan through the map to figure out which dependencies are built with two or more different feature sets, collecting them into an output map.
- If one assumes that the output map will be written out to the
workspace-hackpackage through step 3 below, it is possible that it causes some extra packages to be built with a second feature set. Look for such packages, add them to the output map, and iterate until a fixpoint is reached and no new packages are built more than one way.
This computation is done in a parallel fashion, using the Rayon library.
The result of this computation is a Hakari instance.
Third-party packages that depend on the workspace-hack, or on a workspace member that hakari manages, are never unified, since adding them would form a cycle. These are called structural excludes. Note that their own dependencies are still unified as usual.
§3. Serialization
The last step is to serialize the contents of the output map into the workspace-hack package’s
Cargo.toml file.
-
Hakari::read_tomlreads an existingCargo.tomlfile on disk. This file is partially generated:[package] name = "workspace-hack" version = "0.1.0" # more options... #### BEGIN HAKARI SECTION ... #### END HAKARI SECTIONThe contents outside the
BEGIN HAKARI SECTIONandEND HAKARI SECTIONlines may be edited by hand. The contents within this section are automatically generated.On success, a
HakariCargoTomlis returned. -
Hakari::to_toml_stringreturns the new contents of the automatically generated section. -
HakariCargoToml::write_to_filewrites out the contents to disk.
HakariCargoToml also supports serializing contents to memory and producing diffs.
§Future work
hakari is still missing a few features:
- Simulating cross-compilations
- Platform-specific excludes
- Only including a subset of packages in the final result (e.g. unifying core packages like
synbut not any others)
These features will be added as time permits.
Re-exports§
pub use diffy;
Modules§
- cli_ops
- Command-line operations for
hakari. - explain
- Information about why a dependency is in the workspace-hack.
- internals
- Access to internal Hakari data structures.
- summaries
- Manage configuration and generate summaries for
hakari. - verify
- Code related to ensuring that
hakariworks properly.
Structs§
- Hakari
- The result of a Hakari computation.
- Hakari
Builder - Configures and constructs
Hakariinstances. - Hakari
Cargo Toml - Support for maintaining
Cargo.tomlfiles that unify features in a workspace. - Hakari
Output Options - Options for Hakari TOML output.
Enums§
- Cargo
Toml Error - An error that can occur while reading or writing a
Cargo.tomlfile. - DepFormat
Version - Format version for hakari.
- Toml
OutError - An error that occurred while writing out TOML.
- Unify
Target Host - Whether to unify feature sets for a given dependency across target and host platforms.
- Workspace
Hack Line Style - Style of
workspace-hack = ...lines to output.