Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore path deps in metadata hash #2687

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crate_universe/src/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl Digest {
})
}

/// A helper for generating a hash and logging it's contents.
/// A helper for generating a hash and logging its contents.
fn compute_single_hash(data: &str, id: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(data.as_bytes());
Expand Down Expand Up @@ -141,7 +141,7 @@ impl Digest {
// Data collected about Cargo manifests and configs that feed into dependency generation. This file
// is also generated by Bazel behind the scenes based on user inputs.
hasher.update(Digest::compute_single_hash(
&serde_json::to_string(splicing_metadata).unwrap(),
&splicing_metadata.as_digestable_str(),
"splicing manifest",
));
hasher.update(b"\0");
Expand Down
77 changes: 75 additions & 2 deletions crate_universe/src/splicing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl SplicingManifest {
}

/// The result of fully resolving a [SplicingManifest] in preparation for splicing.
#[derive(Debug, Serialize, Default)]
#[derive(Clone, Debug, Serialize, Default)]
pub(crate) struct SplicingMetadata {
/// A set of all packages directly written to the rule
pub(crate) direct_packages: DirectPackageManifest,
Expand Down Expand Up @@ -148,6 +148,27 @@ impl TryFrom<SplicingManifest> for SplicingMetadata {
}
}

impl SplicingMetadata {
// Calculates a string which can be digested to represent the splicing metadata.
// This allows us to strip out actions which may create noise when hashing otherwise causing spurious rebuilds.
// Things should only be stripped out if we are very confident they aren't used as part of resolving or rendering.
pub(crate) fn as_digestable_str(&self) -> String {
let mut copy = self.clone();
use cargo_toml::Dependency::*;
for (_, v) in copy.manifests.iter_mut() {
// Strip path dependencies.
// They don't end up factoring into what we generate, so we pretend they don't exist.
// This avoids people who are using both Cargo and Bazel needing to spuriously repin just because they edited Cargo-only dependency information.
v.dependencies.retain(|_, dep| match dep {
Detailed(details) => details.path.is_none(),
Simple(..) => true,
Inherited(..) => true,
})
}
serde_json::to_string(&copy).unwrap()
}
}

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub(crate) struct SourceInfo {
/// A url where to a `.crate` file.
Expand Down Expand Up @@ -227,7 +248,7 @@ impl WorkspaceMetadata {
})
.collect();

// It is invald for toml maps to use empty strings as keys. In the case
// It is invalid for toml maps to use empty strings as keys. In the case
// the empty key is expected to be the root package. If the root package
// has a prefix, then all other packages will as well (even if no other
// manifest represents them). The value is then saved as a separate value
Expand Down Expand Up @@ -653,4 +674,56 @@ mod test {
"serialized metadata should not contain absolute path"
);
}

#[test]
fn splicing_metadata_digest_ignores_path_deps() {
let cargo_toml_manifest_with_path_dep_str = r#"[package]
name = "pkg"
version = "0.1.0"
edition = "2021"

[dependencies]
local_pkg = { path = "local_pkg" }
termcolor = "1.4.1"
"#;

let cargo_toml_manifest_without_path_dep_str = r#"[package]
name = "pkg"
version = "0.1.0"
edition = "2021"

[dependencies]
termcolor = "1.4.1"
"#;

let label = Label::from_str("//pkg:Cargo.toml").unwrap();

let mut manifests_with_path_dep = BTreeMap::new();
manifests_with_path_dep.insert(
label.clone(),
cargo_toml::Manifest::from_str(cargo_toml_manifest_with_path_dep_str).unwrap(),
);

let mut manifests_without_path_dep = BTreeMap::new();
manifests_without_path_dep.insert(
label,
cargo_toml::Manifest::from_str(cargo_toml_manifest_without_path_dep_str).unwrap(),
);

let metadata_with_path_dep = SplicingMetadata {
direct_packages: DirectPackageManifest::new(),
manifests: manifests_with_path_dep,
cargo_config: None,
};
let metadata_without_path_dep = SplicingMetadata {
direct_packages: DirectPackageManifest::new(),
manifests: manifests_without_path_dep,
cargo_config: None,
};

assert_eq!(
metadata_with_path_dep.as_digestable_str(),
metadata_without_path_dep.as_digestable_str()
);
}
}
8 changes: 4 additions & 4 deletions crate_universe/src/splicing/cargo_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};

/// The [`[registry]`](https://doc.rust-lang.org/cargo/reference/config.html#registry)
/// table controls the default registry used when one is not specified.
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub(crate) struct Registry {
/// name of the default registry
pub(crate) default: String,
Expand All @@ -22,7 +22,7 @@ pub(crate) struct Registry {

/// The [`[source]`](https://doc.rust-lang.org/cargo/reference/config.html#source)
/// table defines the registry sources available.
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub(crate) struct Source {
/// replace this source with the given named source
#[serde(rename = "replace-with")]
Expand All @@ -38,7 +38,7 @@ fn default_registry_url() -> String {
utils::CRATES_IO_INDEX_URL.to_owned()
}

#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
/// registries other than crates.io
pub(crate) struct AdditionalRegistry {
/// URL of the registry index
Expand All @@ -52,7 +52,7 @@ pub(crate) struct AdditionalRegistry {
/// is required for parsing registry information.
/// See [cargo docs](https://doc.rust-lang.org/cargo/reference/config.html#configuration-format)
/// for more details.
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub(crate) struct CargoConfig {
/// registries other than crates.io
#[serde(default = "default_registries")]
Expand Down
2 changes: 1 addition & 1 deletion crate_universe/src/splicing/splicer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ impl<'a> SplicerKind<'a> {
// Optionally install the cargo config after contents have been symlinked
Self::setup_cargo_config(&splicing_manifest.cargo_config, workspace_dir)?;

// Add any additional depeendencies to the root package
// Add any additional dependencies to the root package
if !splicing_manifest.direct_packages.is_empty() {
Self::inject_direct_packages(&mut manifest, &splicing_manifest.direct_packages)?;
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading