|
10 | 10 |
|
11 | 11 | use std::{fmt::Debug, sync::Arc}; |
12 | 12 |
|
13 | | -use miette::IntoDiagnostic; |
14 | 13 | use pixi_build_types::{self as pbt}; |
15 | 14 | use rattler_conda_types::{Channel, MatchSpec, NamelessMatchSpec, PackageName}; |
16 | 15 |
|
@@ -87,15 +86,8 @@ impl PackageSpec for pbt::PackageSpecV1 { |
87 | 86 | ) -> miette::Result<(MatchSpec, Option<Self::SourceSpec>)> { |
88 | 87 | match self { |
89 | 88 | pbt::PackageSpecV1::Binary(binary_spec) => { |
90 | | - let match_spec = if binary_spec.version == Some("*".parse().unwrap()) { |
91 | | - // Skip dependencies with wildcard versions. |
92 | | - name.as_normalized() |
93 | | - .to_string() |
94 | | - .parse::<MatchSpec>() |
95 | | - .into_diagnostic()? |
96 | | - } else { |
97 | | - MatchSpec::from_nameless(binary_spec.to_nameless(), Some(name)) |
98 | | - }; |
| 89 | + // Always use to_nameless() to preserve all fields including build constraints |
| 90 | + let match_spec = MatchSpec::from_nameless(binary_spec.to_nameless(), Some(name)); |
99 | 91 | Ok((match_spec, None)) |
100 | 92 | } |
101 | 93 | pbt::PackageSpecV1::Source(source_spec) => Ok(( |
@@ -142,3 +134,99 @@ impl PackageSourceSpec for pbt::SourcePackageSpecV1 { |
142 | 134 | self |
143 | 135 | } |
144 | 136 | } |
| 137 | + |
| 138 | +#[cfg(test)] |
| 139 | +mod tests { |
| 140 | + use super::*; |
| 141 | + use rattler_conda_types::{ParseStrictness, StringMatcher, VersionSpec}; |
| 142 | + |
| 143 | + #[test] |
| 144 | + fn test_to_match_spec_preserves_build_constraint_with_wildcard_version() { |
| 145 | + // Test case: dependency with wildcard version and build constraint |
| 146 | + // e.g., tk = { build = "xft*" } |
| 147 | + let build_matcher: StringMatcher = "xft*".parse().unwrap(); |
| 148 | + let binary_spec = pbt::BinaryPackageSpecV1 { |
| 149 | + version: Some(VersionSpec::Any), |
| 150 | + build: Some(build_matcher.clone()), |
| 151 | + build_number: None, |
| 152 | + file_name: None, |
| 153 | + channel: None, |
| 154 | + subdir: None, |
| 155 | + md5: None, |
| 156 | + sha256: None, |
| 157 | + url: None, |
| 158 | + license: None, |
| 159 | + }; |
| 160 | + |
| 161 | + let package_spec = pbt::PackageSpecV1::Binary(Box::new(binary_spec)); |
| 162 | + let package_name = PackageName::try_from("tk").unwrap(); |
| 163 | + |
| 164 | + let (match_spec, _) = package_spec.to_match_spec(package_name).unwrap(); |
| 165 | + |
| 166 | + // Verify the build constraint is preserved |
| 167 | + assert_eq!(match_spec.name, Some(PackageName::try_from("tk").unwrap())); |
| 168 | + assert_eq!(match_spec.version, Some(VersionSpec::Any)); |
| 169 | + assert_eq!(match_spec.build, Some(build_matcher)); |
| 170 | + } |
| 171 | + |
| 172 | + #[test] |
| 173 | + fn test_to_match_spec_preserves_build_constraint_with_specific_version() { |
| 174 | + // Test case: dependency with specific version and build constraint |
| 175 | + // e.g., tk = { version = "8.6.13", build = "xft*" } |
| 176 | + let version = VersionSpec::from_str("8.6.13", ParseStrictness::Lenient).unwrap(); |
| 177 | + let build_matcher: StringMatcher = "xft*".parse().unwrap(); |
| 178 | + let binary_spec = pbt::BinaryPackageSpecV1 { |
| 179 | + version: Some(version.clone()), |
| 180 | + build: Some(build_matcher.clone()), |
| 181 | + build_number: None, |
| 182 | + file_name: None, |
| 183 | + channel: None, |
| 184 | + subdir: None, |
| 185 | + md5: None, |
| 186 | + sha256: None, |
| 187 | + url: None, |
| 188 | + license: None, |
| 189 | + }; |
| 190 | + |
| 191 | + let package_spec = pbt::PackageSpecV1::Binary(Box::new(binary_spec)); |
| 192 | + let package_name = PackageName::try_from("tk").unwrap(); |
| 193 | + |
| 194 | + let (match_spec, _) = package_spec.to_match_spec(package_name).unwrap(); |
| 195 | + |
| 196 | + // Verify both version and build constraint are preserved |
| 197 | + assert_eq!(match_spec.name, Some(PackageName::try_from("tk").unwrap())); |
| 198 | + assert_eq!(match_spec.version, Some(version)); |
| 199 | + assert_eq!(match_spec.build, Some(build_matcher)); |
| 200 | + } |
| 201 | + |
| 202 | + #[test] |
| 203 | + fn test_to_match_spec_without_build_constraint() { |
| 204 | + // Test case: dependency with wildcard version but no build constraint |
| 205 | + // e.g., python = "*" |
| 206 | + let binary_spec = pbt::BinaryPackageSpecV1 { |
| 207 | + version: Some(VersionSpec::Any), |
| 208 | + build: None, |
| 209 | + build_number: None, |
| 210 | + file_name: None, |
| 211 | + channel: None, |
| 212 | + subdir: None, |
| 213 | + md5: None, |
| 214 | + sha256: None, |
| 215 | + url: None, |
| 216 | + license: None, |
| 217 | + }; |
| 218 | + |
| 219 | + let package_spec = pbt::PackageSpecV1::Binary(Box::new(binary_spec)); |
| 220 | + let package_name = PackageName::try_from("python").unwrap(); |
| 221 | + |
| 222 | + let (match_spec, _) = package_spec.to_match_spec(package_name).unwrap(); |
| 223 | + |
| 224 | + // Verify the match spec is correct |
| 225 | + assert_eq!( |
| 226 | + match_spec.name, |
| 227 | + Some(PackageName::try_from("python").unwrap()) |
| 228 | + ); |
| 229 | + assert_eq!(match_spec.version, Some(VersionSpec::Any)); |
| 230 | + assert_eq!(match_spec.build, None); |
| 231 | + } |
| 232 | +} |
0 commit comments