mirror of
https://github.com/processing/processing4.git
synced 2026-02-16 11:55:38 +01:00
392 lines
13 KiB
Java
392 lines
13 KiB
Java
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
|
|
/*
|
|
Part of the Processing project - http://processing.org
|
|
|
|
Copyright (c) 2008-12 Ben Fry and Casey Reas
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
package processing.mode.java;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.PrintStream;
|
|
import java.io.UnsupportedEncodingException;
|
|
|
|
import processing.app.*;
|
|
import processing.app.contrib.ModeContribution;
|
|
import processing.core.PApplet;
|
|
import processing.mode.java.runner.*;
|
|
|
|
|
|
/**
|
|
* Class to handle running Processing from the command line.
|
|
*
|
|
* @author fry
|
|
*/
|
|
public class Commander implements RunnerListener {
|
|
static final String helpArg = "--help";
|
|
// static final String preprocArg = "--preprocess";
|
|
static final String buildArg = "--build";
|
|
static final String runArg = "--run";
|
|
static final String presentArg = "--present";
|
|
static final String sketchArg = "--sketch=";
|
|
static final String forceArg = "--force";
|
|
static final String outputArg = "--output=";
|
|
static final String exportApplicationArg = "--export";
|
|
static final String noJavaArg = "--no-java";
|
|
static final String platformArg = "--platform=";
|
|
static final String bitsArg = "--bits=";
|
|
// static final String preferencesArg = "--preferences=";
|
|
|
|
static final int HELP = -1;
|
|
static final int PREPROCESS = 0;
|
|
static final int BUILD = 1;
|
|
static final int RUN = 2;
|
|
static final int PRESENT = 3;
|
|
// static final int EXPORT_APPLET = 4;
|
|
static final int EXPORT = 4;
|
|
|
|
Sketch sketch;
|
|
|
|
PrintStream systemOut;
|
|
PrintStream systemErr;
|
|
|
|
|
|
static public void main(String[] args) {
|
|
// Do this early so that error messages go to the console
|
|
Base.setCommandLine();
|
|
// init the platform so that prefs and other native code is ready to go
|
|
Base.initPlatform();
|
|
// make sure a full JDK is installed
|
|
Base.initRequirements();
|
|
|
|
// launch command line handler
|
|
new Commander(args);
|
|
}
|
|
|
|
|
|
public Commander(String[] args) {
|
|
String sketchPath = null;
|
|
File sketchFolder = null;
|
|
String pdePath = null; // path to the .pde file
|
|
String outputPath = null;
|
|
File outputFolder = null;
|
|
boolean force = false; // replace that no good output folder
|
|
// String preferencesPath = null;
|
|
int platform = PApplet.platform; // default to this platform
|
|
// int platformBits = 0;
|
|
int platformBits = Base.getNativeBits();
|
|
int task = HELP;
|
|
boolean embedJava = true;
|
|
|
|
// Turns out the output goes as MacRoman or something else useless.
|
|
// http://code.google.com/p/processing/issues/detail?id=1418
|
|
try {
|
|
systemOut = new PrintStream(System.out, true, "UTF-8");
|
|
systemErr = new PrintStream(System.err, true, "UTF-8");
|
|
|
|
} catch (UnsupportedEncodingException e) {
|
|
e.printStackTrace();
|
|
System.exit(1);
|
|
}
|
|
|
|
// File preferencesFile = Base.getSettingsFile("preferences.txt");
|
|
// System.out.println("Preferences file at " + preferencesFile.getAbsolutePath());
|
|
|
|
for (String arg : args) {
|
|
if (arg.length() == 0) {
|
|
// ignore it, just the crappy shell script
|
|
|
|
} else if (arg.equals(helpArg)) {
|
|
// mode already set to HELP
|
|
|
|
// } else if (arg.equals(preprocArg)) {
|
|
// task = PREPROCESS;
|
|
|
|
} else if (arg.equals(buildArg)) {
|
|
task = BUILD;
|
|
|
|
} else if (arg.equals(runArg)) {
|
|
task = RUN;
|
|
|
|
} else if (arg.equals(presentArg)) {
|
|
task = PRESENT;
|
|
|
|
// } else if (arg.equals(exportAppletArg)) {
|
|
// task = EXPORT_APPLET;
|
|
|
|
} else if (arg.equals(exportApplicationArg)) {
|
|
task = EXPORT;
|
|
|
|
} else if (arg.equals(noJavaArg)) {
|
|
embedJava = false;
|
|
|
|
} else if (arg.startsWith(platformArg)) {
|
|
complainAndQuit("The --platform option has been removed from Processing 2.1.", false);
|
|
// String platformStr = arg.substring(platformArg.length());
|
|
// platform = Base.getPlatformIndex(platformStr);
|
|
// if (platform == -1) {
|
|
// complainAndQuit(platformStr + " should instead be " +
|
|
// "'windows', 'macosx', or 'linux'.", true);
|
|
// }
|
|
|
|
} else if (arg.startsWith(bitsArg)) {
|
|
complainAndQuit("The --bits option has been removed from Processing 2.1.", false);
|
|
// String bitsStr = arg.substring(bitsArg.length());
|
|
// if (bitsStr.equals("32")) {
|
|
// platformBits = 32;
|
|
// } else if (bitsStr.equals("64")) {
|
|
// platformBits = 64;
|
|
// } else {
|
|
// complainAndQuit("Bits should be either 32 or 64, not " + bitsStr, true);
|
|
// }
|
|
|
|
} else if (arg.startsWith(sketchArg)) {
|
|
sketchPath = arg.substring(sketchArg.length());
|
|
sketchFolder = new File(sketchPath);
|
|
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();
|
|
|
|
// } else if (arg.startsWith(preferencesArg)) {
|
|
// preferencesPath = arg.substring(preferencesArg.length());
|
|
|
|
} else if (arg.startsWith(outputArg)) {
|
|
outputPath = arg.substring(outputArg.length());
|
|
|
|
} else if (arg.equals(forceArg)) {
|
|
force = true;
|
|
|
|
} else {
|
|
complainAndQuit("I don't know anything about " + arg + ".", true);
|
|
}
|
|
}
|
|
|
|
// if ((outputPath == null) &&
|
|
// (task == PREPROCESS || task == BUILD ||
|
|
// task == RUN || task == PRESENT)) {
|
|
// complainAndQuit("An output path must be specified when using " +
|
|
// preprocArg + ", " + buildArg + ", " +
|
|
// runArg + ", or " + presentArg + ".");
|
|
// }
|
|
if (task == HELP) {
|
|
printCommandLine(systemOut);
|
|
System.exit(0);
|
|
}
|
|
|
|
if (outputPath == null) {
|
|
complainAndQuit("An output path must be specified.", true);
|
|
}
|
|
|
|
outputFolder = new File(outputPath);
|
|
if (outputFolder.exists()) {
|
|
if (force) {
|
|
Base.removeDir(outputFolder);
|
|
} else {
|
|
complainAndQuit("The output folder already exists. " +
|
|
"Use --force to remove it.", false);
|
|
}
|
|
}
|
|
|
|
if (!outputFolder.mkdirs()) {
|
|
complainAndQuit("Could not create the output folder.", false);
|
|
}
|
|
|
|
// // run static initialization that grabs all the prefs
|
|
// // (also pass in a prefs path if that was specified)
|
|
// if (preferencesPath != null) {
|
|
// Preferences.init(preferencesPath);
|
|
// }
|
|
|
|
Preferences.init();
|
|
Base.locateSketchbookFolder();
|
|
|
|
if (sketchPath == null) {
|
|
complainAndQuit("No sketch path specified.", true);
|
|
|
|
} else if (outputPath.equals(sketchPath)) {
|
|
complainAndQuit("The sketch path and output path cannot be identical.", false);
|
|
|
|
// } else if (!pdePath.toLowerCase().endsWith(".pde")) {
|
|
// complainAndQuit("Sketch path must point to the main .pde file.", false);
|
|
|
|
} else {
|
|
boolean success = false;
|
|
|
|
// JavaMode javaMode =
|
|
// new JavaMode(null, Base.getContentFile("modes/java"));
|
|
JavaMode javaMode = (JavaMode)
|
|
ModeContribution.load(null, Base.getContentFile("modes/java"),
|
|
"processing.mode.java.JavaMode").getMode();
|
|
try {
|
|
sketch = new Sketch(pdePath, javaMode);
|
|
if (task == BUILD || task == RUN || task == PRESENT) {
|
|
JavaBuild build = new JavaBuild(sketch);
|
|
File srcFolder = new File(outputFolder, "source");
|
|
String className = build.build(srcFolder, outputFolder, true);
|
|
// String className = build.build(sketchFolder, outputFolder, true);
|
|
if (className != null) {
|
|
success = true;
|
|
if (task == RUN || task == PRESENT) {
|
|
Runner runner = new Runner(build, this);
|
|
runner.launch(task == PRESENT);
|
|
}
|
|
} else {
|
|
success = false;
|
|
}
|
|
|
|
} else if (task == EXPORT) {
|
|
if (outputPath == null) {
|
|
javaMode.handleExportApplication(sketch);
|
|
} else {
|
|
JavaBuild build = new JavaBuild(sketch);
|
|
build.build(true);
|
|
if (build != null) {
|
|
// if (platformBits == 0) {
|
|
// platformBits = Base.getNativeBits();
|
|
// }
|
|
// if (platformBits == 0 &&
|
|
// Library.hasMultipleArch(platform, build.getImportedLibraries())) {
|
|
// complainAndQuit("This sketch can be exported for 32- or 64-bit, please specify one.", true);
|
|
// }
|
|
success = build.exportApplication(outputFolder, platform, platformBits, embedJava);
|
|
}
|
|
}
|
|
}
|
|
if (!success) { // error already printed
|
|
System.exit(1);
|
|
}
|
|
systemOut.println("Finished.");
|
|
System.exit(0);
|
|
|
|
} catch (SketchException re) {
|
|
statusError(re);
|
|
System.exit(1);
|
|
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
System.exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void statusNotice(String message) {
|
|
systemErr.println(message);
|
|
}
|
|
|
|
|
|
public void statusError(String message) {
|
|
systemErr.println(message);
|
|
}
|
|
|
|
|
|
public void statusError(Exception exception) {
|
|
if (exception instanceof SketchException) {
|
|
SketchException re = (SketchException) exception;
|
|
|
|
int codeIndex = re.getCodeIndex();
|
|
if (codeIndex != -1) {
|
|
// format the runner exception like emacs
|
|
//blah.java:2:10:2:13: Syntax Error: This is a big error message
|
|
// Emacs doesn't like the double line thing coming from Java
|
|
// https://github.com/processing/processing/issues/2158
|
|
String filename = sketch.getCode(codeIndex).getFileName();
|
|
int line = re.getCodeLine() + 1;
|
|
int column = re.getCodeColumn() + 1;
|
|
//if (column == -1) column = 0;
|
|
// TODO if column not specified, should just select the whole line.
|
|
// But what's the correct syntax for that?
|
|
systemErr.println(filename + ":" +
|
|
line + ":" + column + ":" +
|
|
line + ":" + column + ":" + " " + re.getMessage());
|
|
|
|
} else { // no line number, pass the trace along to the user
|
|
exception.printStackTrace();
|
|
}
|
|
} else {
|
|
exception.printStackTrace();
|
|
}
|
|
}
|
|
|
|
|
|
void complainAndQuit(String lastWords, boolean schoolEmFirst) {
|
|
if (schoolEmFirst) {
|
|
printCommandLine(systemErr);
|
|
}
|
|
systemErr.println(lastWords);
|
|
System.exit(1);
|
|
}
|
|
|
|
|
|
static void printCommandLine(PrintStream out) {
|
|
out.println();
|
|
out.println("Command line edition for Processing " + Base.getVersionName() + " (Java Mode)");
|
|
out.println();
|
|
out.println("--help Show this help text. Congratulations.");
|
|
out.println();
|
|
out.println("--sketch=<name> Specify the sketch folder (required)");
|
|
out.println("--output=<name> Specify the output folder (required and");
|
|
out.println(" cannot be the same as the sketch folder.)");
|
|
out.println();
|
|
out.println("--force The sketch will not build if the output");
|
|
out.println(" folder already exists, because the contents");
|
|
out.println(" will be replaced. This option erases the");
|
|
out.println(" folder first. Use with extreme caution!");
|
|
out.println();
|
|
out.println("--build Preprocess and compile a sketch into .class files.");
|
|
out.println("--run Preprocess, compile, and run a sketch.");
|
|
out.println("--present Preprocess, compile, and run a sketch full screen.");
|
|
out.println();
|
|
out.println("--export Export an application.");
|
|
out.println("--no-java Do not embed Java. Use at your own risk!");
|
|
// out.println("--platform Specify the platform (export to application only).");
|
|
// out.println(" Should be one of 'windows', 'macosx', or 'linux'.");
|
|
// out.println("--bits Must be specified if libraries are used that are");
|
|
// out.println(" 32- or 64-bit specific such as the OpenGL library.");
|
|
// out.println(" Otherwise specify 0 or leave it out.");
|
|
out.println();
|
|
}
|
|
|
|
|
|
@Override
|
|
public void startIndeterminate() {
|
|
}
|
|
|
|
|
|
@Override
|
|
public void stopIndeterminate() {
|
|
}
|
|
|
|
|
|
@Override
|
|
public void statusHalt() {
|
|
}
|
|
|
|
|
|
@Override
|
|
public boolean isHalted() {
|
|
return false;
|
|
}
|
|
}
|