Skip to content

Commit c71c36e

Browse files
committed
feat: build source dependencies in conda-script tool.pixi tables
`--experimental` implies the pixi-build preview for conda-script files, so a git, path or url spec under `[tool.pixi.dependencies]` builds without further opt-in. The integration test covers the union shape nothing tested before: a binary spec in one feature and a source spec in another reach the solver together, the source provides the candidate and the version constrains it. A corpus example demonstrates the same shape end to end.
1 parent 38212f8 commit c71c36e

3 files changed

Lines changed: 67 additions & 0 deletions

File tree

crates/pixi_conda_script/src/manifest.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,15 @@ impl CondaScriptManifest {
134134
"platforms",
135135
toml_edit::Item::Value(toml_edit::Value::Array(toml_edit::Array::new())),
136136
);
137+
// Running a conda-script is already gated behind `--experimental`,
138+
// which implies the pixi-build preview so source dependencies under
139+
// `[tool.pixi.dependencies]` build without further opt-in.
140+
let mut preview = toml_edit::Array::new();
141+
preview.push("pixi-build");
142+
workspace.insert(
143+
"preview",
144+
toml_edit::Item::Value(toml_edit::Value::Array(preview)),
145+
);
137146
document.insert("workspace", toml_edit::Item::Table(workspace));
138147

139148
if let Some(dependencies) = dependencies {
@@ -438,6 +447,7 @@ mod tests {
438447
name = "example"
439448
channels = ["conda-forge"]
440449
platforms = []
450+
preview = ["pixi-build"]
441451
442452
[dependencies]
443453
python = "3.13.*"
@@ -472,6 +482,7 @@ mod tests {
472482
name = "example"
473483
channels = ["conda-forge"]
474484
platforms = []
485+
preview = ["pixi-build"]
475486
"#);
476487
}
477488

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# /// conda-script
2+
# channels = ["conda-forge"]
3+
# entrypoint = "python ${SCRIPT}"
4+
#
5+
# [dependencies]
6+
# python = "3.13.*"
7+
# simple-app = "0.1.*"
8+
#
9+
# [tool.pixi.dependencies]
10+
# simple-app = { git = "https://github.com/prefix-dev/pixi-build-testsuite.git", subdirectory = "tests/data/pixi_build/minimal-backend-workspaces/pixi-build-python" }
11+
# /// end-conda-script
12+
"""A source dependency, built from git by pixi-build.
13+
14+
The binary spec in `[dependencies]` keeps the script solvable for tools that
15+
only implement the conda-script specification, while the source spec under
16+
`[tool.pixi.dependencies]` provides the candidate pixi actually builds. Both
17+
specs reach the solver, so the version constrains the built package.
18+
"""
19+
20+
import simple_app
21+
22+
simple_app.main()

tests/integration_python/test_conda_script.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,40 @@ def test_a_failing_entrypoint_propagates_its_exit_code(
228228
assert not (tmp_pixi_workspace / "marker").exists()
229229

230230

231+
SOURCE_DEPENDENCY_BLOCK = f"""# /// conda-script
232+
# channels = ["{CONDA_FORGE_CHANNEL}"]
233+
# entrypoint = "simple-app"
234+
#
235+
# [dependencies]
236+
# simple-app = "{{version}}"
237+
#
238+
# [tool.pixi.dependencies]
239+
# simple-app = {{{{ git = "https://github.com/prefix-dev/pixi-build-testsuite.git", subdirectory = "tests/data/pixi_build/minimal-backend-workspaces/pixi-build-python" }}}}
240+
# /// end-conda-script
241+
"""
242+
243+
244+
@pytest.mark.slow
245+
def test_a_binary_spec_constrains_a_source_dependency(pixi: Path, tmp_pixi_workspace: Path) -> None:
246+
"""Both features' specs reach the solver as a union: the source spec in
247+
`[tool.pixi.dependencies]` provides the candidate and the binary spec in
248+
`[dependencies]` constrains its version."""
249+
script = tmp_pixi_workspace / "source.code"
250+
script.write_text(SOURCE_DEPENDENCY_BLOCK.format(version="0.1.*"))
251+
252+
verify_cli_command(
253+
[pixi, "run", "--experimental", "--script", script],
254+
stdout_contains="Build backend works",
255+
)
256+
257+
script.write_text(SOURCE_DEPENDENCY_BLOCK.format(version="0.2.*"))
258+
verify_cli_command(
259+
[pixi, "run", "--experimental", "--script", script],
260+
ExitCode.FAILURE,
261+
stderr_contains="0.2",
262+
)
263+
264+
231265
@pytest.mark.slow
232266
def test_lock_writes_an_adjacent_lock_file_with_conditional_dependencies(
233267
pixi: Path, tmp_pixi_workspace: Path

0 commit comments

Comments
 (0)