groovy.ui.GroovyMain.orig Maven / Gradle / Ivy
/*
* Copyright 2003-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package groovy.ui;
import groovy.lang.Binding;
import groovy.lang.GroovyRuntimeException;
import groovy.lang.GroovyShell;
import groovy.lang.GroovySystem;
import groovy.lang.MissingMethodException;
import groovy.lang.Script;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GroovyPosixParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.InvokerInvocationException;
import org.codehaus.groovy.runtime.ResourceGroovyMethods;
import org.codehaus.groovy.runtime.StackTraceUtils;
import java.io.*;
import java.math.BigInteger;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
/**
* A Command line to execute groovy.
*
* @author Jeremy Rayner
* @author Yuri Schimke
* @author Roshan Dawrani
* @version $Revision$
*/
public class GroovyMain {
// arguments to the script
private List args;
// is this a file on disk
private boolean isScriptFile;
// filename or content of script
private String script;
// process args as input files
private boolean processFiles;
// edit input files in place
private boolean editFiles;
// automatically output the result of each script
private boolean autoOutput;
// automatically split each line using the splitpattern
private boolean autoSplit;
// The pattern used to split the current line
private String splitPattern = " ";
// process sockets
private boolean processSockets;
// port to listen on when processing sockets
private int port;
// backup input files with extension
private String backupExtension;
// do you want full stack traces in script exceptions?
private boolean debug = false;
// Compiler configuration, used to set the encodings of the scripts/classes
private CompilerConfiguration conf = new CompilerConfiguration(System.getProperties());
/**
* Main CLI interface.
*
* @param args all command line args.
*/
public static void main(String args[]) {
processArgs(args, System.out);
}
// package-level visibility for testing purposes (just usage/errors at this stage)
// TODO: should we have an 'err' printstream too for ParseException?
static void processArgs(String[] args, final PrintStream out) {
Options options = buildOptions();
try {
CommandLine cmd = parseCommandLine(options, args);
if (cmd.hasOption('h')) {
printHelp(out, options);
} else if (cmd.hasOption('v')) {
String version = GroovySystem.getVersion();
out.println("Groovy Version: " + version + " JVM: " + System.getProperty("java.version") +
" Vendor: " + System.getProperty("java.vm.vendor") + " OS: " + System.getProperty("os.name"));
} else {
// If we fail, then exit with an error so scripting frameworks can catch it
// TODO: pass printstream(s) down through process
if (!process(cmd)) {
System.exit(1);
}
}
} catch (ParseException pe) {
out.println("error: " + pe.getMessage());
printHelp(out, options);
} catch (IOException ioe) {
out.println("error: " + ioe.getMessage());
}
}
private static void printHelp(PrintStream out, Options options) {
HelpFormatter formatter = new HelpFormatter();
PrintWriter pw = new PrintWriter(out);
formatter.printHelp(
pw,
80,
"groovy [options] [args]",
"options:",
options,
2,
4,
null, // footer
false);
pw.flush();
}
/**
* Parse the command line.
*
* @param options the options parser.
* @param args the command line args.
* @return parsed command line.
* @throws ParseException if there was a problem.
*/
private static CommandLine parseCommandLine(Options options, String[] args) throws ParseException {
CommandLineParser parser = new GroovyPosixParser();
return parser.parse(options, args, true);
}
/**
* Build the options parser. Has to be synchronized because of the way Options are constructed.
*
* @return an options parser.
*/
@SuppressWarnings("static-access")
private static synchronized Options buildOptions() {
Options options = new Options();
options.addOption(OptionBuilder.hasArg().withArgName("path").withDescription("Specify where to find the class files - must be first argument").create("classpath"));
options.addOption(OptionBuilder.withLongOpt("classpath").hasArg().withArgName("path").withDescription("Aliases for '-classpath'").create("cp"));
options.addOption(
OptionBuilder.withLongOpt("define").
withDescription("define a system property").
hasArg(true).
withArgName("name=value").
create('D'));
options.addOption(
OptionBuilder.withLongOpt("disableopt").
withDescription("disables one or all optimization elements. " +
"optlist can be a comma separated list with the elements: " +
"all (disables all optimizations), " +
"int (disable any int based optimizations)").
hasArg(true).
withArgName("optlist").
create());
options.addOption(
OptionBuilder.hasArg(false)
.withDescription("usage information")
.withLongOpt("help")
.create('h'));
options.addOption(
OptionBuilder.hasArg(false)
.withDescription("debug mode will print out full stack traces")
.withLongOpt("debug")
.create('d'));
options.addOption(
OptionBuilder.hasArg(false)
.withDescription("display the Groovy and JVM versions")
.withLongOpt("version")
.create('v'));
options.addOption(
OptionBuilder.withArgName("charset")
.hasArg()
.withDescription("specify the encoding of the files")
.withLongOpt("encoding")
.create('c'));
options.addOption(
OptionBuilder.withArgName("script")
.hasArg()
.withDescription("specify a command line script")
.create('e'));
options.addOption(
OptionBuilder.withArgName("extension")
.hasOptionalArg()
.withDescription("modify files in place; create backup if extension is given (e.g. \'.bak\')")
.create('i'));
options.addOption(
OptionBuilder.hasArg(false)
.withDescription("process files line by line using implicit 'line' variable")
.create('n'));
options.addOption(
OptionBuilder.hasArg(false)
.withDescription("process files line by line and print result (see also -n)")
.create('p'));
options.addOption(
OptionBuilder.withArgName("port")
.hasOptionalArg()
.withDescription("listen on a port and process inbound lines (default: 1960)")
.create('l'));
options.addOption(
OptionBuilder.withArgName("splitPattern")
.hasOptionalArg()
.withDescription("split lines using splitPattern (default '\\s') using implicit 'split' variable")
.withLongOpt("autosplit")
.create('a'));
options.addOption(
OptionBuilder.withLongOpt("indy")
.withDescription("enables compilation using invokedynamic")
.create());
options.addOption(
OptionBuilder.withLongOpt("configscript")
.hasArg().withDescription("A script for tweaking the configuration options")
.create());
return options;
}
private static void setSystemPropertyFrom(final String nameValue) {
if(nameValue==null) throw new IllegalArgumentException("argument should not be null");
String name, value;
int i = nameValue.indexOf("=");
if (i == -1) {
name = nameValue;
value = Boolean.TRUE.toString();
}
else {
name = nameValue.substring(0, i);
value = nameValue.substring(i + 1, nameValue.length());
}
name = name.trim();
System.setProperty(name, value);
}
/**
* Process the users request.
*
* @param line the parsed command line.
* @throws ParseException if invalid options are chosen
*/
private static boolean process(CommandLine line) throws ParseException, IOException {
List args = line.getArgList();
if (line.hasOption('D')) {
String[] values = line.getOptionValues('D');
for (int i=0; i