Skip to content

Commit 634b159

Browse files
committed
Work toward alignment with Python implementation
See also apposed/appose-python@bd7b13f.
1 parent 71280aa commit 634b159

File tree

8 files changed

+52
-108
lines changed

8 files changed

+52
-108
lines changed

src/main/java/org/apposed/appose/Builder.java

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -204,31 +204,31 @@ default T channels(String... channels) {
204204
T channels(List<String> channels);
205205

206206
/**
207-
* Specifies a configuration file to build from.
207+
* Specifies a configuration file path to build from.
208208
* Reads the file content immediately and delegates to {@link #content(String)}.
209209
*
210-
* @param file Configuration file (e.g., pixi.toml, environment.yml)
210+
* @param path Path to configuration file (e.g., "pixi.toml", "environment.yml")
211211
* @return This builder instance, for fluent-style programming.
212-
* @throws BuildException If the file cannot be read
212+
* @throws BuildException If the file cannot be read or is invalid
213213
*/
214-
default T file(File file) throws BuildException {
215-
return file(file.getAbsolutePath());
214+
default T file(String path) throws BuildException {
215+
return file(new File(path));
216216
}
217217

218218
/**
219-
* Specifies a configuration file path to build from.
219+
* Specifies a configuration file to build from.
220220
* Reads the file content immediately and delegates to {@link #content(String)}.
221221
*
222-
* @param path Path to configuration file (e.g., "pixi.toml", "environment.yml")
222+
* @param file Configuration file (e.g., pixi.toml, environment.yml)
223223
* @return This builder instance, for fluent-style programming.
224-
* @throws BuildException If the file cannot be read or is invalid
224+
* @throws BuildException If the file cannot be read
225225
*/
226-
default T file(String path) throws BuildException {
226+
default T file(File file) throws BuildException {
227227
try {
228-
Path filePath = Paths.get(path);
228+
Path filePath = file.toPath();
229229
String fileContent = new String(
230-
Files.readAllBytes(filePath),
231-
StandardCharsets.UTF_8
230+
Files.readAllBytes(filePath),
231+
StandardCharsets.UTF_8
232232
);
233233
return content(fileContent);
234234
}
@@ -237,6 +237,23 @@ default T file(String path) throws BuildException {
237237
}
238238
}
239239

240+
/**
241+
* Specifies a URL to fetch configuration content from.
242+
* Reads the URL content immediately and delegates to {@link #content(String)}.
243+
*
244+
* @param path URL path of configuration file
245+
* @return This builder instance, for fluent-style programming.
246+
* @throws BuildException If the URL cannot be read or is invalid
247+
*/
248+
default T url(String path) throws BuildException {
249+
try {
250+
return url(new URL(path));
251+
}
252+
catch (MalformedURLException e) {
253+
throw new BuildException(this, e);
254+
}
255+
}
256+
240257
/**
241258
* Specifies a URL to fetch configuration content from.
242259
* Reads the URL content immediately and delegates to {@link #content(String)}.
@@ -260,23 +277,6 @@ default T url(URL url) throws BuildException {
260277
}
261278
}
262279

263-
/**
264-
* Specifies a URL to fetch configuration content from.
265-
* Reads the URL content immediately and delegates to {@link #content(String)}.
266-
*
267-
* @param path URL path of configuration file
268-
* @return This builder instance, for fluent-style programming.
269-
* @throws BuildException If the URL cannot be read or is invalid
270-
*/
271-
default T url(String path) throws BuildException {
272-
try {
273-
return url(new URL(path));
274-
}
275-
catch (MalformedURLException e) {
276-
throw new BuildException(this, e);
277-
}
278-
}
279-
280280
/**
281281
* Specifies configuration file content to build from.
282282
* The scheme will be auto-detected from content syntax.

src/main/java/org/apposed/appose/TaskException.java

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,37 +42,10 @@
4242
*/
4343
public class TaskException extends Exception {
4444

45-
private final Task task;
45+
public final Task task;
4646

4747
public TaskException(String message, Task task) {
4848
super(message);
4949
this.task = task;
5050
}
51-
52-
/**
53-
* Returns the task that failed.
54-
*
55-
* @return The task associated with this exception.
56-
*/
57-
public Task getTask() {
58-
return task;
59-
}
60-
61-
/**
62-
* Returns the status of the failed task.
63-
*
64-
* @return The task's status (FAILED, CANCELED, or CRASHED).
65-
*/
66-
public TaskStatus getStatus() {
67-
return task.status;
68-
}
69-
70-
/**
71-
* Returns the error message from the task, if available.
72-
*
73-
* @return The task's error message, or null if none was set.
74-
*/
75-
public @Nullable String getTaskError() {
76-
return task.error;
77-
}
7851
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@
5555
*/
5656
public abstract class BaseBuilder<T extends BaseBuilder<T>> implements Builder<T> {
5757

58-
public final List<ProgressConsumer> progressSubscribers = new ArrayList<>();
59-
public final List<Consumer<String>> outputSubscribers = new ArrayList<>();
60-
public final List<Consumer<String>> errorSubscribers = new ArrayList<>();
61-
public final Map<String, String> envVars = new HashMap<>();
62-
public final List<String> channels = new ArrayList<>();
63-
public final List<String> flags = new ArrayList<>();
58+
protected final List<ProgressConsumer> progressSubscribers = new ArrayList<>();
59+
protected final List<Consumer<String>> outputSubscribers = new ArrayList<>();
60+
protected final List<Consumer<String>> errorSubscribers = new ArrayList<>();
61+
protected final Map<String, String> envVars = new HashMap<>();
62+
protected final List<String> channels = new ArrayList<>();
63+
protected final List<String> flags = new ArrayList<>();
6464
protected String envName;
6565
protected File envDir;
6666

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

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,6 @@ public String envType() {
5757
return "mamba";
5858
}
5959

60-
/**
61-
* Adds conda channels to search for packages.
62-
*
63-
* @param channels Channel names (e.g., "conda-forge", "bioconda")
64-
* @return This builder instance, for fluent-style programming.
65-
*/
66-
@Override
67-
public MambaBuilder channels(String... channels) {
68-
return super.channels(channels);
69-
}
70-
7160
@Override
7261
public Environment build() throws BuildException {
7362
File envDir = resolveEnvDir();
@@ -80,11 +69,14 @@ public Environment build() throws BuildException {
8069
throw new BuildException(this, "Cannot use MambaBuilder: environment already managed by uv/venv at " + envDir);
8170
}
8271

72+
// Create Mamba tool instance early so it's available for wrapping.
73+
Mamba mamba = new Mamba();
74+
8375
// Is this envDir an already-existing conda directory?
8476
boolean isCondaDir = new File(envDir, "conda-meta").isDirectory();
8577
if (isCondaDir) {
8678
// Environment already exists, just wrap it.
87-
return createEnvironment(envDir);
79+
return createEnvironment(mamba, envDir);
8880
}
8981

9082
// Building a new environment - config content is required.
@@ -99,8 +91,6 @@ public Environment build() throws BuildException {
9991
throw new IllegalArgumentException("MambaBuilder only supports environment.yml scheme, got: " + scheme);
10092
}
10193

102-
Mamba mamba = new Mamba();
103-
10494
// Set up progress/output consumers.
10595
mamba.setOutputConsumer(msg -> outputSubscribers.forEach(sub -> sub.accept(msg)));
10696
mamba.setErrorConsumer(msg -> errorSubscribers.forEach(sub -> sub.accept(msg)));
@@ -133,7 +123,7 @@ public Environment build() throws BuildException {
133123
// Step 3: Update environment from yml.
134124
mamba.update(envDir, envYaml);
135125

136-
return createEnvironment(envDir);
126+
return createEnvironment(mamba, envDir);
137127
}
138128
catch (IOException | InterruptedException e) {
139129
throw new BuildException(this, e);
@@ -161,8 +151,7 @@ public Environment wrap(File envDir) throws BuildException {
161151
return build();
162152
}
163153

164-
private Environment createEnvironment(File envDir) {
165-
Mamba mamba = new Mamba();
154+
private Environment createEnvironment(Mamba mamba, File envDir) {
166155
String base = envDir.getAbsolutePath();
167156
List<String> launchArgs = Arrays.asList(mamba.command, "run", "-p", base);
168157
List<String> binPaths = Collections.singletonList(envDir.toPath().resolve("bin").toString());

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

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,6 @@ public Environment wrap(File envDir) throws BuildException {
246246
return build();
247247
}
248248

249-
/**
250-
* Adds conda channels to search for packages.
251-
*
252-
* @param channels Channel names (e.g.: {@code "conda-forge", "bioconda"})
253-
* @return This builder instance, for fluent-style programming.
254-
*/
255-
@Override
256-
public PixiBuilder channels(String... channels) {
257-
return super.channels(channels);
258-
}
259-
260249
// -- Helper methods --
261250

262251
private Environment createEnvironment(Pixi pixi, File envDir) {

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -222,18 +222,6 @@ public Environment wrap(File envDir) throws BuildException {
222222
return build();
223223
}
224224

225-
/**
226-
* Adds PyPI index URLs for package discovery.
227-
* These are alternative or additional package indexes beyond the default pypi.org.
228-
*
229-
* @param indexes Index URLs (e.g., custom PyPI mirrors or private package repositories)
230-
* @return This builder instance, for fluent-style programming.
231-
*/
232-
@Override
233-
public UvBuilder channels(String... indexes) {
234-
return super.channels(indexes);
235-
}
236-
237225
// -- Helper methods --
238226

239227
private Environment createEnvironment(File envDir) {

src/test/java/org/apposed/appose/DumpApi.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public class DumpApi {
7373
// Core API classes.
7474
PACKAGE_TO_MODULE.put("org.apposed.appose.Appose", "appose/__init__.api");
7575
PACKAGE_TO_MODULE.put("org.apposed.appose.Environment", "appose/environment.api");
76+
PACKAGE_TO_MODULE.put("org.apposed.appose.TaskException", "appose/service.api");
7677
PACKAGE_TO_MODULE.put("org.apposed.appose.Service", "appose/service.api");
7778
PACKAGE_TO_MODULE.put("org.apposed.appose.Service.Task", "appose/service.api");
7879
PACKAGE_TO_MODULE.put("org.apposed.appose.Service.TaskStatus", "appose/service.api");
@@ -86,7 +87,11 @@ public class DumpApi {
8687
PACKAGE_TO_MODULE.put("org.apposed.appose.SharedMemory", "appose/shm.api");
8788

8889
// Subsystem packages - all classes in package go to same file.
89-
PACKAGE_TO_MODULE.put("org.apposed.appose.scheme", "appose/scheme.api");
90+
PACKAGE_TO_MODULE.put("org.apposed.appose.Scheme", "appose/scheme.api");
91+
PACKAGE_TO_MODULE.put("org.apposed.appose.scheme.PixiTomlScheme", "appose/scheme.api");
92+
PACKAGE_TO_MODULE.put("org.apposed.appose.scheme.EnvironmentYmlScheme", "appose/scheme.api");
93+
PACKAGE_TO_MODULE.put("org.apposed.appose.scheme.PyProjectTomlScheme", "appose/scheme.api");
94+
PACKAGE_TO_MODULE.put("org.apposed.appose.scheme.RequirementsTxtScheme", "appose/scheme.api");
9095
PACKAGE_TO_MODULE.put("org.apposed.appose.scheme.Schemes", "appose/scheme.api");
9196
PACKAGE_TO_MODULE.put("org.apposed.appose.shm.Shms", "appose/shm.api");
9297
PACKAGE_TO_MODULE.put("org.apposed.appose.syntax", "appose/syntax.api");

src/test/java/org/apposed/appose/TaskExceptionTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ public void testTaskExceptionOnFailure() throws Exception {
6363
assertTrue(e.getMessage().contains("NameError"));
6464

6565
// Verify we can access the task and its details through the exception.
66-
assertSame(task, e.getTask());
67-
assertEquals(TaskStatus.FAILED, e.getStatus());
68-
assertNotNull(e.getTaskError());
69-
assertTrue(e.getTaskError().contains("NameError"));
66+
assertSame(task, e.task);
67+
assertEquals(TaskStatus.FAILED, e.task.status);
68+
assertNotNull(e.task.error);
69+
assertTrue(e.task.error.contains("NameError"));
7070
}
7171
}
7272
}

0 commit comments

Comments
 (0)