Skip to content

Commit 45a9b8d

Browse files
ctruedenclaude
andcommitted
Add PixiBuilder.environment() to select named pixi environments
Pixi supports multiple named environments in a single pixi.toml. Add a fluent `.environment(name)` method to PixiBuilder that maps to `pixi run --environment <name>` and resolves binPaths to `.pixi/envs/<name>/bin`. When not set, behavior is unchanged (no flag passed, bin path uses "default"). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 50e1151 commit 45a9b8d

3 files changed

Lines changed: 63 additions & 4 deletions

File tree

src/main/java/org/apposed/appose/builder/PixiBuilder.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,24 @@ public final class PixiBuilder extends BaseBuilder<PixiBuilder> {
5353

5454
private final List<String> condaPackages = new ArrayList<>();
5555
private final List<String> pypiPackages = new ArrayList<>();
56+
private String pixiEnvironment;
5657

5758
// -- PixiBuilder methods --
5859

60+
/**
61+
* Selects which pixi environment to activate within the manifest.
62+
* Pixi supports multiple named environments in a single {@code pixi.toml};
63+
* use this method to target one other than {@code "default"}.
64+
* Maps to {@code pixi run --environment <name>}.
65+
*
66+
* @param name The pixi environment name (e.g. {@code "cuda"}, {@code "cpu"}).
67+
* @return This builder instance, for fluent-style programming.
68+
*/
69+
public PixiBuilder environment(String name) {
70+
this.pixiEnvironment = name;
71+
return this;
72+
}
73+
5974
/**
6075
* Adds conda packages to the environment.
6176
*
@@ -256,16 +271,21 @@ public Environment wrap(File envDir) throws BuildException {
256271

257272
private Environment createEnvironment(Pixi pixi, File envDir) {
258273
String base = envDir.getAbsolutePath();
274+
String envName = pixiEnvironment != null ? pixiEnvironment : "default";
259275
// Check which manifest file exists (pyproject.toml takes precedence).
260276
File manifestFile = new File(envDir, "pyproject.toml");
261277
if (!manifestFile.exists()) manifestFile = new File(envDir, "pixi.toml");
262-
List<String> launchArgs = Arrays.asList(
278+
List<String> launchArgs = new ArrayList<>(Arrays.asList(
263279
pixi.command, "run", "--manifest-path",
264280
manifestFile.getAbsolutePath()
265-
);
281+
));
282+
if (pixiEnvironment != null) {
283+
launchArgs.add("--environment");
284+
launchArgs.add(pixiEnvironment);
285+
}
266286
List<String> binPaths = Collections.singletonList(
267-
envDir.toPath().resolve(".pixi").resolve("envs").resolve("default").resolve("bin").toString()
268-
);
287+
envDir.toPath().resolve(".pixi").resolve("envs").resolve(envName).resolve("bin").toString()
288+
);
269289
return createEnv(base, binPaths, launchArgs);
270290
}
271291
}

src/test/java/org/apposed/appose/builder/PixiBuilderTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@
3838
import java.io.File;
3939
import java.io.IOException;
4040
import java.net.URL;
41+
import java.util.List;
4142

43+
import static org.junit.jupiter.api.Assertions.assertEquals;
4244
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
4345
import static org.junit.jupiter.api.Assertions.assertThrows;
46+
import static org.junit.jupiter.api.Assertions.assertTrue;
4447

4548
/** End-to-end tests for {@link PixiBuilder}. */
4649
public class PixiBuilderTest extends TestBase {
@@ -193,6 +196,27 @@ public void testContentPixiToml() throws Exception {
193196
cowsayAndAssert(env, "toml!");
194197
}
195198

199+
/** Tests that {@code .environment()} selects a non-default pixi environment. */
200+
@Test
201+
public void testPixiEnvironmentSelection() throws Exception {
202+
Environment env = Appose
203+
.pixi("src/test/resources/envs/cowsay-multi-env.toml")
204+
.base("target/envs/pixi-multi-env")
205+
.environment("alt")
206+
.logDebug()
207+
.build();
208+
assertInstanceOf(PixiBuilder.class, env.builder());
209+
// Verify launch args include --environment alt.
210+
List<String> launchArgs = env.launchArgs();
211+
int idx = launchArgs.indexOf("--environment");
212+
assertTrue(idx >= 0, "launchArgs should contain --environment");
213+
assertEquals("alt", launchArgs.get(idx + 1));
214+
// Verify bin path resolves to the alt environment directory.
215+
assertTrue(env.binPaths().get(0).contains(File.separator + "alt" + File.separator),
216+
"binPaths should reference the alt environment");
217+
cowsayAndAssert(env, "multi-env");
218+
}
219+
196220
/** Tests building from a file:// URL to exercise URL support. */
197221
@Test
198222
public void testURLSupport() throws Exception {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[project]
2+
name = "appose-cowsay-multi-env"
3+
channels = ["conda-forge"]
4+
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]
5+
6+
[dependencies]
7+
python = ">=3.8"
8+
pip = "*"
9+
10+
[pypi-dependencies]
11+
cowsay = "==6.1"
12+
appose = "*"
13+
14+
[environments]
15+
alt = { features = ["default"] }

0 commit comments

Comments
 (0)