A copy of the gradle wrapper ported for use with maven

Lightly touched to better mesh with current maven builds. (some of which my not have been necessary in hind sight) 

Test it out with this build, run: "./mvnw clean install" at the root of this repo
This will download, install, and run maven 3.0.5 (as configured in maven/wrapper/maven-wrapper.properties)

NOTE: windows batch file is NOT tested


TODO: 
* Possibly extract these bits out into something both gradle and maven (and others) can use
* Port gradle IT's to this build
* See if anyone is interested in this project
This commit is contained in:
bdemers 2013-03-04 11:21:40 -05:00 committed by rfscholte
parent ba16eb1b39
commit a850495296
31 changed files with 3423 additions and 0 deletions

3
maven-wrapper/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.classpath
.project
.settings

Binary file not shown.

View File

@ -0,0 +1 @@
distributionUrl=https://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.0.5/apache-maven-3.0.5-bin.zip

170
maven-wrapper/mvnw vendored Executable file
View File

@ -0,0 +1,170 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
if [ -z "$JAVA_VERSION" ] ; then
JAVA_VERSION="CurrentJDK"
fi
if [ -z "$JAVA_HOME" ] ; then
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Migwn, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" -a ! "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
javaExecutable="`readlink -f \"$javaExecutable\"`"
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly."
echo " We cannot execute $JAVACMD"
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
fi
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "./maven/wrapper/maven-wrapper.jar" \
${WRAPPER_LAUNCHER} "$@"

189
maven-wrapper/mvnw.bat Normal file
View File

@ -0,0 +1,189 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
:skipRcPre
set ERROR_CODE=0
@REM set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" @setlocal
if "%OS%"=="WINNT" @setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo ERROR: JAVA_HOME not found in your environment.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto chkMHome
echo.
echo ERROR: JAVA_HOME is set to an invalid directory.
echo JAVA_HOME = "%JAVA_HOME%"
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation
echo.
goto error
:chkMHome
if not "%M2_HOME%"=="" goto valMHome
if "%OS%"=="Windows_NT" SET "M2_HOME=%~dp0.."
if "%OS%"=="WINNT" SET "M2_HOME=%~dp0.."
if not "%M2_HOME%"=="" goto valMHome
echo.
echo ERROR: M2_HOME not found in your environment.
echo Please set the M2_HOME variable in your environment to match the
echo location of the Maven installation
echo.
goto error
:valMHome
:stripMHome
if not "_%M2_HOME:~-1%"=="_\" goto checkMBat
set "M2_HOME=%M2_HOME:~0,-1%"
goto stripMHome
:checkMBat
if exist "%M2_HOME%\bin\mvn.bat" goto init
echo.
echo ERROR: M2_HOME is set to an invalid directory.
echo M2_HOME = "%M2_HOME%"
echo Please set the M2_HOME variable in your environment to match the
echo location of the Maven installation
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Decide how to startup depending on the version of windows
@REM -- Windows NT with Novell Login
if "%OS%"=="WINNT" goto WinNTNovell
@REM -- Win98ME
if NOT "%OS%"=="Windows_NT" goto Win9xArg
:WinNTNovell
@REM -- 4NT shell
if "%@eval[2+2]" == "4" goto 4NTArgs
@REM -- Regular WinNT shell
set MAVEN_CMD_LINE_ARGS=%*
goto endInit
@REM The 4NT Shell from jp software
:4NTArgs
set MAVEN_CMD_LINE_ARGS=%$
goto endInit
:Win9xArg
@REM Slurp the command line arguments. This loop allows for an unlimited number
@REM of agruments (up to the command line limit, anyway).
set MAVEN_CMD_LINE_ARGS=
:Win9xApp
if %1a==a goto endInit
set MAVEN_CMD_LINE_ARGS=%MAVEN_CMD_LINE_ARGS% %1
shift
goto Win9xApp
@REM Reaching here means variables are defined and arguments have been captured
:endInit
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
@REM -- Regular WinNT shell
set WRAPPER_JAR="".\maven\wrapper\maven-wrapper.jar""
goto runm2
@REM Start MAVEN2
:runm2
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
%MAVEN_JAVA_EXE% %MAVEN_OPTS% -classpath %WRAPPER_JAR% %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
if ERRORLEVEL 1 goto error
goto end
:error
if "%OS%"=="Windows_NT" @endlocal
if "%OS%"=="WINNT" @endlocal
set ERROR_CODE=1
:end
@REM set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" goto endNT
if "%OS%"=="WINNT" goto endNT
@REM For old DOS remove the set variables from ENV - we assume they were not set
@REM before we started - at least we don't leave any baggage around
set MAVEN_JAVA_EXE=
set MAVEN_CMD_LINE_ARGS=
goto postExec
:endNT
@endlocal & set ERROR_CODE=%ERROR_CODE%
:postExec
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
:skipRcPost
@REM pause the batch file if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

55
maven-wrapper/pom.xml Normal file
View File

@ -0,0 +1,55 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>maven-parent</artifactId>
<groupId>org.apache.maven</groupId>
<version>23</version>
</parent>
<artifactId>maven-wapper</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Wrapper</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
<scope>test</scope>
</dependency>
<!-- Using zip util class, should be replaced with a zip lib -->
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,57 @@
/*
* Copyright 2010 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.apache.maven.wrapper;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
/**
* @author Hans Dockter
*/
public class BootstrapMainStarter
{
public void start( String[] args, File mavenHome )
throws Exception
{
File mavenJar = findLauncherJar( mavenHome );
URLClassLoader contextClassLoader =
new URLClassLoader( new URL[] { mavenJar.toURI().toURL() }, ClassLoader.getSystemClassLoader().getParent() );
Thread.currentThread().setContextClassLoader( contextClassLoader );
Class<?> mainClass = contextClassLoader.loadClass( "org.codehaus.plexus.classworlds.launcher.Launcher" );
System.setProperty( "maven.home", mavenHome.getAbsolutePath() );
System.setProperty( "classworlds.conf", new File( mavenHome, "/bin/m2.conf" ).getAbsolutePath() );
Method mainMethod = mainClass.getMethod( "main", String[].class );
mainMethod.invoke( null, new Object[] { args } );
}
private File findLauncherJar( File mavenHome )
{
for ( File file : new File( mavenHome, "boot" ).listFiles() )
{
if ( file.getName().matches( "plexus-classworlds-.*\\.jar" ) )
{
return file;
}
}
throw new RuntimeException(
String.format( "Could not locate the Maven launcher JAR in Maven distribution '%s'.",
mavenHome ) );
}
}

View File

@ -0,0 +1,137 @@
/*
* Copyright 2007-2009 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.apache.maven.wrapper;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
/**
* @author Hans Dockter
*/
public class DefaultDownloader
implements Downloader
{
private static final int PROGRESS_CHUNK = 20000;
private static final int BUFFER_SIZE = 10000;
private final String applicationName;
private final String applicationVersion;
public DefaultDownloader( String applicationName, String applicationVersion )
{
this.applicationName = applicationName;
this.applicationVersion = applicationVersion;
configureProxyAuthentication();
}
private void configureProxyAuthentication()
{
if ( System.getProperty( "http.proxyUser" ) != null )
{
Authenticator.setDefault( new SystemPropertiesProxyAuthenticator() );
}
}
public void download( URI address, File destination )
throws Exception
{
if ( destination.exists() )
{
return;
}
destination.getParentFile().mkdirs();
downloadInternal( address, destination );
}
private void downloadInternal( URI address, File destination )
throws Exception
{
OutputStream out = null;
URLConnection conn;
InputStream in = null;
try
{
URL url = address.toURL();
out = new BufferedOutputStream( new FileOutputStream( destination ) );
conn = url.openConnection();
final String userAgentValue = calculateUserAgent();
conn.setRequestProperty( "User-Agent", userAgentValue );
in = conn.getInputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int numRead;
long progressCounter = 0;
while ( ( numRead = in.read( buffer ) ) != -1 )
{
progressCounter += numRead;
if ( progressCounter / PROGRESS_CHUNK > 0 )
{
System.out.print( "." );
progressCounter = progressCounter - PROGRESS_CHUNK;
}
out.write( buffer, 0, numRead );
}
}
finally
{
System.out.println( "" );
if ( in != null )
{
in.close();
}
if ( out != null )
{
out.close();
}
}
}
private String calculateUserAgent()
{
String appVersion = applicationVersion;
String javaVendor = System.getProperty( "java.vendor" );
String javaVersion = System.getProperty( "java.version" );
String javaVendorVersion = System.getProperty( "java.vm.version" );
String osName = System.getProperty( "os.name" );
String osVersion = System.getProperty( "os.version" );
String osArch = System.getProperty( "os.arch" );
return String.format( "%s/%s (%s;%s;%s) (%s;%s;%s)", applicationName, appVersion, osName, osVersion, osArch,
javaVendor, javaVersion, javaVendorVersion );
}
private static class SystemPropertiesProxyAuthenticator
extends Authenticator
{
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication( System.getProperty( "http.proxyUser" ),
System.getProperty( "http.proxyPassword", "" ).toCharArray() );
}
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2007-2009 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.apache.maven.wrapper;
import java.io.File;
import java.net.URI;
/**
* @author Hans Dockter
*/
public interface Downloader
{
void download( URI address, File destination )
throws Exception;
}

View File

@ -0,0 +1,233 @@
/*
* Copyright 2010 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.apache.maven.wrapper;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* @author Hans Dockter
*/
public class Installer
{
public static final String DEFAULT_DISTRIBUTION_PATH = "wrapper/dists";
private final Downloader download;
private final PathAssembler pathAssembler;
public Installer( Downloader download, PathAssembler pathAssembler )
{
this.download = download;
this.pathAssembler = pathAssembler;
}
public File createDist( WrapperConfiguration configuration )
throws Exception
{
URI distributionUrl = configuration.getDistribution();
boolean alwaysDownload = configuration.isAlwaysDownload();
boolean alwaysUnpack = configuration.isAlwaysUnpack();
PathAssembler.LocalDistribution localDistribution = pathAssembler.getDistribution( configuration );
File localZipFile = localDistribution.getZipFile();
boolean downloaded = false;
if ( alwaysDownload || !localZipFile.exists() )
{
File tmpZipFile = new File( localZipFile.getParentFile(), localZipFile.getName() + ".part" );
tmpZipFile.delete();
System.out.println( "Downloading " + distributionUrl );
download.download( distributionUrl, tmpZipFile );
tmpZipFile.renameTo( localZipFile );
downloaded = true;
}
File distDir = localDistribution.getDistributionDir();
List<File> dirs = listDirs( distDir );
if ( downloaded || alwaysUnpack || dirs.isEmpty() )
{
for ( File dir : dirs )
{
System.out.println( "Deleting directory " + dir.getAbsolutePath() );
deleteDir( dir );
}
System.out.println( "Unzipping " + localZipFile.getAbsolutePath() + " to " + distDir.getAbsolutePath() );
unzip( localZipFile, distDir );
dirs = listDirs( distDir );
if ( dirs.isEmpty() )
{
throw new RuntimeException(
String.format( "Maven distribution '%s' does not contain any directories. Expected to find exactly 1 directory.",
distributionUrl ) );
}
setExecutablePermissions( dirs.get( 0 ) );
}
if ( dirs.size() != 1 )
{
throw new RuntimeException(
String.format( "Maven distribution '%s' contains too many directories. Expected to find exactly 1 directory.",
distributionUrl ) );
}
return dirs.get( 0 );
}
private List<File> listDirs( File distDir )
{
List<File> dirs = new ArrayList<File>();
if ( distDir.exists() )
{
for ( File file : distDir.listFiles() )
{
if ( file.isDirectory() )
{
dirs.add( file );
}
}
}
return dirs;
}
private void setExecutablePermissions( File mavenHome )
{
if ( isWindows() )
{
return;
}
File mavenCommand = new File( mavenHome, "bin/mvn" );
String errorMessage = null;
try
{
ProcessBuilder pb = new ProcessBuilder( "chmod", "755", mavenCommand.getCanonicalPath() );
Process p = pb.start();
if ( p.waitFor() == 0 )
{
System.out.println( "Set executable permissions for: " + mavenCommand.getAbsolutePath() );
}
else
{
BufferedReader is = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
Formatter stdout = new Formatter();
String line;
while ( ( line = is.readLine() ) != null )
{
stdout.format( "%s%n", line );
}
errorMessage = stdout.toString();
}
}
catch ( IOException e )
{
errorMessage = e.getMessage();
}
catch ( InterruptedException e )
{
errorMessage = e.getMessage();
}
if ( errorMessage != null )
{
System.out.println( "Could not set executable permissions for: " + mavenCommand.getAbsolutePath() );
System.out.println( "Please do this manually if you want to use maven." );
}
}
private boolean isWindows()
{
String osName = System.getProperty( "os.name" ).toLowerCase( Locale.US );
if ( osName.indexOf( "windows" ) > -1 )
{
return true;
}
return false;
}
private boolean deleteDir( File dir )
{
if ( dir.isDirectory() )
{
String[] children = dir.list();
for ( int i = 0; i < children.length; i++ )
{
boolean success = deleteDir( new File( dir, children[i] ) );
if ( !success )
{
return false;
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
public void unzip( File zip, File dest )
throws IOException
{
Enumeration entries;
ZipFile zipFile;
zipFile = new ZipFile( zip );
entries = zipFile.entries();
while ( entries.hasMoreElements() )
{
ZipEntry entry = (ZipEntry) entries.nextElement();
if ( entry.isDirectory() )
{
( new File( dest, entry.getName() ) ).mkdirs();
continue;
}
copyInputStream( zipFile.getInputStream( entry ),
new BufferedOutputStream( new FileOutputStream( new File( dest, entry.getName() ) ) ) );
}
zipFile.close();
}
public void copyInputStream( InputStream in, OutputStream out )
throws IOException
{
byte[] buffer = new byte[1024];
int len;
while ( ( len = in.read( buffer ) ) >= 0 )
{
out.write( buffer, 0, len );
}
in.close();
out.close();
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright 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.apache.maven.wrapper;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.Properties;
import org.apache.maven.wrapper.cli.CommandLineParser;
import org.apache.maven.wrapper.cli.SystemPropertiesCommandLineConverter;
/**
* @author Hans Dockter
*/
public class MavenWrapperMain
{
public static final String DEFAULT_MAVEN_USER_HOME = System.getProperty( "user.home" ) + "/.m2";
public static final String MAVEN_USER_HOME_PROPERTY_KEY = "maven.user.home";
public static final String MAVEN_USER_HOME_ENV_KEY = "MAVEN_USER_HOME";
public static void main( String[] args )
throws Exception
{
File wrapperJar = wrapperJar();
File propertiesFile = wrapperProperties( wrapperJar );
File rootDir = rootDir( wrapperJar );
Properties systemProperties = System.getProperties();
systemProperties.putAll( parseSystemPropertiesFromArgs( args ) );
addSystemProperties( rootDir );
WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile( propertiesFile, System.out );
wrapperExecutor.execute( args, new Installer( new DefaultDownloader( "mvnw", wrapperVersion() ),
new PathAssembler( mavenUserHome() ) ), new BootstrapMainStarter() );
}
private static Map<String, String> parseSystemPropertiesFromArgs( String[] args )
{
SystemPropertiesCommandLineConverter converter = new SystemPropertiesCommandLineConverter();
CommandLineParser commandLineParser = new CommandLineParser();
converter.configure( commandLineParser );
commandLineParser.allowUnknownOptions();
return converter.convert( commandLineParser.parse( args ) );
}
private static void addSystemProperties( File rootDir )
{
System.getProperties().putAll( SystemPropertiesHandler.getSystemProperties( new File( mavenUserHome(),
"maven.properties" ) ) );
System.getProperties().putAll( SystemPropertiesHandler.getSystemProperties( new File( rootDir,
"maven.properties" ) ) );
}
private static File rootDir( File wrapperJar )
{
return wrapperJar.getParentFile().getParentFile().getParentFile();
}
private static File wrapperProperties( File wrapperJar )
{
return new File( wrapperJar.getParent(), wrapperJar.getName().replaceFirst( "\\.jar$", ".properties" ) );
}
private static File wrapperJar()
{
URI location;
try
{
location = MavenWrapperMain.class.getProtectionDomain().getCodeSource().getLocation().toURI();
}
catch ( URISyntaxException e )
{
throw new RuntimeException( e );
}
if ( !location.getScheme().equals( "file" ) )
{
throw new RuntimeException(
String.format( "Cannot determine classpath for wrapper Jar from codebase '%s'.",
location ) );
}
return new File( location.getPath() );
}
static String wrapperVersion()
{
try
{
InputStream resourceAsStream =
MavenWrapperMain.class.getResourceAsStream( "/META-INF/maven/org.apache.maven/maven-wapper/pom.properties" );
if ( resourceAsStream == null )
{
throw new RuntimeException( "No maven properties found." );
}
Properties mavenProperties = new Properties();
try
{
mavenProperties.load( resourceAsStream );
String version = mavenProperties.getProperty( "version" );
if ( version == null )
{
throw new RuntimeException( "No version number specified in build receipt resource." );
}
return version;
}
finally
{
resourceAsStream.close();
}
}
catch ( Exception e )
{
throw new RuntimeException( "Could not determine wrapper version.", e );
}
}
private static File mavenUserHome()
{
String mavenUserHome = System.getProperty( MAVEN_USER_HOME_PROPERTY_KEY );
if ( mavenUserHome != null )
{
return new File( mavenUserHome );
}
else if ( ( mavenUserHome = System.getenv( MAVEN_USER_HOME_ENV_KEY ) ) != null )
{
return new File( mavenUserHome );
}
else
{
return new File( DEFAULT_MAVEN_USER_HOME );
}
}
}

View File

@ -0,0 +1,146 @@
/*
* Copyright 2007-2008 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.apache.maven.wrapper;
import java.io.File;
import java.math.BigInteger;
import java.net.URI;
import java.security.MessageDigest;
/**
* @author Hans Dockter
*/
public class PathAssembler
{
public static final String MAVEN_USER_HOME_STRING = "MAVEN_USER_HOME";
public static final String PROJECT_STRING = "PROJECT";
private File mavenUserHome;
public PathAssembler()
{
}
public PathAssembler( File mavenUserHome )
{
this.mavenUserHome = mavenUserHome;
}
/**
* Determines the local locations for the distribution to use given the supplied configuration.
*/
public LocalDistribution getDistribution( WrapperConfiguration configuration )
{
String baseName = getDistName( configuration.getDistribution() );
String distName = removeExtension( baseName );
String rootDirName = rootDirName( distName, configuration );
File distDir =
new File( getBaseDir( configuration.getDistributionBase() ), configuration.getDistributionPath() + "/"
+ rootDirName );
File distZip =
new File( getBaseDir( configuration.getZipBase() ), configuration.getZipPath() + "/" + rootDirName + "/"
+ baseName );
return new LocalDistribution( distDir, distZip );
}
private String rootDirName( String distName, WrapperConfiguration configuration )
{
String urlHash = getMd5Hash( configuration.getDistribution().toString() );
return String.format( "%s/%s", distName, urlHash );
}
private String getMd5Hash( String string )
{
try
{
MessageDigest messageDigest = MessageDigest.getInstance( "MD5" );
byte[] bytes = string.getBytes();
messageDigest.update( bytes );
return new BigInteger( 1, messageDigest.digest() ).toString( 32 );
}
catch ( Exception e )
{
throw new RuntimeException( "Could not hash input string.", e );
}
}
private String removeExtension( String name )
{
int p = name.lastIndexOf( "." );
if ( p < 0 )
{
return name;
}
return name.substring( 0, p );
}
private String getDistName( URI distUrl )
{
String path = distUrl.getPath();
int p = path.lastIndexOf( "/" );
if ( p < 0 )
{
return path;
}
return path.substring( p + 1 );
}
private File getBaseDir( String base )
{
if ( base.equals( MAVEN_USER_HOME_STRING ) )
{
return mavenUserHome;
}
else if ( base.equals( PROJECT_STRING ) )
{
return new File( System.getProperty( "user.dir" ) );
}
else
{
throw new RuntimeException( "Base: " + base + " is unknown" );
}
}
public class LocalDistribution
{
private final File distZip;
private final File distDir;
public LocalDistribution( File distDir, File distZip )
{
this.distDir = distDir;
this.distZip = distZip;
}
/**
* Returns the location to install the distribution into.
*/
public File getDistributionDir()
{
return distDir;
}
/**
* Returns the location to install the distribution ZIP file to.
*/
public File getZipFile()
{
return distZip;
}
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 2010 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.apache.maven.wrapper;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Hans Dockter
*/
public class SystemPropertiesHandler
{
public static Map<String, String> getSystemProperties( File propertiesFile )
{
Map<String, String> propertyMap = new HashMap<String, String>();
if ( !propertiesFile.isFile() )
{
return propertyMap;
}
Properties properties = new Properties();
try
{
FileInputStream inStream = new FileInputStream( propertiesFile );
try
{
properties.load( inStream );
}
finally
{
inStream.close();
}
}
catch ( IOException e )
{
throw new RuntimeException( "Error when loading properties file=" + propertiesFile, e );
}
Pattern pattern = Pattern.compile( "systemProp\\.(.*)" );
for ( Object argument : properties.keySet() )
{
Matcher matcher = pattern.matcher( argument.toString() );
if ( matcher.find() )
{
String key = matcher.group( 1 );
if ( key.length() > 0 )
{
propertyMap.put( key, properties.get( argument ).toString() );
}
}
}
return propertyMap;
}
}

View File

@ -0,0 +1,109 @@
/*
* Copyright 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 org.apache.maven.wrapper;
import java.net.URI;
public class WrapperConfiguration
{
public static final String ALWAYS_UNPACK_ENV = "MAVEN_WRAPPER_ALWAYS_UNPACK";
public static final String ALWAYS_DOWNLOAD_ENV = "MAVEN_WRAPPER_ALWAYS_DOWNLOAD";
private boolean alwaysUnpack = Boolean.parseBoolean( System.getenv( ALWAYS_UNPACK_ENV ) );
private boolean alwaysDownload = Boolean.parseBoolean( System.getenv( ALWAYS_DOWNLOAD_ENV ) );
private URI distribution;
private String distributionBase = PathAssembler.MAVEN_USER_HOME_STRING;
private String distributionPath = Installer.DEFAULT_DISTRIBUTION_PATH;
private String zipBase = PathAssembler.MAVEN_USER_HOME_STRING;
private String zipPath = Installer.DEFAULT_DISTRIBUTION_PATH;
public boolean isAlwaysDownload()
{
return alwaysDownload;
}
public void setAlwaysDownload( boolean alwaysDownload )
{
this.alwaysDownload = alwaysDownload;
}
public boolean isAlwaysUnpack()
{
return alwaysUnpack;
}
public void setAlwaysUnpack( boolean alwaysUnpack )
{
this.alwaysUnpack = alwaysUnpack;
}
public URI getDistribution()
{
return distribution;
}
public void setDistribution( URI distribution )
{
this.distribution = distribution;
}
public String getDistributionBase()
{
return distributionBase;
}
public void setDistributionBase( String distributionBase )
{
this.distributionBase = distributionBase;
}
public String getDistributionPath()
{
return distributionPath;
}
public void setDistributionPath( String distributionPath )
{
this.distributionPath = distributionPath;
}
public String getZipBase()
{
return zipBase;
}
public void setZipBase( String zipBase )
{
this.zipBase = zipBase;
}
public String getZipPath()
{
return zipPath;
}
public void setZipPath( String zipPath )
{
this.zipPath = zipPath;
}
}

View File

@ -0,0 +1,177 @@
/*
* Copyright 2007-2008 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.apache.maven.wrapper;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
/**
* @author Hans Dockter
*/
public class WrapperExecutor
{
public static final String DISTRIBUTION_URL_PROPERTY = "distributionUrl";
public static final String DISTRIBUTION_BASE_PROPERTY = "distributionBase";
public static final String ZIP_STORE_BASE_PROPERTY = "zipStoreBase";
public static final String DISTRIBUTION_PATH_PROPERTY = "distributionPath";
public static final String ZIP_STORE_PATH_PROPERTY = "zipStorePath";
private final Properties properties;
private final File propertiesFile;
private final Appendable warningOutput;
private final WrapperConfiguration config = new WrapperConfiguration();
public static WrapperExecutor forProjectDirectory( File projectDir, Appendable warningOutput )
{
return new WrapperExecutor( new File( projectDir, "maven/wrapper/maven-wrapper.properties" ), new Properties(),
warningOutput );
}
public static WrapperExecutor forWrapperPropertiesFile( File propertiesFile, Appendable warningOutput )
{
if ( !propertiesFile.exists() )
{
throw new RuntimeException( String.format( "Wrapper properties file '%s' does not exist.", propertiesFile ) );
}
return new WrapperExecutor( propertiesFile, new Properties(), warningOutput );
}
WrapperExecutor( File propertiesFile, Properties properties, Appendable warningOutput )
{
this.properties = properties;
this.propertiesFile = propertiesFile;
this.warningOutput = warningOutput;
if ( propertiesFile.exists() )
{
try
{
loadProperties( propertiesFile, properties );
config.setDistribution( prepareDistributionUri() );
config.setDistributionBase( getProperty( DISTRIBUTION_BASE_PROPERTY, config.getDistributionBase() ) );
config.setDistributionPath( getProperty( DISTRIBUTION_PATH_PROPERTY, config.getDistributionPath() ) );
config.setZipBase( getProperty( ZIP_STORE_BASE_PROPERTY, config.getZipBase() ) );
config.setZipPath( getProperty( ZIP_STORE_PATH_PROPERTY, config.getZipPath() ) );
}
catch ( Exception e )
{
throw new RuntimeException( String.format( "Could not load wrapper properties from '%s'.",
propertiesFile ), e );
}
}
}
private URI prepareDistributionUri()
throws URISyntaxException
{
URI source = readDistroUrl();
if ( source.getScheme() == null )
{
// no scheme means someone passed a relative url. In our context only file relative urls make sense.
return new File( propertiesFile.getParentFile(), source.getSchemeSpecificPart() ).toURI();
}
else
{
return source;
}
}
private URI readDistroUrl()
throws URISyntaxException
{
if ( properties.getProperty( DISTRIBUTION_URL_PROPERTY ) != null )
{
return new URI( getProperty( DISTRIBUTION_URL_PROPERTY ) );
}
reportMissingProperty( DISTRIBUTION_URL_PROPERTY );
return null; // previous line will fail
}
private static void loadProperties( File propertiesFile, Properties properties )
throws IOException
{
InputStream inStream = new FileInputStream( propertiesFile );
try
{
properties.load( inStream );
}
finally
{
inStream.close();
}
}
/**
* Returns the distribution which this wrapper will use. Returns null if no wrapper meta-data was found in the
* specified project directory.
*/
public URI getDistribution()
{
return config.getDistribution();
}
/**
* Returns the configuration for this wrapper.
*/
public WrapperConfiguration getConfiguration()
{
return config;
}
public void execute( String[] args, Installer install, BootstrapMainStarter bootstrapMainStarter )
throws Exception
{
File mavenHome = install.createDist( config );
bootstrapMainStarter.start( args, mavenHome );
}
private String getProperty( String propertyName )
{
return getProperty( propertyName, null );
}
private String getProperty( String propertyName, String defaultValue )
{
String value = properties.getProperty( propertyName );
if ( value != null )
{
return value;
}
if ( defaultValue != null )
{
return defaultValue;
}
return reportMissingProperty( propertyName );
}
private String reportMissingProperty( String propertyName )
{
throw new RuntimeException( String.format( "No value with key '%s' specified in wrapper properties file '%s'.",
propertyName, propertiesFile ) );
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2009 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.apache.maven.wrapper.cli;
public abstract class AbstractCommandLineConverter<T>
implements CommandLineConverter<T>
{
public T convert( Iterable<String> args )
throws CommandLineArgumentException
{
CommandLineParser parser = new CommandLineParser();
configure( parser );
return convert( parser.parse( args ) );
}
public T convert( ParsedCommandLine args )
throws CommandLineArgumentException
{
return convert( args, newInstance() );
}
public T convert( Iterable<String> args, T target )
throws CommandLineArgumentException
{
CommandLineParser parser = new CommandLineParser();
configure( parser );
return convert( parser.parse( args ), target );
}
protected abstract T newInstance();
}

View File

@ -0,0 +1,60 @@
/*
* Copyright 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 org.apache.maven.wrapper.cli;
import java.util.HashMap;
import java.util.Map;
public abstract class AbstractPropertiesCommandLineConverter
extends AbstractCommandLineConverter<Map<String, String>>
{
protected abstract String getPropertyOption();
protected abstract String getPropertyOptionDetailed();
protected abstract String getPropertyOptionDescription();
public void configure( CommandLineParser parser )
{
CommandLineOption option = parser.option( getPropertyOption(), getPropertyOptionDetailed() );
option = option.hasArguments();
option.hasDescription( getPropertyOptionDescription() );
}
protected Map<String, String> newInstance()
{
return new HashMap<String, String>();
}
public Map<String, String> convert( ParsedCommandLine options, Map<String, String> properties )
throws CommandLineArgumentException
{
for ( String keyValueExpression : options.option( getPropertyOption() ).getValues() )
{
int pos = keyValueExpression.indexOf( "=" );
if ( pos < 0 )
{
properties.put( keyValueExpression, "" );
}
else
{
properties.put( keyValueExpression.substring( 0, pos ), keyValueExpression.substring( pos + 1 ) );
}
}
return properties;
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2009 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.apache.maven.wrapper.cli;
/**
* A {@code CommandLineArgumentException} is thrown when command-line arguments cannot be parsed.
*
* @author Hans Dockter
*/
public class CommandLineArgumentException
extends RuntimeException
{
public CommandLineArgumentException( String message )
{
super( message );
}
public CommandLineArgumentException( String message, Throwable cause )
{
super( message, cause );
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2009 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.apache.maven.wrapper.cli;
/**
* @author Hans Dockter
*/
public interface CommandLineConverter<T>
{
T convert( Iterable<String> args )
throws CommandLineArgumentException;
T convert( Iterable<String> args, T target )
throws CommandLineArgumentException;
T convert( ParsedCommandLine args )
throws CommandLineArgumentException;
T convert( ParsedCommandLine args, T target )
throws CommandLineArgumentException;
void configure( CommandLineParser parser );
}

View File

@ -0,0 +1,132 @@
/*
* Copyright 2010 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.apache.maven.wrapper.cli;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CommandLineOption
{
private final Set<String> options = new HashSet<String>();
private Class<?> argumentType = Void.TYPE;
private String description;
private String subcommand;
private String deprecationWarning;
private boolean incubating;
public CommandLineOption( Iterable<String> options )
{
for ( String option : options )
{
this.options.add( option );
}
}
public Set<String> getOptions()
{
return options;
}
public CommandLineOption hasArgument()
{
argumentType = String.class;
return this;
}
public CommandLineOption hasArguments()
{
argumentType = List.class;
return this;
}
public String getSubcommand()
{
return subcommand;
}
public CommandLineOption mapsToSubcommand( String command )
{
this.subcommand = command;
return this;
}
public String getDescription()
{
StringBuilder result = new StringBuilder();
if ( description != null )
{
result.append( description );
}
if ( deprecationWarning != null )
{
if ( result.length() > 0 )
{
result.append( ' ' );
}
result.append( "[deprecated - " );
result.append( deprecationWarning );
result.append( "]" );
}
if ( incubating )
{
if ( result.length() > 0 )
{
result.append( ' ' );
}
result.append( "[incubating]" );
}
return result.toString();
}
public CommandLineOption hasDescription( String description )
{
this.description = description;
return this;
}
public boolean getAllowsArguments()
{
return argumentType != Void.TYPE;
}
public boolean getAllowsMultipleArguments()
{
return argumentType == List.class;
}
public CommandLineOption deprecated( String deprecationWarning )
{
this.deprecationWarning = deprecationWarning;
return this;
}
public CommandLineOption incubating()
{
incubating = true;
return this;
}
public String getDeprecationWarning()
{
return deprecationWarning;
}
}

View File

@ -0,0 +1,675 @@
/*
* Copyright 2010 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.apache.maven.wrapper.cli;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Formatter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
/**
* <p>
* A command-line parser which supports a command/sub-command style command-line interface. Supports the following
* syntax:
* </p>
*
* <pre>
* &lt;option>* (&lt;sub-command> &lt;sub-command-option>*)*
* </pre>
* <ul>
* <li>Short options are a '-' followed by a single character. For example: {@code -a}.</li>
* <li>Long options are '--' followed by multiple characters. For example: {@code --long-option}.</li>
* <li>Options can take arguments. The argument follows the option. For example: {@code -a arg} or {@code --long arg}.</li>
* <li>Arguments can be attached to the option using '='. For example: {@code -a=arg} or {@code --long=arg}.</li>
* <li>Arguments can be attached to short options. For example: {@code -aarg}.</li>
* <li>Short options can be combined. For example {@code -ab} is equivalent to {@code -a -b}.</li>
* <li>Anything else is treated as an extra argument. This includes a single {@code -} character.</li>
* <li>'--' indicates the end of the options. Anything following is not parsed and is treated as extra arguments.</li>
* <li>The parser is forgiving, and allows '--' to be used with short options and '-' to be used with long options.</li>
* <li>The set of options must be known at parse time. Sub-commands and their options do not need to be known at parse
* time. Use {@link ParsedCommandLine#getExtraArguments()} to obtain the non-option command-line arguments.</li>
* </ul>
*/
public class CommandLineParser
{
private Map<String, CommandLineOption> optionsByString = new HashMap<String, CommandLineOption>();
private boolean allowMixedOptions;
private boolean allowUnknownOptions;
private final PrintWriter deprecationPrinter;
public CommandLineParser()
{
this( new OutputStreamWriter( System.out ) );
}
public CommandLineParser( Writer deprecationPrinter )
{
this.deprecationPrinter = new PrintWriter( deprecationPrinter );
}
/**
* Parses the given command-line.
*
* @param commandLine The command-line.
* @return The parsed command line.
* @throws org.apache.maven.wrapper.cli.CommandLineArgumentException On parse failure.
*/
public ParsedCommandLine parse( String... commandLine )
throws CommandLineArgumentException
{
return parse( Arrays.asList( commandLine ) );
}
/**
* Parses the given command-line.
*
* @param commandLine The command-line.
* @return The parsed command line.
* @throws org.apache.maven.wrapper.cli.CommandLineArgumentException On parse failure.
*/
public ParsedCommandLine parse( Iterable<String> commandLine )
throws CommandLineArgumentException
{
ParsedCommandLine parsedCommandLine =
new ParsedCommandLine( new HashSet<CommandLineOption>( optionsByString.values() ) );
ParserState parseState = new BeforeFirstSubCommand( parsedCommandLine );
for ( String arg : commandLine )
{
if ( parseState.maybeStartOption( arg ) )
{
if ( arg.equals( "--" ) )
{
parseState = new AfterOptions( parsedCommandLine );
}
else if ( arg.matches( "--[^=]+" ) )
{
OptionParserState parsedOption = parseState.onStartOption( arg, arg.substring( 2 ) );
parseState = parsedOption.onStartNextArg();
}
else if ( arg.matches( "--[^=]+=.*" ) )
{
int endArg = arg.indexOf( '=' );
OptionParserState parsedOption = parseState.onStartOption( arg, arg.substring( 2, endArg ) );
parseState = parsedOption.onArgument( arg.substring( endArg + 1 ) );
}
else if ( arg.matches( "-[^=]=.*" ) )
{
OptionParserState parsedOption = parseState.onStartOption( arg, arg.substring( 1, 2 ) );
parseState = parsedOption.onArgument( arg.substring( 3 ) );
}
else
{
assert arg.matches( "-[^-].*" );
String option = arg.substring( 1 );
if ( optionsByString.containsKey( option ) )
{
OptionParserState parsedOption = parseState.onStartOption( arg, option );
parseState = parsedOption.onStartNextArg();
}
else
{
String option1 = arg.substring( 1, 2 );
OptionParserState parsedOption;
if ( optionsByString.containsKey( option1 ) )
{
parsedOption = parseState.onStartOption( "-" + option1, option1 );
if ( parsedOption.getHasArgument() )
{
parseState = parsedOption.onArgument( arg.substring( 2 ) );
}
else
{
parseState = parsedOption.onComplete();
for ( int i = 2; i < arg.length(); i++ )
{
String optionStr = arg.substring( i, i + 1 );
parsedOption = parseState.onStartOption( "-" + optionStr, optionStr );
parseState = parsedOption.onComplete();
}
}
}
else
{
if ( allowUnknownOptions )
{
// if we are allowing unknowns, just pass through the whole arg
parsedOption = parseState.onStartOption( arg, option );
parseState = parsedOption.onComplete();
}
else
{
// We are going to throw a CommandLineArgumentException below, but want the message
// to reflect that we didn't recognise the first char (i.e. the option specifier)
parsedOption = parseState.onStartOption( "-" + option1, option1 );
parseState = parsedOption.onComplete();
}
}
}
}
}
else
{
parseState = parseState.onNonOption( arg );
}
}
parseState.onCommandLineEnd();
return parsedCommandLine;
}
public CommandLineParser allowMixedSubcommandsAndOptions()
{
allowMixedOptions = true;
return this;
}
public CommandLineParser allowUnknownOptions()
{
allowUnknownOptions = true;
return this;
}
/**
* Prints a usage message to the given stream.
*
* @param out The output stream to write to.
*/
public void printUsage( Appendable out )
{
Formatter formatter = new Formatter( out );
Set<CommandLineOption> orderedOptions = new TreeSet<CommandLineOption>( new OptionComparator() );
orderedOptions.addAll( optionsByString.values() );
Map<String, String> lines = new LinkedHashMap<String, String>();
for ( CommandLineOption option : orderedOptions )
{
Set<String> orderedOptionStrings = new TreeSet<String>( new OptionStringComparator() );
orderedOptionStrings.addAll( option.getOptions() );
List<String> prefixedStrings = new ArrayList<String>();
for ( String optionString : orderedOptionStrings )
{
if ( optionString.length() == 1 )
{
prefixedStrings.add( "-" + optionString );
}
else
{
prefixedStrings.add( "--" + optionString );
}
}
String key = join( prefixedStrings, ", " );
String value = option.getDescription();
if ( value == null || value.length() == 0 )
{
value = "";
}
lines.put( key, value );
}
int max = 0;
for ( String optionStr : lines.keySet() )
{
max = Math.max( max, optionStr.length() );
}
for ( Map.Entry<String, String> entry : lines.entrySet() )
{
if ( entry.getValue().length() == 0 )
{
formatter.format( "%s%n", entry.getKey() );
}
else
{
formatter.format( "%-" + max + "s %s%n", entry.getKey(), entry.getValue() );
}
}
formatter.flush();
}
private static String join( Collection<?> things, String separator )
{
StringBuffer buffer = new StringBuffer();
boolean first = true;
if ( separator == null )
{
separator = "";
}
for ( Object thing : things )
{
if ( !first )
{
buffer.append( separator );
}
buffer.append( thing.toString() );
first = false;
}
return buffer.toString();
}
/**
* Defines a new option. By default, the option takes no arguments and has no description.
*
* @param options The options values.
* @return The option, which can be further configured.
*/
public CommandLineOption option( String... options )
{
for ( String option : options )
{
if ( optionsByString.containsKey( option ) )
{
throw new IllegalArgumentException( String.format( "Option '%s' is already defined.", option ) );
}
if ( option.startsWith( "-" ) )
{
throw new IllegalArgumentException(
String.format( "Cannot add option '%s' as an option cannot start with '-'.",
option ) );
}
}
CommandLineOption option = new CommandLineOption( Arrays.asList( options ) );
for ( String optionStr : option.getOptions() )
{
this.optionsByString.put( optionStr, option );
}
return option;
}
private static class OptionString
{
private final String arg;
private final String option;
private OptionString( String arg, String option )
{
this.arg = arg;
this.option = option;
}
public String getDisplayName()
{
return arg.startsWith( "--" ) ? "--" + option : "-" + option;
}
@Override
public String toString()
{
return getDisplayName();
}
}
private static abstract class ParserState
{
public abstract boolean maybeStartOption( String arg );
boolean isOption( String arg )
{
return arg.matches( "-.+" );
}
public abstract OptionParserState onStartOption( String arg, String option );
public abstract ParserState onNonOption( String arg );
public void onCommandLineEnd()
{
}
}
private abstract class OptionAwareParserState
extends ParserState
{
protected final ParsedCommandLine commandLine;
protected OptionAwareParserState( ParsedCommandLine commandLine )
{
this.commandLine = commandLine;
}
@Override
public boolean maybeStartOption( String arg )
{
return isOption( arg );
}
@Override
public ParserState onNonOption( String arg )
{
commandLine.addExtraValue( arg );
return allowMixedOptions ? new AfterFirstSubCommand( commandLine ) : new AfterOptions( commandLine );
}
}
private class BeforeFirstSubCommand
extends OptionAwareParserState
{
private BeforeFirstSubCommand( ParsedCommandLine commandLine )
{
super( commandLine );
}
@Override
public OptionParserState onStartOption( String arg, String option )
{
OptionString optionString = new OptionString( arg, option );
CommandLineOption commandLineOption = optionsByString.get( option );
if ( commandLineOption == null )
{
if ( allowUnknownOptions )
{
return new UnknownOptionParserState( arg, commandLine, this );
}
else
{
throw new CommandLineArgumentException( String.format( "Unknown command-line option '%s'.",
optionString ) );
}
}
return new KnownOptionParserState( optionString, commandLineOption, commandLine, this );
}
}
private class AfterFirstSubCommand
extends OptionAwareParserState
{
private AfterFirstSubCommand( ParsedCommandLine commandLine )
{
super( commandLine );
}
@Override
public OptionParserState onStartOption( String arg, String option )
{
CommandLineOption commandLineOption = optionsByString.get( option );
if ( commandLineOption == null )
{
return new UnknownOptionParserState( arg, commandLine, this );
}
return new KnownOptionParserState( new OptionString( arg, option ), commandLineOption, commandLine, this );
}
}
private static class AfterOptions
extends ParserState
{
private final ParsedCommandLine commandLine;
private AfterOptions( ParsedCommandLine commandLine )
{
this.commandLine = commandLine;
}
@Override
public boolean maybeStartOption( String arg )
{
return false;
}
@Override
public OptionParserState onStartOption( String arg, String option )
{
return new UnknownOptionParserState( arg, commandLine, this );
}
@Override
public ParserState onNonOption( String arg )
{
commandLine.addExtraValue( arg );
return this;
}
}
private static class MissingOptionArgState
extends ParserState
{
private final OptionParserState option;
private MissingOptionArgState( OptionParserState option )
{
this.option = option;
}
@Override
public boolean maybeStartOption( String arg )
{
return isOption( arg );
}
@Override
public OptionParserState onStartOption( String arg, String option )
{
return this.option.onComplete().onStartOption( arg, option );
}
@Override
public ParserState onNonOption( String arg )
{
return option.onArgument( arg );
}
@Override
public void onCommandLineEnd()
{
option.onComplete();
}
}
private static abstract class OptionParserState
{
public abstract ParserState onStartNextArg();
public abstract ParserState onArgument( String argument );
public abstract boolean getHasArgument();
public abstract ParserState onComplete();
}
private class KnownOptionParserState
extends OptionParserState
{
private final OptionString optionString;
private final CommandLineOption option;
private final ParsedCommandLine commandLine;
private final ParserState state;
private final List<String> values = new ArrayList<String>();
private KnownOptionParserState( OptionString optionString, CommandLineOption option,
ParsedCommandLine commandLine, ParserState state )
{
this.optionString = optionString;
this.option = option;
this.commandLine = commandLine;
this.state = state;
}
@Override
public ParserState onArgument( String argument )
{
if ( !getHasArgument() )
{
throw new CommandLineArgumentException(
String.format( "Command-line option '%s' does not take an argument.",
optionString ) );
}
if ( argument.length() == 0 )
{
throw new CommandLineArgumentException(
String.format( "An empty argument was provided for command-line option '%s'.",
optionString ) );
}
values.add( argument );
return onComplete();
}
@Override
public ParserState onStartNextArg()
{
if ( option.getAllowsArguments() && values.isEmpty() )
{
return new MissingOptionArgState( this );
}
return onComplete();
}
@Override
public boolean getHasArgument()
{
return option.getAllowsArguments();
}
@Override
public ParserState onComplete()
{
if ( getHasArgument() && values.isEmpty() )
{
throw new CommandLineArgumentException(
String.format( "No argument was provided for command-line option '%s'.",
optionString ) );
}
ParsedCommandLineOption parsedOption = commandLine.addOption( optionString.option, option );
if ( values.size() + parsedOption.getValues().size() > 1 && !option.getAllowsMultipleArguments() )
{
throw new CommandLineArgumentException(
String.format( "Multiple arguments were provided for command-line option '%s'.",
optionString ) );
}
for ( String value : values )
{
parsedOption.addArgument( value );
}
if ( option.getDeprecationWarning() != null )
{
deprecationPrinter.println( "The " + optionString + " option is deprecated - "
+ option.getDeprecationWarning() );
}
if ( option.getSubcommand() != null )
{
return state.onNonOption( option.getSubcommand() );
}
return state;
}
}
private static class UnknownOptionParserState
extends OptionParserState
{
private final ParserState state;
private final String arg;
private final ParsedCommandLine commandLine;
private UnknownOptionParserState( String arg, ParsedCommandLine commandLine, ParserState state )
{
this.arg = arg;
this.commandLine = commandLine;
this.state = state;
}
@Override
public boolean getHasArgument()
{
return true;
}
@Override
public ParserState onStartNextArg()
{
return onComplete();
}
@Override
public ParserState onArgument( String argument )
{
return onComplete();
}
@Override
public ParserState onComplete()
{
commandLine.addExtraValue( arg );
return state;
}
}
private static final class OptionComparator
implements Comparator<CommandLineOption>
{
public int compare( CommandLineOption option1, CommandLineOption option2 )
{
String min1 = Collections.min( option1.getOptions(), new OptionStringComparator() );
String min2 = Collections.min( option2.getOptions(), new OptionStringComparator() );
return new CaseInsensitiveStringComparator().compare( min1, min2 );
}
}
private static final class CaseInsensitiveStringComparator
implements Comparator<String>
{
public int compare( String option1, String option2 )
{
int diff = option1.compareToIgnoreCase( option2 );
if ( diff != 0 )
{
return diff;
}
return option1.compareTo( option2 );
}
}
private static final class OptionStringComparator
implements Comparator<String>
{
public int compare( String option1, String option2 )
{
boolean short1 = option1.length() == 1;
boolean short2 = option2.length() == 1;
if ( short1 && !short2 )
{
return -1;
}
if ( !short1 && short2 )
{
return 1;
}
return new CaseInsensitiveStringComparator().compare( option1, option2 );
}
}
}

View File

@ -0,0 +1,133 @@
/*
* Copyright 2010 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.apache.maven.wrapper.cli;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ParsedCommandLine
{
private final Map<String, ParsedCommandLineOption> optionsByString = new HashMap<String, ParsedCommandLineOption>();
private final Set<String> presentOptions = new HashSet<String>();
private final List<String> extraArguments = new ArrayList<String>();
ParsedCommandLine( Iterable<CommandLineOption> options )
{
for ( CommandLineOption option : options )
{
ParsedCommandLineOption parsedOption = new ParsedCommandLineOption();
for ( String optionStr : option.getOptions() )
{
optionsByString.put( optionStr, parsedOption );
}
}
}
@Override
public String toString()
{
return String.format( "options: %s, extraArguments: %s", quoteAndJoin( presentOptions ),
quoteAndJoin( extraArguments ) );
}
private String quoteAndJoin( Iterable<String> strings )
{
StringBuilder output = new StringBuilder();
boolean isFirst = true;
for ( String string : strings )
{
if ( !isFirst )
{
output.append( ", " );
}
output.append( "'" );
output.append( string );
output.append( "'" );
isFirst = false;
}
return output.toString();
}
/**
* Returns true if the given option is present in this command-line.
*
* @param option The option, without the '-' or '--' prefix.
* @return true if the option is present.
*/
public boolean hasOption( String option )
{
option( option );
return presentOptions.contains( option );
}
/**
* See also {@link #hasOption}.
*
* @param logLevelOptions the options to check
* @return true if any of the passed options is present
*/
public boolean hasAnyOption( Collection<String> logLevelOptions )
{
for ( String option : logLevelOptions )
{
if ( hasOption( option ) )
{
return true;
}
}
return false;
}
/**
* Returns the value of the given option.
*
* @param option The option, without the '-' or '--' prefix.
* @return The option. never returns null.
*/
public ParsedCommandLineOption option( String option )
{
ParsedCommandLineOption parsedOption = optionsByString.get( option );
if ( parsedOption == null )
{
throw new IllegalArgumentException( String.format( "Option '%s' not defined.", option ) );
}
return parsedOption;
}
public List<String> getExtraArguments()
{
return extraArguments;
}
void addExtraValue( String value )
{
extraArguments.add( value );
}
ParsedCommandLineOption addOption( String optionStr, CommandLineOption option )
{
ParsedCommandLineOption parsedOption = optionsByString.get( optionStr );
presentOptions.addAll( option.getOptions() );
return parsedOption;
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2010 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.apache.maven.wrapper.cli;
import java.util.ArrayList;
import java.util.List;
public class ParsedCommandLineOption
{
private final List<String> values = new ArrayList<String>();
public String getValue()
{
if ( !hasValue() )
{
throw new IllegalStateException( "Option does not have any value." );
}
if ( values.size() > 1 )
{
throw new IllegalStateException( "Option has multiple values." );
}
return values.get( 0 );
}
public List<String> getValues()
{
return values;
}
public void addArgument( String argument )
{
values.add( argument );
}
public boolean hasValue()
{
return !values.isEmpty();
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 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 org.apache.maven.wrapper.cli;
public class ProjectPropertiesCommandLineConverter
extends AbstractPropertiesCommandLineConverter
{
@Override
protected String getPropertyOption()
{
return "P";
}
@Override
protected String getPropertyOptionDetailed()
{
return "project-prop";
}
@Override
protected String getPropertyOptionDescription()
{
return "Set project property for the build script (e.g. -Pmyprop=myvalue).";
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2011 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.apache.maven.wrapper.cli;
public class SystemPropertiesCommandLineConverter
extends AbstractPropertiesCommandLineConverter
{
@Override
protected String getPropertyOption()
{
return "D";
}
@Override
protected String getPropertyOptionDetailed()
{
return "system-prop";
}
@Override
protected String getPropertyOptionDescription()
{
return "Set system property of the JVM (e.g. -Dmyprop=myvalue).";
}
}

View File

@ -0,0 +1,49 @@
package org.apache.maven.wrapper;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.net.URI;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
public class DownloaderTest
{
private DefaultDownloader download;
private File testDir;
private File downloadFile;
private File rootDir;
private URI sourceRoot;
private File remoteFile;
@Before
public void setUp()
throws Exception
{
download = new DefaultDownloader( "mvnw", "aVersion" );
testDir = new File( "target/test-files/DownloadTest" );
rootDir = new File( testDir, "root" );
downloadFile = new File( rootDir, "file" );
remoteFile = new File( testDir, "remoteFile" );
FileUtils.write( remoteFile, "sometext" );
sourceRoot = remoteFile.toURI();
}
@Test
public void testDownload()
throws Exception
{
assert !downloadFile.exists();
download.download( sourceRoot, downloadFile );
assert downloadFile.exists();
assertEquals( "sometext", FileUtils.readFileToString( downloadFile ) );
}
}

View File

@ -0,0 +1,196 @@
package org.apache.maven.wrapper;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
import java.net.URI;
import org.apache.commons.io.FileUtils;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Zip;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @author Hans Dockter
*/
public class InstallerTest
{
private File testDir = new File( "target/test-files/SystemPropertiesHandlerTest-" + System.currentTimeMillis() );
private Installer install;
private Downloader downloadMock;
private PathAssembler pathAssemblerMock;
private boolean downloadCalled;
private File zip;
private File distributionDir;
private File zipStore;
private File mavenHomeDir;
private File zipDestination;
private WrapperConfiguration configuration = new WrapperConfiguration();
private Downloader download;
private PathAssembler pathAssembler;
private PathAssembler.LocalDistribution localDistribution;
@Before
public void setup()
throws Exception
{
testDir.mkdirs();
downloadCalled = false;
configuration.setZipBase( PathAssembler.PROJECT_STRING );
configuration.setZipPath( "someZipPath" );
configuration.setDistributionBase( PathAssembler.MAVEN_USER_HOME_STRING );
configuration.setDistributionPath( "someDistPath" );
configuration.setDistribution( new URI( "http://server/maven-0.9.zip" ) );
configuration.setAlwaysDownload( false );
configuration.setAlwaysUnpack( false );
distributionDir = new File( testDir, "someDistPath" );
mavenHomeDir = new File( distributionDir, "maven-0.9" );
zipStore = new File( testDir, "zips" );
zipDestination = new File( zipStore, "maven-0.9.zip" );
download = mock( Downloader.class );
pathAssembler = mock( PathAssembler.class );
localDistribution = mock( PathAssembler.LocalDistribution.class );
when( localDistribution.getZipFile() ).thenReturn( zipDestination );
when( localDistribution.getDistributionDir() ).thenReturn( distributionDir );
when( pathAssembler.getDistribution( configuration ) ).thenReturn( localDistribution );
install = new Installer( download, pathAssembler );
}
private void createTestZip( File zipDestination )
throws Exception
{
File explodedZipDir = new File( testDir, "explodedZip" );
explodedZipDir.mkdirs();
zipDestination.getParentFile().mkdirs();
File mavenScript = new File( explodedZipDir, "maven-0.9/bin/mvn" );
mavenScript.getParentFile().mkdirs();
FileUtils.write( mavenScript, "something" );
zipTo( explodedZipDir, zipDestination );
}
public void testCreateDist()
throws Exception
{
File homeDir = install.createDist( configuration );
Assert.assertEquals( mavenHomeDir, homeDir );
Assert.assertTrue( homeDir.isDirectory() );
Assert.assertTrue( new File( homeDir, "bin/mvn" ).exists() );
Assert.assertTrue( zipDestination.exists() );
Assert.assertEquals( localDistribution, pathAssembler.getDistribution( configuration ) );
Assert.assertEquals( distributionDir, localDistribution.getDistributionDir() );
Assert.assertEquals( zipDestination, localDistribution.getZipFile() );
// download.download(new URI("http://some/test"), distributionDir);
// verify(download).download(new URI("http://some/test"), distributionDir);
}
@Test
public void testCreateDistWithExistingDistribution()
throws Exception
{
FileUtils.touch( zipDestination );
mavenHomeDir.mkdirs();
File someFile = new File( mavenHomeDir, "some-file" );
FileUtils.touch( someFile );
File homeDir = install.createDist( configuration );
Assert.assertEquals( mavenHomeDir, homeDir );
Assert.assertTrue( mavenHomeDir.isDirectory() );
Assert.assertTrue( new File( homeDir, "some-file" ).exists() );
Assert.assertTrue( zipDestination.exists() );
Assert.assertEquals( localDistribution, pathAssembler.getDistribution( configuration ) );
Assert.assertEquals( distributionDir, localDistribution.getDistributionDir() );
Assert.assertEquals( zipDestination, localDistribution.getZipFile() );
}
@Test
public void testCreateDistWithExistingDistAndZipAndAlwaysUnpackTrue()
throws Exception
{
createTestZip( zipDestination );
mavenHomeDir.mkdirs();
File garbage = new File( mavenHomeDir, "garbage" );
FileUtils.touch( garbage );
configuration.setAlwaysUnpack( true );
File homeDir = install.createDist( configuration );
Assert.assertEquals( mavenHomeDir, homeDir );
Assert.assertTrue( mavenHomeDir.isDirectory() );
Assert.assertFalse( new File( homeDir, "garbage" ).exists() );
Assert.assertTrue( zipDestination.exists() );
Assert.assertEquals( localDistribution, pathAssembler.getDistribution( configuration ) );
Assert.assertEquals( distributionDir, localDistribution.getDistributionDir() );
Assert.assertEquals( zipDestination, localDistribution.getZipFile() );
}
@Test
public void testCreateDistWithExistingZipAndDistAndAlwaysDownloadTrue()
throws Exception
{
createTestZip( zipDestination );
File garbage = new File( mavenHomeDir, "garbage" );
FileUtils.touch( garbage );
configuration.setAlwaysUnpack( true );
File homeDir = install.createDist( configuration );
Assert.assertEquals( mavenHomeDir, homeDir );
Assert.assertTrue( mavenHomeDir.isDirectory() );
Assert.assertTrue( new File( homeDir, "bin/mvn" ).exists() );
Assert.assertFalse( new File( homeDir, "garbage" ).exists() );
Assert.assertTrue( zipDestination.exists() );
Assert.assertEquals( localDistribution, pathAssembler.getDistribution( configuration ) );
Assert.assertEquals( distributionDir, localDistribution.getDistributionDir() );
Assert.assertEquals( zipDestination, localDistribution.getZipFile() );
// download.download(new URI("http://some/test"), distributionDir);
// verify(download).download(new URI("http://some/test"), distributionDir);
}
public void zipTo( File directoryToZip, File zipFile )
{
Zip zip = new Zip();
zip.setBasedir( directoryToZip );
zip.setDestFile( zipFile );
zip.setProject( new Project() );
Zip.WhenEmpty whenEmpty = new Zip.WhenEmpty();
whenEmpty.setValue( "create" );
zip.setWhenempty( whenEmpty );
zip.execute();
}
}

View File

@ -0,0 +1,145 @@
/*
* Copyright 2007-2008 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.apache.maven.wrapper;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.File;
import java.net.URI;
import java.util.regex.Pattern;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Test;
/**
* @author Hans Dockter
*/
public class PathAssemblerTest
{
public static final String TEST_MAVEN_USER_HOME = "someUserHome";
private PathAssembler pathAssembler = new PathAssembler( new File( TEST_MAVEN_USER_HOME ) );
final WrapperConfiguration configuration = new WrapperConfiguration();
@Before
public void setup()
{
configuration.setDistributionBase( PathAssembler.MAVEN_USER_HOME_STRING );
configuration.setDistributionPath( "somePath" );
configuration.setZipBase( PathAssembler.MAVEN_USER_HOME_STRING );
configuration.setZipPath( "somePath" );
}
@Test
public void distributionDirWithMavenUserHomeBase()
throws Exception
{
configuration.setDistribution( new URI( "http://server/dist/maven-0.9-bin.zip" ) );
File distributionDir = pathAssembler.getDistribution( configuration ).getDistributionDir();
assertThat( distributionDir.getName(), matchesRegexp( "[a-z0-9]+" ) );
assertThat( distributionDir.getParentFile(), equalTo( file( TEST_MAVEN_USER_HOME + "/somePath/maven-0.9-bin" ) ) );
}
@Test
public void distributionDirWithProjectBase()
throws Exception
{
configuration.setDistributionBase( PathAssembler.PROJECT_STRING );
configuration.setDistribution( new URI( "http://server/dist/maven-0.9-bin.zip" ) );
File distributionDir = pathAssembler.getDistribution( configuration ).getDistributionDir();
assertThat( distributionDir.getName(), matchesRegexp( "[a-z0-9]+" ) );
assertThat( distributionDir.getParentFile(), equalTo( file( currentDirPath() + "/somePath/maven-0.9-bin" ) ) );
}
@Test
public void distributionDirWithUnknownBase()
throws Exception
{
configuration.setDistribution( new URI( "http://server/dist/maven-1.0.zip" ) );
configuration.setDistributionBase( "unknownBase" );
try
{
pathAssembler.getDistribution( configuration );
fail();
}
catch ( RuntimeException e )
{
assertEquals( "Base: unknownBase is unknown", e.getMessage() );
}
}
@Test
public void distZipWithMavenUserHomeBase()
throws Exception
{
configuration.setDistribution( new URI( "http://server/dist/maven-1.0.zip" ) );
File dist = pathAssembler.getDistribution( configuration ).getZipFile();
assertThat( dist.getName(), equalTo( "maven-1.0.zip" ) );
assertThat( dist.getParentFile().getName(), matchesRegexp( "[a-z0-9]+" ) );
assertThat( dist.getParentFile().getParentFile(),
equalTo( file( TEST_MAVEN_USER_HOME + "/somePath/maven-1.0" ) ) );
}
@Test
public void distZipWithProjectBase()
throws Exception
{
configuration.setZipBase( PathAssembler.PROJECT_STRING );
configuration.setDistribution( new URI( "http://server/dist/maven-1.0.zip" ) );
File dist = pathAssembler.getDistribution( configuration ).getZipFile();
assertThat( dist.getName(), equalTo( "maven-1.0.zip" ) );
assertThat( dist.getParentFile().getName(), matchesRegexp( "[a-z0-9]+" ) );
assertThat( dist.getParentFile().getParentFile(), equalTo( file( currentDirPath() + "/somePath/maven-1.0" ) ) );
}
private File file( String path )
{
return new File( path );
}
private String currentDirPath()
{
return System.getProperty( "user.dir" );
}
public static <T extends CharSequence> Matcher<T> matchesRegexp( final String pattern )
{
return new BaseMatcher<T>()
{
public boolean matches( Object o )
{
return Pattern.compile( pattern ).matcher( (CharSequence) o ).matches();
}
public void describeTo( Description description )
{
description.appendText( "a CharSequence that matches regexp " ).appendValue( pattern );
}
};
}
}

View File

@ -0,0 +1,60 @@
package org.apache.maven.wrapper;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
public class SystemPropertiesHandlerTest
{
private File tmpDir = new File( "target/test-files/SystemPropertiesHandlerTest" );
@Before
public void setupTempDir()
{
tmpDir.mkdirs();
}
@Test
public void testParsePropertiesFile()
throws Exception
{
File propFile = new File( tmpDir, "props" );
Properties props = new Properties();
props.put( "a", "b" );
props.put( "systemProp.c", "d" );
props.put( "systemProp.", "e" );
FileOutputStream fos = null;
try
{
fos = new FileOutputStream( propFile );
props.store( fos, "" );
}
finally
{
IOUtils.closeQuietly( fos );
}
Map<String, String> expected = new HashMap<String, String>();
expected.put( "c", "d" );
assertThat( SystemPropertiesHandler.getSystemProperties( propFile ), equalTo( expected ) );
}
@Test
public void ifNoPropertyFileExistShouldReturnEmptyMap()
{
Map<String, String> expected = new HashMap<String, String>();
assertThat( SystemPropertiesHandler.getSystemProperties( new File( tmpDir, "unknown" ) ), equalTo( expected ) );
}
}

View File

@ -0,0 +1,192 @@
package org.apache.maven.wrapper;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
public class WrapperExecutorTest
{
private final Installer install;
private final BootstrapMainStarter start;
private File propertiesFile;
private Properties properties = new Properties();
private File testDir = new File( "target/test-files/SystemPropertiesHandlerTest-" + System.currentTimeMillis() );
private File mockInstallDir = new File( testDir, "mock-dir" );
public WrapperExecutorTest()
throws Exception
{
install = mock( Installer.class );
when( install.createDist( Mockito.any( WrapperConfiguration.class ) ) ).thenReturn( mockInstallDir );
start = mock( BootstrapMainStarter.class );
testDir.mkdirs();
propertiesFile = new File( testDir, "maven/wrapper/maven-wrapper.properties" );
properties.put( "distributionUrl", "http://server/test/maven.zip" );
properties.put( "distributionBase", "testDistBase" );
properties.put( "distributionPath", "testDistPath" );
properties.put( "zipStoreBase", "testZipBase" );
properties.put( "zipStorePath", "testZipPath" );
writePropertiesFile( properties, propertiesFile, "header" );
}
@Test
public void loadWrapperMetadataFromFile()
throws Exception
{
WrapperExecutor wrapper = WrapperExecutor.forWrapperPropertiesFile( propertiesFile, System.out );
Assert.assertEquals( new URI( "http://server/test/maven.zip" ), wrapper.getDistribution() );
Assert.assertEquals( new URI( "http://server/test/maven.zip" ), wrapper.getConfiguration().getDistribution() );
Assert.assertEquals( "testDistBase", wrapper.getConfiguration().getDistributionBase() );
Assert.assertEquals( "testDistPath", wrapper.getConfiguration().getDistributionPath() );
Assert.assertEquals( "testZipBase", wrapper.getConfiguration().getZipBase() );
Assert.assertEquals( "testZipPath", wrapper.getConfiguration().getZipPath() );
}
@Test
public void loadWrapperMetadataFromDirectory()
throws Exception
{
WrapperExecutor wrapper = WrapperExecutor.forProjectDirectory( testDir, System.out );
Assert.assertEquals( new URI( "http://server/test/maven.zip" ), wrapper.getDistribution() );
Assert.assertEquals( new URI( "http://server/test/maven.zip" ), wrapper.getConfiguration().getDistribution() );
Assert.assertEquals( "testDistBase", wrapper.getConfiguration().getDistributionBase() );
Assert.assertEquals( "testDistPath", wrapper.getConfiguration().getDistributionPath() );
Assert.assertEquals( "testZipBase", wrapper.getConfiguration().getZipBase() );
Assert.assertEquals( "testZipPath", wrapper.getConfiguration().getZipPath() );
}
@Test
public void useDefaultMetadataNoProeprtiesFile()
throws Exception
{
WrapperExecutor wrapper = WrapperExecutor.forProjectDirectory( new File( testDir, "unknown" ), System.out );
Assert.assertNull( wrapper.getDistribution() );
Assert.assertNull( wrapper.getConfiguration().getDistribution() );
Assert.assertEquals( PathAssembler.MAVEN_USER_HOME_STRING, wrapper.getConfiguration().getDistributionBase() );
Assert.assertEquals( Installer.DEFAULT_DISTRIBUTION_PATH, wrapper.getConfiguration().getDistributionPath() );
Assert.assertEquals( PathAssembler.MAVEN_USER_HOME_STRING, wrapper.getConfiguration().getZipBase() );
Assert.assertEquals( Installer.DEFAULT_DISTRIBUTION_PATH, wrapper.getConfiguration().getZipPath() );
}
@Test
public void propertiesFileOnlyContainsDistURL()
throws Exception
{
properties = new Properties();
properties.put( "distributionUrl", "http://server/test/maven.zip" );
writePropertiesFile( properties, propertiesFile, "header" );
WrapperExecutor wrapper = WrapperExecutor.forWrapperPropertiesFile( propertiesFile, System.out );
Assert.assertEquals( new URI( "http://server/test/maven.zip" ), wrapper.getDistribution() );
Assert.assertEquals( new URI( "http://server/test/maven.zip" ), wrapper.getConfiguration().getDistribution() );
Assert.assertEquals( PathAssembler.MAVEN_USER_HOME_STRING, wrapper.getConfiguration().getDistributionBase() );
Assert.assertEquals( Installer.DEFAULT_DISTRIBUTION_PATH, wrapper.getConfiguration().getDistributionPath() );
Assert.assertEquals( PathAssembler.MAVEN_USER_HOME_STRING, wrapper.getConfiguration().getZipBase() );
Assert.assertEquals( Installer.DEFAULT_DISTRIBUTION_PATH, wrapper.getConfiguration().getZipPath() );
}
@Test
public void executeInstallAndLaunch()
throws Exception
{
WrapperExecutor wrapper = WrapperExecutor.forProjectDirectory( propertiesFile, System.out );
wrapper.execute( new String[] { "arg" }, install, start );
verify( install ).createDist( Mockito.any( WrapperConfiguration.class ) );
verify( start ).start( new String[] { "arg" }, mockInstallDir );
}
@Test( )
public void failWhenDistNotSetInProperties()
throws Exception
{
properties = new Properties();
writePropertiesFile( properties, propertiesFile, "header" );
try
{
WrapperExecutor.forWrapperPropertiesFile( propertiesFile, System.out );
Assert.fail( "Expected RuntimeException" );
}
catch ( RuntimeException e )
{
Assert.assertEquals( "Could not load wrapper properties from '" + propertiesFile + "'.", e.getMessage() );
Assert.assertEquals( "No value with key 'distributionUrl' specified in wrapper properties file '"
+ propertiesFile + "'.", e.getCause().getMessage() );
}
}
@Test
public void failWhenPropertiesFileDoesNotExist()
{
propertiesFile = new File( testDir, "unknown.properties" );
try
{
WrapperExecutor.forWrapperPropertiesFile( propertiesFile, System.out );
Assert.fail( "Expected RuntimeException" );
}
catch ( RuntimeException e )
{
Assert.assertEquals( "Wrapper properties file '" + propertiesFile + "' does not exist.", e.getMessage() );
}
}
@Test
public void testRelativeDistUrl()
throws Exception
{
properties = new Properties();
properties.put( "distributionUrl", "some/relative/url/to/bin.zip" );
writePropertiesFile( properties, propertiesFile, "header" );
WrapperExecutor wrapper = WrapperExecutor.forWrapperPropertiesFile( propertiesFile, System.out );
Assert.assertNotEquals( "some/relative/url/to/bin.zip", wrapper.getDistribution().getSchemeSpecificPart() );
Assert.assertTrue( wrapper.getDistribution().getSchemeSpecificPart().endsWith( "some/relative/url/to/bin.zip" ) );
}
private void writePropertiesFile( Properties properties, File propertiesFile, String message )
throws Exception
{
propertiesFile.getParentFile().mkdirs();
OutputStream outStream = null;
try
{
outStream = new FileOutputStream( propertiesFile );
properties.store( outStream, message );
}
finally
{
IOUtils.closeQuietly( outStream );
}
}
}

View File

@ -0,0 +1,5 @@
distributionUrl=http://server/test/maven.zip
distributionBase=testDistBase
zipStoreBase=testZipBase
distributionPath=testDistPath
zipStorePath=testZipPath