From 0a73e1851f669d3f780bed8957b4251caef2714e Mon Sep 17 00:00:00 2001 From: Matt Stark Date: Fri, 31 Mar 2023 12:13:33 +1100 Subject: [PATCH] Make serialization of packages deterministic. The nondeterminism is causing cache misses for users of bazel, who depend on this for rules_rust's crate_universe package (https://github.com/bazelbuild/rules_rust/tree/main/crate_universe). --- src/lib.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ed43479d..62751177 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,7 +81,7 @@ use camino::Utf8PathBuf; #[cfg(feature = "builder")] use derive_builder::Builder; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::env; use std::ffi::OsString; use std::fmt; @@ -109,7 +109,7 @@ pub use messages::{ ArtifactBuilder, ArtifactProfileBuilder, BuildFinishedBuilder, BuildScriptBuilder, CompilerMessageBuilder, }; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize, Serializer}; mod dependency; pub mod diagnostic; @@ -139,6 +139,18 @@ fn is_null(value: &serde_json::Value) -> bool { matches!(value, serde_json::Value::Null) } +/// Helper to ensure that hashmaps serialize in sorted order, to make +/// serialization deterministic. +fn sorted_map( + value: &HashMap, + serializer: S, +) -> std::result::Result { + value + .iter() + .collect::>() + .serialize(serializer) +} + #[derive(Clone, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "builder", derive(Builder))] #[non_exhaustive] @@ -311,6 +323,7 @@ pub struct Package { /// Targets provided by the crate (lib, bin, example, test, ...) pub targets: Vec, /// Features provided by the crate, mapped to the features required by that feature. + #[serde(serialize_with = "sorted_map")] pub features: HashMap>, /// Path containing the `Cargo.toml` pub manifest_path: Utf8PathBuf,