Skip to content

Commit af1be21

Browse files
authored
fix: return all used variants (#438)
Make sure that all used variants are returned by conda_outputs* fix: return all used variants
1 parent 511411d commit af1be21

File tree

7 files changed

+343
-70
lines changed

7 files changed

+343
-70
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/pixi-build-backend/src/intermediate_backend.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -253,23 +253,11 @@ where
253253
// combination of defaults provided by the generator (lowest priority),
254254
// variants loaded from external files, and finally the user supplied
255255
// variants (highest priority).
256-
let mut variant_config = if let Some(variant_files) = params
257-
.variant_files
258-
.as_ref()
259-
.filter(|files| !files.is_empty())
260-
{
261-
let mut variant_config =
262-
VariantConfig::from_files(variant_files, &selector_config_for_variants)?;
263-
variants.append(&mut variant_config.variants);
264-
variant_config.variants = variants;
265-
variant_config
266-
} else {
267-
VariantConfig {
268-
variants,
269-
pin_run_as_build: None,
270-
zip_keys: None,
271-
}
272-
};
256+
let variant_files = params.variant_files.unwrap_or_default();
257+
let mut variant_config =
258+
VariantConfig::from_files(&variant_files, &selector_config_for_variants)?;
259+
variants.append(&mut variant_config.variants);
260+
variant_config.variants = variants;
273261

274262
let mut param_variants =
275263
convert_input_variant_configuration(params.variant_configuration.clone())

crates/pixi-build-backend/src/utils/test.rs

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,15 @@ pub(crate) fn remove_empty_values(value: &mut Value) {
4141
}
4242
}
4343

44-
/// Calls the `conda/outputs` procedure of the `IntermediateBackend` for the
44+
/// Prepares and calls the `conda/outputs` procedure of the `IntermediateBackend` for the
4545
/// given recipe general and with the given project model.
46-
///
47-
/// Returns a pretty-printed JSON string of the outputs that can be used for
48-
/// snapshots
49-
pub fn intermediate_conda_outputs_snapshot<T>(
46+
pub async fn intermediate_conda_outputs<T>(
5047
project_model: Option<pixi_build_types::ProjectModelV1>,
5148
source_dir: Option<PathBuf>,
5249
host_platform: Platform,
5350
variant_configuration: Option<BTreeMap<String, Vec<String>>>,
5451
variant_files: Option<Vec<PathBuf>>,
55-
) -> String
52+
) -> CondaOutputsResult
5653
where
5754
T: GenerateRecipe + Default + Clone + Send + Sync + 'static,
5855
<T as GenerateRecipe>::Config: Send + Sync + 'static,
@@ -61,41 +58,35 @@ where
6158
Some(dir) => dir.join("pixi.toml"),
6259
None => PathBuf::from("pixi.toml"),
6360
};
64-
let runtime = tokio::runtime::Builder::new_current_thread()
65-
.build()
66-
.unwrap();
67-
runtime.block_on(async move {
68-
let (protocol, _result) = IntermediateBackendInstantiator::<T>::new(
69-
LoggingOutputHandler::default(),
70-
Arc::new(T::default()),
71-
)
72-
.initialize(InitializeParams {
73-
workspace_root: None,
74-
source_dir,
75-
manifest_path,
76-
project_model: project_model.map(Into::into),
77-
configuration: None,
78-
target_configuration: None,
79-
cache_directory: None,
80-
})
81-
.await
82-
.unwrap();
83-
84-
let current_dir = std::env::current_dir().unwrap();
85-
let result = protocol
86-
.conda_outputs(CondaOutputsParams {
87-
channels: vec![],
88-
host_platform,
89-
build_platform: host_platform,
90-
variant_configuration,
91-
variant_files,
92-
work_directory: current_dir,
93-
})
94-
.await
95-
.unwrap();
9661

97-
conda_outputs_snapshot(result)
62+
let (protocol, _result) = IntermediateBackendInstantiator::<T>::new(
63+
LoggingOutputHandler::default(),
64+
Arc::new(T::default()),
65+
)
66+
.initialize(InitializeParams {
67+
workspace_root: None,
68+
source_dir,
69+
manifest_path,
70+
project_model: project_model.map(Into::into),
71+
configuration: None,
72+
target_configuration: None,
73+
cache_directory: None,
9874
})
75+
.await
76+
.unwrap();
77+
78+
let current_dir = std::env::current_dir().unwrap();
79+
protocol
80+
.conda_outputs(CondaOutputsParams {
81+
channels: vec![],
82+
host_platform,
83+
build_platform: host_platform,
84+
variant_configuration,
85+
variant_files,
86+
work_directory: current_dir,
87+
})
88+
.await
89+
.unwrap()
9990
}
10091

10192
/// A function to convert a `CondaOutputsResult` into a pretty-printed JSON

crates/pixi-build-cmake/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,5 @@ tokio = { workspace = true, features = ["macros"] }
2626
insta = { workspace = true, features = ["yaml", "redactions", "filters"] }
2727
rstest = { workspace = true }
2828
strum = { workspace = true }
29+
tempfile = { workspace = true }
30+
fs-err = { workspace = true }

crates/pixi-build-cmake/src/main.rs

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,16 @@ mod tests {
156156
use std::path::PathBuf;
157157

158158
use indexmap::IndexMap;
159-
use pixi_build_backend::protocol::ProtocolInstantiator;
159+
use pixi_build_backend::{
160+
protocol::ProtocolInstantiator, utils::test::intermediate_conda_outputs,
161+
};
160162
use pixi_build_types::{
161163
ProjectModelV1,
162164
procedures::{conda_outputs::CondaOutputsParams, initialize::InitializeParams},
163165
};
164166
use rattler_build::console_utils::LoggingOutputHandler;
165167
use recipe_stage0::recipe::{Item, Value};
168+
use tokio::fs;
166169

167170
use super::*;
168171

@@ -396,6 +399,91 @@ mod tests {
396399
);
397400
}
398401

402+
#[tokio::test]
403+
async fn test_intermediate_conda_outputs_snapshot() {
404+
let project_model = project_fixture!({
405+
"name": "foobar",
406+
"version": "0.1.0",
407+
"targets": {
408+
"defaultTarget": {
409+
"buildDependencies": {
410+
"boltons": {
411+
"binary": {
412+
"version": "*"
413+
}
414+
}
415+
}
416+
},
417+
}
418+
});
419+
420+
let temp_dir = tempfile::tempdir().expect("Failed to create temp dir");
421+
422+
let variant_configuration =
423+
BTreeMap::from([("boltons".to_string(), Vec::from(["==1.0.0".to_string()]))]);
424+
425+
let result = intermediate_conda_outputs::<CMakeGenerator>(
426+
Some(project_model),
427+
Some(temp_dir.path().to_path_buf()),
428+
Platform::Linux64,
429+
Some(variant_configuration),
430+
None,
431+
)
432+
.await;
433+
434+
assert_eq!(result.outputs[0].metadata.variant["boltons"], "==1.0.0");
435+
assert_eq!(
436+
result.outputs[0].metadata.variant["target_platform"],
437+
"linux-64"
438+
);
439+
}
440+
441+
#[tokio::test]
442+
async fn test_variant_files_are_applied() {
443+
let project_model = project_fixture!({
444+
"name": "foobar",
445+
"version": "0.1.0",
446+
"targets": {
447+
"defaultTarget": {
448+
"buildDependencies": {
449+
"boltons": {
450+
"binary": {
451+
"version": "*"
452+
}
453+
}
454+
}
455+
},
456+
}
457+
});
458+
459+
let temp_dir = tempfile::tempdir().expect("Failed to create temp dir");
460+
461+
let variant_file = temp_dir.path().join("variants.yaml");
462+
fs::write(
463+
&variant_file,
464+
r#"boltons:
465+
- "==2.0.0"
466+
"#,
467+
)
468+
.await
469+
.expect("Failed to write variants file");
470+
471+
let result = intermediate_conda_outputs::<CMakeGenerator>(
472+
Some(project_model),
473+
Some(temp_dir.path().to_path_buf()),
474+
Platform::Linux64,
475+
None,
476+
Some(vec![variant_file]),
477+
)
478+
.await;
479+
480+
assert_eq!(result.outputs[0].metadata.variant["boltons"], "==2.0.0");
481+
assert_eq!(
482+
result.outputs[0].metadata.variant["target_platform"],
483+
"linux-64"
484+
);
485+
}
486+
399487
#[test]
400488
fn test_multiple_compilers_configuration() {
401489
let project_model = project_fixture!({

crates/pixi-build-python/src/main.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,12 @@ pub async fn main() {
272272

273273
#[cfg(test)]
274274
mod tests {
275+
use std::collections::BTreeMap;
276+
275277
use indexmap::IndexMap;
278+
use pixi_build_backend::utils::test::intermediate_conda_outputs;
276279
use recipe_stage0::recipe::{Item, Value};
280+
use tokio::fs;
277281

278282
use super::*;
279283

@@ -313,6 +317,129 @@ mod tests {
313317
};
314318
}
315319

320+
#[tokio::test]
321+
async fn test_intermediate_conda_outputs_snapshot() {
322+
let project_model = project_fixture!({
323+
"name": "foobar",
324+
"version": "0.1.0",
325+
"targets": {
326+
"defaultTarget": {
327+
"buildDependencies": {
328+
"boltons": {
329+
"binary": {
330+
"version": "*"
331+
}
332+
}
333+
}
334+
},
335+
}
336+
});
337+
338+
let temp_dir = tempfile::tempdir().expect("Failed to create temp dir");
339+
340+
fs::write(
341+
temp_dir.path().join("pyproject.toml"),
342+
r#"[project]
343+
name = "foobar"
344+
version = "0.1.0"
345+
"#,
346+
)
347+
.await
348+
.expect("Failed to write pyproject.toml");
349+
fs::write(
350+
temp_dir.path().join("pixi.toml"),
351+
r#"[project]
352+
name = "foobar"
353+
version = "0.1.0"
354+
"#,
355+
)
356+
.await
357+
.expect("Failed to write pixi.toml");
358+
359+
let variant_configuration =
360+
BTreeMap::from([("boltons".to_string(), Vec::from(["==1.0.0".to_string()]))]);
361+
362+
let result = intermediate_conda_outputs::<PythonGenerator>(
363+
Some(project_model),
364+
Some(temp_dir.path().to_path_buf()),
365+
Platform::Linux64,
366+
Some(variant_configuration),
367+
None,
368+
)
369+
.await;
370+
371+
assert_eq!(result.outputs[0].metadata.variant["boltons"], "==1.0.0");
372+
assert_eq!(
373+
result.outputs[0].metadata.variant["target_platform"],
374+
"noarch"
375+
);
376+
}
377+
378+
#[tokio::test]
379+
async fn test_variant_files_are_applied() {
380+
let project_model = project_fixture!({
381+
"name": "foobar",
382+
"version": "0.1.0",
383+
"targets": {
384+
"defaultTarget": {
385+
"buildDependencies": {
386+
"boltons": {
387+
"binary": {
388+
"version": "*"
389+
}
390+
}
391+
}
392+
},
393+
}
394+
});
395+
396+
let temp_dir = tempfile::tempdir().expect("Failed to create temp dir");
397+
398+
fs::write(
399+
temp_dir.path().join("pyproject.toml"),
400+
r#"[project]
401+
name = "foobar"
402+
version = "0.1.0"
403+
"#,
404+
)
405+
.await
406+
.expect("Failed to write pyproject.toml");
407+
fs::write(
408+
temp_dir.path().join("pixi.toml"),
409+
r#"[project]
410+
name = "foobar"
411+
version = "0.1.0"
412+
"#,
413+
)
414+
.await
415+
.expect("Failed to write pixi.toml");
416+
417+
let variant_file = temp_dir.path().join("variants.yaml");
418+
fs::write(
419+
&variant_file,
420+
r#"boltons:
421+
- "==2.0.0"
422+
"#,
423+
)
424+
.await
425+
.expect("Failed to write variants file");
426+
427+
let result = intermediate_conda_outputs::<PythonGenerator>(
428+
Some(project_model),
429+
Some(temp_dir.path().to_path_buf()),
430+
Platform::Linux64,
431+
None,
432+
Some(vec![variant_file]),
433+
)
434+
.await;
435+
436+
assert_eq!(result.outputs[0].metadata.variant["boltons"], "==2.0.0");
437+
assert_eq!(
438+
result.outputs[0].metadata.variant["target_platform"],
439+
"noarch"
440+
);
441+
}
442+
316443
#[test]
317444
fn test_pip_is_in_host_requirements() {
318445
let project_model = project_fixture!({

0 commit comments

Comments
 (0)