Skip to content

Commit

Permalink
fix: sort conda lock files alphabetically
Browse files Browse the repository at this point in the history
  • Loading branch information
baszalmstra committed Aug 28, 2023
1 parent bd8a713 commit aa93aa1
Show file tree
Hide file tree
Showing 4 changed files with 9,031 additions and 9,004 deletions.
1 change: 0 additions & 1 deletion crates/rattler_conda_types/src/conda_lock/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ impl LockFileBuilder {
.into_values()
.flat_map(|package| package.build())
.collect(),
version: super::default_version(),
};
Ok(lock)
}
Expand Down
46 changes: 36 additions & 10 deletions crates/rattler_conda_types/src/conda_lock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,16 @@ use url::Url;
pub mod builder;
mod content_hash;

/// Default version for the conda-lock file format
const fn default_version() -> u32 {
1
}

/// Represents the conda-lock file
/// Contains the metadata regarding the lock files
/// also the locked packages
#[derive(Serialize, Deserialize, Clone, Debug)]
#[derive(Deserialize, Clone, Debug)]
pub struct CondaLock {
/// Metadata for the lock file
pub metadata: LockMeta,

/// Locked packages
pub package: Vec<LockedDependency>,

/// Version of the conda-lock file format
#[serde(default = "default_version")]
pub version: u32,
}

#[allow(missing_docs)]
Expand Down Expand Up @@ -444,6 +435,41 @@ impl From<&str> for Channel {
}
}

impl Serialize for CondaLock {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[derive(Serialize)]
struct Raw<'a> {
metadata: &'a LockMeta,
package: Vec<&'a LockedDependency>,
version: u32,
}

// Sort all packages in alphabetical order. We choose to use alphabetic order instead of
// topological because the alphabetic order will create smaller diffs when packages change
// or are added.
// See: https://github.com/conda/conda-lock/issues/491
let mut sorted_deps = self.package.iter().collect::<Vec<_>>();
sorted_deps.sort_by(|&a, &b| {
a.name
.cmp(&b.name)
.then_with(|| a.platform.cmp(&b.platform))
.then_with(|| a.version.cmp(&b.version))
.then_with(|| a.build.cmp(&b.build))
});

let raw = Raw {
metadata: &self.metadata,
package: sorted_deps,
version: 1,
};

raw.serialize(serializer)
}
}

#[cfg(test)]
mod test {
use super::{channel_from_url, file_name_from_url, CondaLock, PackageHashes};
Expand Down
Loading

0 comments on commit aa93aa1

Please sign in to comment.