| /* |
| * Copyright 2003-2007 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 org.codehaus.groovy.tools.shell |
| |
| import org.codehaus.groovy.runtime.InvokerHelper |
| import org.codehaus.groovy.tools.shell.util.ANSI |
| import org.codehaus.groovy.tools.shell.util.HelpFormatter |
| import org.codehaus.groovy.tools.shell.util.Logger |
| import org.codehaus.groovy.tools.shell.util.MessageSource |
| import org.codehaus.groovy.tools.shell.util.NoExitSecurityManager |
| |
| /** |
| * Main CLI entry-point for <tt>groovysh</tt>. |
| * |
| * @version $Id$ |
| * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> |
| */ |
| class Main |
| { |
| private static final MessageSource messages = new MessageSource(Main.class) |
| |
| static void main(final String[] args) { |
| IO io = new IO() |
| Logger.io = io |
| |
| def cli = new CliBuilder(usage : 'groovysh [options] [...]', formatter: new HelpFormatter(), writer: io.out) |
| |
| cli.h(longOpt: 'help', messages['cli.option.help.description']) |
| cli.V(longOpt: 'version', messages['cli.option.version.description']) |
| cli.v(longOpt: 'verbose', messages['cli.option.verbose.description']) |
| cli.q(longOpt: 'quiet', messages['cli.option.quiet.description']) |
| cli.d(longOpt: 'debug', messages['cli.option.debug.description']) |
| cli.C(longOpt: 'color', args: 1, argName: 'FLAG', optionalArg: true, messages['cli.option.color.description']) |
| cli.D(longOpt: 'define', args: 1, argName: 'NAME=VALUE', messages['cli.option.define.description']) |
| cli.T(longOpt: 'terminal', args: 1, argName: 'TYPE', messages['cli.option.terminal.description']) |
| |
| def options = cli.parse(args) |
| |
| if (options.h) { |
| cli.usage() |
| System.exit(0) |
| } |
| |
| if (options.V) { |
| io.out.println(messages.format('cli.info.version', InvokerHelper.version)) |
| System.exit(0) |
| } |
| |
| if (options.hasOption('T')) { |
| def type = options.getOptionValue('T') |
| setTerminalType(type) |
| } |
| |
| if (options.hasOption('D')) { |
| def values = options.getOptionValues('D') |
| |
| values.each { |
| setSystemProperty(it as String) |
| } |
| } |
| |
| if (options.v) { |
| io.verbosity = IO.Verbosity.VERBOSE |
| } |
| |
| if (options.d) { |
| io.verbosity = IO.Verbosity.DEBUG |
| } |
| |
| if (options.q) { |
| io.verbosity = IO.Verbosity.QUIET |
| } |
| |
| if (options.hasOption('C')) { |
| def value = options.getOptionValue('C') |
| setColor(value) |
| } |
| |
| def code |
| |
| // Add a hook to display some status when shutting down... |
| addShutdownHook { |
| // |
| // FIXME: We need to configure JLine to catch CTRL-C for us... if that is possible |
| // |
| |
| if (code == null) { |
| // Give the user a warning when the JVM shutdown abnormally, normal shutdown |
| // will set an exit code through the proper channels |
| |
| io.err.println() |
| io.err.println('@|red WARNING:| Abnormal JVM shutdown detected') |
| } |
| |
| io.flush() |
| } |
| |
| // Boot up the shell... :-) |
| Groovysh shell = new Groovysh(io) |
| |
| SecurityManager psm = System.getSecurityManager() |
| System.setSecurityManager(new NoExitSecurityManager()) |
| |
| try { |
| code = shell.run(options.arguments() as String[]) |
| } |
| finally { |
| System.setSecurityManager(psm) |
| } |
| |
| // Force the JVM to exit at this point, since shell could have created threads or |
| // popped up Swing components that will cause the JVM to linger after we have been |
| // asked to shutdown |
| |
| System.exit(code) |
| } |
| |
| static void setTerminalType(String type) { |
| assert type != null |
| |
| type = type.toLowerCase(); |
| |
| switch (type) { |
| case 'auto': |
| type = null; |
| break; |
| |
| case 'unix': |
| type = 'jline.UnixTerminal' |
| break |
| |
| case 'win': |
| case 'windows': |
| type = 'jline.WindowsTerminal' |
| break |
| |
| case 'false': |
| case 'off': |
| case 'none': |
| type = 'jline.UnsupportedTerminal' |
| // Disable ANSI, for some reason UnsupportedTerminal reports ANSI as enabled, when it shouldn't |
| ANSI.enabled = false |
| break; |
| } |
| |
| if (type != null) { |
| System.setProperty('jline.terminal', type) |
| } |
| } |
| |
| static void setColor(value) { |
| if (value == null) { |
| value = true // --color is the same as --color=true |
| } |
| else { |
| value = Boolean.valueOf(value).booleanValue(); // For JDK 1.4 compat |
| } |
| |
| ANSI.enabled = value |
| } |
| |
| static void setSystemProperty(final String nameValue) { |
| String name |
| String value |
| |
| if (nameValue.indexOf('=') > 0) { |
| def tmp = nameValue.split('=', 2) |
| name = tmp[0] |
| value = tmp[1] |
| } |
| else { |
| name = nameValue |
| value = Boolean.TRUE.toString() |
| } |
| |
| System.setProperty(name, value) |
| } |
| } |