Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 49 additions & 5 deletions java/src/processing/mode/java/Commander.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.util.Locale;

import processing.app.Base;
import processing.app.Platform;
Expand All @@ -51,6 +54,7 @@ public class Commander implements RunnerListener {
static final String runArg = "--run";
static final String presentArg = "--present";
static final String sketchArg = "--sketch=";
static final String mainArg = "--main=";
static final String forceArg = "--force";
static final String outputArg = "--output=";
static final String exportApplicationArg = "--export";
Expand All @@ -77,6 +81,7 @@ public Commander(String[] args) {
String sketchPath = null;
File sketchFolder = null;
String pdePath = null; // path to the .pde file
String mainFilename = null; // custom main .pde file (optional)
String outputPath = null;
File outputFolder = null;
boolean outputSet = false; // set an output folder
Expand Down Expand Up @@ -145,15 +150,15 @@ public Commander(String[] args) {
if (!sketchFolder.exists()) {
complainAndQuit(sketchFolder + " does not exist.", false);
}
File pdeFile = new File(sketchFolder, sketchFolder.getName() + ".pde");
if (!pdeFile.exists()) {
complainAndQuit("Not a valid sketch folder. " + pdeFile + " does not exist.", true);
}
pdePath = pdeFile.getAbsolutePath();
// Will be set later after checking for --main argument
// or default to folder name convention

// } else if (arg.startsWith(preferencesArg)) {
// preferencesPath = arg.substring(preferencesArg.length());

} else if (arg.startsWith(mainArg)) {
mainFilename = arg.substring(mainArg.length());

} else if (arg.startsWith(outputArg)) {
outputSet = true;
outputPath = arg.substring(outputArg.length());
Expand Down Expand Up @@ -208,6 +213,42 @@ public Commander(String[] args) {
// complainAndQuit("Sketch path must point to the main .pde file.", false);

} else {
// Determine the main .pde file to use
File pdeFile;
if (mainFilename != null) {
// Validate file extension first (fail fast)
int dotIndex = mainFilename.lastIndexOf('.');
if (dotIndex == -1 || dotIndex == mainFilename.length() - 1) {
// No extension or dot at end (e.g., "file" or "file.")
complainAndQuit("The main file must be a .pde file.", true);
}
String extension = mainFilename.substring(dotIndex + 1).toLowerCase(Locale.ENGLISH);
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The file extension validation logic should be extracted into a separate method to improve readability and reusability. Consider creating a validatePdeExtension(String filename) helper method.

Copilot uses AI. Check for mistakes.

if (!extension.equals("pde")) {
complainAndQuit("The main file must be a .pde file.", true);
}

// User specified a custom main file with --main
pdeFile = new File(sketchFolder, mainFilename);
try {
Path pdeFilePath = pdeFile.toPath().toRealPath(LinkOption.NOFOLLOW_LINKS);
Path sketchFolderPath = sketchFolder.toPath().toRealPath(LinkOption.NOFOLLOW_LINKS);
if (!pdeFilePath.startsWith(sketchFolderPath)) {
complainAndQuit("The main file must be inside the sketch folder.", true);
}
} catch (IOException e) {
complainAndQuit("Could not resolve real path for main file or sketch folder: " + e.getMessage(), true);
}
if (!pdeFile.exists()) {
complainAndQuit("The main file does not exist: " + pdeFile.getAbsolutePath(), true);
}
} else {
// Default behavior: look for <foldername>.pde
pdeFile = new File(sketchFolder, sketchFolder.getName() + ".pde");
if (!pdeFile.exists()) {
complainAndQuit("Not a valid sketch folder. " + pdeFile + " does not exist.", true);
}
}
pdePath = pdeFile.getAbsolutePath();

if (outputSet) {
if (outputPath.equals(sketchPath)) {
Expand Down Expand Up @@ -331,6 +372,9 @@ static void printCommandLine(PrintStream out) {
out.println("--help Show this help text. Congratulations.");
out.println();
out.println("--sketch=<name> Specify the sketch folder (required)");
out.println("--main=<file> Specify the main .pde file if not using the default");
out.println(" naming convention (optional). The file should be");
out.println(" inside the sketch folder, e.g. --main=MySketch.pde");
out.println("--output=<name> Specify the output folder (optional and");
out.println(" cannot be the same as the sketch folder.)");
out.println();
Expand Down