diff --git a/crates/rattler_conda_types/src/conda_lock/builder.rs b/crates/rattler_conda_types/src/conda_lock/builder.rs index b082c24eb..c61e30781 100644 --- a/crates/rattler_conda_types/src/conda_lock/builder.rs +++ b/crates/rattler_conda_types/src/conda_lock/builder.rs @@ -141,8 +141,8 @@ impl LockedPackages { category: super::default_category(), source: None, build: Some(locked_package.build_string), - arch: locked_package.arch, - subdir: locked_package.subdir, + arch: self.platform.arch().map(|arch| arch.to_string()), + subdir: Some(self.platform.to_string()), build_number: locked_package.build_number, constrains: if locked_package.constrains.is_empty() { None @@ -450,7 +450,7 @@ mod tests { ); assert_eq!( record.package_record.platform.clone().unwrap(), - locked_dep.platform.to_string() + locked_dep.platform.only_platform().unwrap() ); assert_eq!(record.package_record.arch, locked_dep.arch); assert_eq!( diff --git a/crates/rattler_conda_types/src/conda_lock/mod.rs b/crates/rattler_conda_types/src/conda_lock/mod.rs index 8fe8b9772..84fd67036 100644 --- a/crates/rattler_conda_types/src/conda_lock/mod.rs +++ b/crates/rattler_conda_types/src/conda_lock/mod.rs @@ -242,7 +242,8 @@ pub struct LockedDependency { pub version: String, /// Pip or Conda managed pub manager: Manager, - /// What platform is this package for + /// What platform is this package for (different to other places in the conda ecosystem, + /// this actually represents the _full_ subdir (incl. arch)) pub platform: Platform, /// What are its own dependencies mapping name to version constraint @@ -370,6 +371,9 @@ impl TryFrom for RepoDataRecord { let build = value .build .ok_or_else(|| ConversionError::Missing("build".to_string()))?; + + let platform = value.platform.only_platform(); + Ok(Self { package_record: PackageRecord { arch: value.arch, @@ -385,10 +389,10 @@ impl TryFrom for RepoDataRecord { md5, name: value.name, noarch: value.noarch, - platform: Some(value.platform.to_string()), + platform: platform.map(|p| p.to_string()), sha256, size: value.size, - subdir: value.subdir.unwrap_or("noarch".to_string()), + subdir: value.subdir.unwrap_or(value.platform.to_string()), timestamp: value.timestamp, track_features: value.track_features.unwrap_or_default(), version, @@ -443,10 +447,10 @@ impl From<&str> for Channel { #[cfg(test)] mod test { use super::{channel_from_url, file_name_from_url, CondaLock, PackageHashes}; - use crate::Platform; + use crate::{Platform, RepoDataRecord, VersionWithSource}; use insta::assert_yaml_snapshot; use serde_yaml::from_str; - use std::path::Path; + use std::{path::Path, str::FromStr}; use url::Url; #[test] @@ -562,4 +566,44 @@ mod test { Some("foo-1-0.conda") ); } + + #[test] + fn test_locked_dependency() { + let yaml = r#" + name: ncurses + version: '6.4' + manager: conda + platform: linux-64 + arch: x86_64 + dependencies: + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-hcb278e6_0.conda + hash: + md5: 681105bccc2a3f7f1a837d47d39c9179 + sha256: ccf61e61d58a8a7b2d66822d5568e2dc9387883dd9b2da61e1d787ece4c4979a + optional: false + category: main + build: hcb278e6_0 + subdir: linux-64 + build_number: 0 + license: X11 AND BSD-3-Clause + size: 880967 + timestamp: 1686076725450"#; + + let result: crate::conda_lock::LockedDependency = from_str(yaml).unwrap(); + + assert_eq!(result.name, "ncurses"); + assert_eq!(result.version, "6.4"); + + let repodata_record = RepoDataRecord::try_from(result.clone()).unwrap(); + + assert_eq!(repodata_record.package_record.name, "ncurses"); + assert_eq!( + repodata_record.package_record.version, + VersionWithSource::from_str("6.4").unwrap() + ); + assert!(repodata_record.package_record.noarch.is_none()); + + insta::assert_yaml_snapshot!(repodata_record); + } } diff --git a/crates/rattler_conda_types/src/conda_lock/snapshots/rattler_conda_types__conda_lock__test__locked_dependency.snap b/crates/rattler_conda_types/src/conda_lock/snapshots/rattler_conda_types__conda_lock__test__locked_dependency.snap new file mode 100644 index 000000000..a691dc007 --- /dev/null +++ b/crates/rattler_conda_types/src/conda_lock/snapshots/rattler_conda_types__conda_lock__test__locked_dependency.snap @@ -0,0 +1,22 @@ +--- +source: crates/rattler_conda_types/src/conda_lock/mod.rs +expression: repodata_record +--- +arch: x86_64 +build: hcb278e6_0 +build_number: 0 +depends: + - libgcc-ng >=12 +license: X11 AND BSD-3-Clause +md5: 681105bccc2a3f7f1a837d47d39c9179 +name: ncurses +platform: linux +sha256: ccf61e61d58a8a7b2d66822d5568e2dc9387883dd9b2da61e1d787ece4c4979a +size: 880967 +subdir: linux-64 +timestamp: 1686076725450 +version: "6.4" +fn: ncurses-6.4-hcb278e6_0.conda +url: "https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-hcb278e6_0.conda" +channel: "https://conda.anaconda.org/conda-forge" + diff --git a/crates/rattler_conda_types/src/platform.rs b/crates/rattler_conda_types/src/platform.rs index dadfbb2ce..0939809a3 100644 --- a/crates/rattler_conda_types/src/platform.rs +++ b/crates/rattler_conda_types/src/platform.rs @@ -190,6 +190,26 @@ impl Platform { pub const fn is_osx(self) -> bool { matches!(self, Platform::Osx64 | Platform::OsxArm64) } + + /// Return only the platform (linux, win, or osx from the platform enum) + pub fn only_platform(&self) -> Option<&str> { + match self { + Platform::NoArch => None, + Platform::Linux32 + | Platform::Linux64 + | Platform::LinuxAarch64 + | Platform::LinuxArmV6l + | Platform::LinuxArmV7l + | Platform::LinuxPpc64le + | Platform::LinuxPpc64 + | Platform::LinuxS390X + | Platform::LinuxRiscv32 + | Platform::LinuxRiscv64 => Some("linux"), + Platform::Osx64 | Platform::OsxArm64 => Some("osx"), + Platform::Win32 | Platform::Win64 | Platform::WinArm64 => Some("win"), + Platform::Emscripten32 => Some("emscripten"), + } + } } /// An error that can occur when parsing a platform from a string.