diff options
-rw-r--r-- | archiva-cli/pom.xml | 50 | ||||
-rw-r--r-- | archiva-cli/src/main/java/org/apache/maven/archiva/cli/Cli.java | 318 | ||||
-rw-r--r-- | archiva-cli/src/main/java/org/apache/maven/archiva/cli/CliManager.java | 180 |
3 files changed, 548 insertions, 0 deletions
diff --git a/archiva-cli/pom.xml b/archiva-cli/pom.xml new file mode 100644 index 000000000..270533db4 --- /dev/null +++ b/archiva-cli/pom.xml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<project> + <parent> + <artifactId>archiva</artifactId> + <groupId>org.apache.maven.archiva</groupId> + <version>1.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>archiva-cli</artifactId> + <name>Archiva CLI</name> + <version>1.0-SNAPSHOT</version> + <url>http://maven.apache.org</url> + <dependencies> + <dependency> + <groupId>classworlds</groupId> + <artifactId>classworlds</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.apache.maven.archiva</groupId> + <artifactId>archiva-core</artifactId> + <version>1.0-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.0</version> + <exclusions> + <exclusion> + <artifactId>commons-lang</artifactId> + <groupId>commons-lang</groupId> + </exclusion> + <exclusion> + <artifactId>commons-logging</artifactId> + <groupId>commons-logging</groupId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>ognl</groupId> + <artifactId>ognl</artifactId> + <version>2.6.7</version> + </dependency> + </dependencies> +</project> diff --git a/archiva-cli/src/main/java/org/apache/maven/archiva/cli/Cli.java b/archiva-cli/src/main/java/org/apache/maven/archiva/cli/Cli.java new file mode 100644 index 000000000..d0300c7c2 --- /dev/null +++ b/archiva-cli/src/main/java/org/apache/maven/archiva/cli/Cli.java @@ -0,0 +1,318 @@ +package org.apache.maven.archiva.cli; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * 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. + */ + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.ParseException; +import org.apache.maven.archiva.Archiva; +import org.apache.maven.archiva.discoverer.DiscovererException; +import org.apache.maven.archiva.converter.RepositoryConversionException; +import org.codehaus.classworlds.ClassWorld; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.DefaultPlexusContainer; +import org.codehaus.plexus.PlexusContainerException; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; + +import java.io.IOException; +import java.io.InputStream; +import java.io.File; +import java.util.Properties; + +/** + * @author jason van zyl + * @version $Id$ + * @noinspection UseOfSystemOutOrSystemErr,ACCESS_STATIC_VIA_INSTANCE + * @todo complete separate out the general cli processing + * @todo create a simple component to do the invocation + */ +public class Cli +{ + public static void main( String[] args ) + { + ClassWorld classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() ); + + int result = main( args, classWorld ); + + System.exit( result ); + } + + /** + * @noinspection ConfusingMainMethod + */ + public static int main( String[] args, + ClassWorld classWorld ) + { + // ---------------------------------------------------------------------- + // Setup the command line parser + // ---------------------------------------------------------------------- + + CliManager cliManager = new CliManager(); + + CommandLine cli; + + try + { + cli = cliManager.parse( args ); + } + catch ( ParseException e ) + { + System.err.println( "Unable to parse command line options: " + e.getMessage() ); + + cliManager.displayHelp(); + + return 1; + } + + if ( System.getProperty( "java.class.version", "44.0" ).compareTo( "48.0" ) < 0 ) + { + System.err.println( "Sorry, but JDK 1.4 or above is required to execute Maven" ); + + System.err.println( + "You appear to be using Java version: " + System.getProperty( "java.version", "<unknown>" ) ); + + return 1; + } + + boolean debug = cli.hasOption( CliManager.DEBUG ); + + boolean quiet = !debug && cli.hasOption( CliManager.QUIET ); + + boolean showErrors = debug || cli.hasOption( CliManager.ERRORS ); + + if ( showErrors ) + { + System.out.println( "+ Error stacktraces are turned on." ); + } + + // ---------------------------------------------------------------------------- + // Logging + // ---------------------------------------------------------------------------- + + int loggingLevel; + + if ( debug ) + { + loggingLevel = 0; //MavenExecutionRequest.LOGGING_LEVEL_DEBUG; + } + else if ( quiet ) + { + loggingLevel = 0; //MavenExecutionRequest.LOGGING_LEVEL_ERROR; + } + else + { + loggingLevel = 0; //MavenExecutionRequest.LOGGING_LEVEL_INFO; + } + + // ---------------------------------------------------------------------- + // Process particular command line options + // ---------------------------------------------------------------------- + + if ( cli.hasOption( CliManager.HELP ) ) + { + cliManager.displayHelp(); + + return 0; + } + + if ( cli.hasOption( CliManager.VERSION ) ) + { + showVersion(); + + return 0; + } + else if ( debug ) + { + showVersion(); + } + + // ---------------------------------------------------------------------------- + // This is what we will generalize for the invocation of the command line. + // ---------------------------------------------------------------------------- + + try + { + PlexusContainer plexus = new DefaultPlexusContainer( "plexus.core", classWorld ); + + Archiva archiva = (Archiva) plexus.lookup( Archiva.ROLE ); + + if ( cli.hasOption( CliManager.CONVERT ) ) + { + if ( cli.hasOption( CliManager.OLD_REPOSITORY_PATH ) && + cli.hasOption( CliManager.NEW_REPOSITORY_PATH ) ) + { + File oldRepositoryPath = new File( cli.getOptionValue( CliManager.OLD_REPOSITORY_PATH ) ); + + File newRepositoryPath = new File( cli.getOptionValue( CliManager.NEW_REPOSITORY_PATH ) ); + + try + { + archiva.convertLegacyRepository( oldRepositoryPath, newRepositoryPath, true ); + } + catch ( RepositoryConversionException e ) + { + showFatalError( "", e, true ); + } + catch ( DiscovererException e ) + { + showFatalError( "", e, true ); + } + } + else + { + System.out.println( + "You need to specify both a repository to convert and the path for the repository that will be created." ); + + cliManager.displayHelp(); + } + } + + } + catch ( PlexusContainerException e ) + { + showFatalError( "Cannot create Plexus container.", e, true ); + } + catch ( ComponentLookupException e ) + { + showError( "Cannot lookup application component.", e, true ); + } + + return 0; + } + + private static int showFatalError( String message, + Exception e, + boolean show ) + { + System.err.println( "FATAL ERROR: " + message ); + + if ( show ) + { + System.err.println( "Error stacktrace:" ); + + e.printStackTrace(); + } + else + { + System.err.println( "For more information, run with the -e flag" ); + } + + return 1; + } + + private static void showError( String message, + Exception e, + boolean show ) + { + System.err.println( message ); + + if ( show ) + { + System.err.println( "Error stacktrace:" ); + + e.printStackTrace(); + } + } + + // Need to get the versions of the application in a general way, so that I need a way to get the + // specifics of the application so that I can do this in a general way. + private static void showVersion() + { + InputStream resourceAsStream; + try + { + Properties properties = new Properties(); + resourceAsStream = Cli.class.getClassLoader().getResourceAsStream( + "META-INF/maven/org.apache.maven/maven-core/pom.properties" ); + properties.load( resourceAsStream ); + + if ( properties.getProperty( "builtOn" ) != null ) + { + System.out.println( "Maven version: " + properties.getProperty( "version", "unknown" ) + " built on " + + properties.getProperty( "builtOn" ) ); + } + else + { + System.out.println( "Maven version: " + properties.getProperty( "version", "unknown" ) ); + } + } + catch ( IOException e ) + { + System.err.println( "Unable determine version from JAR file: " + e.getMessage() ); + } + } + + // ---------------------------------------------------------------------- + // System properties handling + // ---------------------------------------------------------------------- + + private static Properties getExecutionProperties( CommandLine commandLine ) + { + Properties executionProperties = new Properties(); + + // ---------------------------------------------------------------------- + // Options that are set on the command line become system properties + // and therefore are set in the session properties. System properties + // are most dominant. + // ---------------------------------------------------------------------- + + if ( commandLine.hasOption( CliManager.SET_SYSTEM_PROPERTY ) ) + { + String[] defStrs = commandLine.getOptionValues( CliManager.SET_SYSTEM_PROPERTY ); + + for ( int i = 0; i < defStrs.length; ++i ) + { + setCliProperty( defStrs[i], executionProperties ); + } + } + + executionProperties.putAll( System.getProperties() ); + + return executionProperties; + } + + private static void setCliProperty( String property, + Properties executionProperties ) + { + String name; + + String value; + + int i = property.indexOf( "=" ); + + if ( i <= 0 ) + { + name = property.trim(); + + value = "true"; + } + else + { + name = property.substring( 0, i ).trim(); + + value = property.substring( i + 1 ).trim(); + } + + executionProperties.setProperty( name, value ); + + // ---------------------------------------------------------------------- + // I'm leaving the setting of system properties here as not to break + // the SystemPropertyProfileActivator. This won't harm embedding. jvz. + // ---------------------------------------------------------------------- + + System.setProperty( name, value ); + } +} diff --git a/archiva-cli/src/main/java/org/apache/maven/archiva/cli/CliManager.java b/archiva-cli/src/main/java/org/apache/maven/archiva/cli/CliManager.java new file mode 100644 index 000000000..2829dc7f3 --- /dev/null +++ b/archiva-cli/src/main/java/org/apache/maven/archiva/cli/CliManager.java @@ -0,0 +1,180 @@ +package org.apache.maven.archiva.cli; + +import org.apache.commons.cli.Options; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.GnuParser; +import org.apache.commons.cli.HelpFormatter; + +import java.util.List; +import java.util.ArrayList; + +/** + * @author Jason van Zyl + * @version $Revision: 381114 $ + */ +public class CliManager +{ + public static char CONVERT = 'c'; + + public static final char OLD_REPOSITORY_PATH = 'o'; + + public static final char NEW_REPOSITORY_PATH = 'n'; + + // ---------------------------------------------------------------------------- + // These are standard options that we would want to use for all our projects. + // ---------------------------------------------------------------------------- + + public static final char QUIET = 'q'; + + public static final char DEBUG = 'X'; + + public static final char ERRORS = 'e'; + + public static final char HELP = 'h'; + + public static final char VERSION = 'v'; + + public static final char SET_SYSTEM_PROPERTY = 'D'; + + private Options options; + + public CliManager() + { + options = new Options(); + + options.addOption( OptionBuilder.withLongOpt( "convert" ).withDescription( + "Convert a legacy Maven 1.x repository to a Maven 2.x repository." ).create( CONVERT ) ); + + options.addOption( OptionBuilder.withLongOpt( "old-repo" ).withDescription( + "Path to Maven 1.x legacy repository to convert." ).create( OLD_REPOSITORY_PATH ) ); + + options.addOption( OptionBuilder.withLongOpt( "new-repo" ).withDescription( + "Path to newly created Maven 2.x repository." ).create( NEW_REPOSITORY_PATH ) ); + } + + public CommandLine parse( String[] args ) + throws ParseException + { + // We need to eat any quotes surrounding arguments... + String[] cleanArgs = cleanArgs( args ); + + CommandLineParser parser = new GnuParser(); + + return parser.parse( options, cleanArgs ); + } + + private String[] cleanArgs( String[] args ) + { + List cleaned = new ArrayList(); + + StringBuffer currentArg = null; + + for ( int i = 0; i < args.length; i++ ) + { + String arg = args[i]; + + boolean addedToBuffer = false; + + if ( arg.startsWith( "\"" ) ) + { + // if we're in the process of building up another arg, push it and start over. + // this is for the case: "-Dfoo=bar "-Dfoo2=bar two" (note the first unterminated quote) + if ( currentArg != null ) + { + cleaned.add( currentArg.toString() ); + } + + // start building an argument here. + currentArg = new StringBuffer( arg.substring( 1 ) ); + + addedToBuffer = true; + } + + // this has to be a separate "if" statement, to capture the case of: "-Dfoo=bar" + if ( arg.endsWith( "\"" ) ) + { + String cleanArgPart = arg.substring( 0, arg.length() - 1 ); + + // if we're building an argument, keep doing so. + if ( currentArg != null ) + { + // if this is the case of "-Dfoo=bar", then we need to adjust the buffer. + if ( addedToBuffer ) + { + currentArg.setLength( currentArg.length() - 1 ); + } + // otherwise, we trim the trailing " and append to the buffer. + else + { + // TODO: introducing a space here...not sure what else to do but collapse whitespace + currentArg.append( ' ' ).append( cleanArgPart ); + } + + // we're done with this argument, so add it. + cleaned.add( currentArg.toString() ); + } + else + { + // this is a simple argument...just add it. + cleaned.add( cleanArgPart ); + } + + // the currentArg MUST be finished when this completes. + currentArg = null; + + continue; + } + + // if we haven't added this arg to the buffer, and we ARE building an argument + // buffer, then append it with a preceding space...again, not sure what else to + // do other than collapse whitespace. + // NOTE: The case of a trailing quote is handled by nullifying the arg buffer. + if ( !addedToBuffer ) + { + // append to the argument we're building, collapsing whitespace to a single space. + if ( currentArg != null ) + { + currentArg.append( ' ' ).append( arg ); + } + // this is a loner, just add it directly. + else + { + cleaned.add( arg ); + } + } + } + + // clean up. + if ( currentArg != null ) + { + cleaned.add( currentArg.toString() ); + } + + int cleanedSz = cleaned.size(); + String[] cleanArgs = null; + + if ( cleanedSz == 0 ) + { + // if we didn't have any arguments to clean, simply pass the original array through + cleanArgs = args; + } + else + { + cleanArgs = (String[]) cleaned.toArray( new String[cleanedSz] ); + } + + return cleanArgs; + } + + public void displayHelp() + { + System.out.println(); + + HelpFormatter formatter = new HelpFormatter(); + + formatter.printHelp( "mvn [options] [<goal(s)>] [<phase(s)>]", "\nOptions:", options, "\n" ); + } +} |