├── .gitignore ├── .travis.yml ├── LICENSE ├── README.org ├── maven ├── maven-wrapper.jar └── maven-wrapper.properties ├── mvnw ├── mvnw.bat ├── pom.xml └── src ├── main ├── java │ └── org │ │ └── apache │ │ └── maven │ │ └── wrapper │ │ ├── BootstrapMainStarter.java │ │ ├── Checksum.java │ │ ├── DefaultDownloader.java │ │ ├── Downloader.java │ │ ├── Installer.java │ │ ├── MavenWrapperMain.java │ │ ├── MavenWrapperMojo.java │ │ ├── PathAssembler.java │ │ ├── SystemPropertiesHandler.java │ │ ├── WrapperConfiguration.java │ │ ├── WrapperExecutor.java │ │ └── cli │ │ ├── AbstractCommandLineConverter.java │ │ ├── AbstractPropertiesCommandLineConverter.java │ │ ├── CommandLineArgumentException.java │ │ ├── CommandLineConverter.java │ │ ├── CommandLineOption.java │ │ ├── CommandLineParser.java │ │ ├── ParsedCommandLine.java │ │ ├── ParsedCommandLineOption.java │ │ ├── ProjectPropertiesCommandLineConverter.java │ │ └── SystemPropertiesCommandLineConverter.java └── resources │ ├── com │ └── rimerosolutions │ │ └── maven │ │ └── plugins │ │ └── wrapper │ │ ├── mvnw_footer │ │ ├── mvnw_footer.bat │ │ ├── mvnw_header │ │ └── mvnw_header.bat │ └── maven_wrapper_logging.properties └── test ├── java └── org │ └── apache │ └── maven │ └── wrapper │ ├── DownloaderTest.java │ ├── InstallerTest.java │ ├── MavenWrapperMojoTest.java │ ├── PathAssemblerTest.java │ ├── SystemPropertiesHandlerTest.java │ └── WrapperExecutorTest.java └── resources └── org └── apache └── maven └── wrapper ├── dummy-wrapper-artifact.txt ├── plugin-config.xml └── wrapper.properties /.gitignore: -------------------------------------------------------------------------------- 1 | ### OSX ### 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | .DocumentRevisions-V100 6 | .fseventsd 7 | .Spotlight-V100 8 | .TemporaryItems 9 | .Trashes 10 | .VolumeIcon.icns 11 | 12 | ### Eclipse ### 13 | .metadata 14 | *.tmp 15 | *.bak 16 | *.swp 17 | *~.nib 18 | .settings/ 19 | .loadpath 20 | .project 21 | .externalToolBuilders/ 22 | *.launch 23 | .classpath 24 | 25 | ### Emacs ### 26 | .projectile 27 | TAGS 28 | 29 | ### IntelliJ ### 30 | .idea/ 31 | *.iml 32 | 33 | ### Maven ### 34 | target/ 35 | pom.xml.tag 36 | pom.xml.releaseBackup 37 | pom.xml.versionsBackup 38 | pom.xml.next 39 | release.properties 40 | dependency-reduced-pom.xml 41 | buildNumber.properties 42 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | install: ./mvnw clean 3 | jdk: 4 | - openjdk6 5 | script: ./mvnw test 6 | notifications: 7 | email: false 8 | branches: 9 | only: 10 | - master 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Maven Command Line Wrapper 2 | 3 | [[https://github.com/rimerosolutions/maven-wrapper/blob/master/LICENSE][file:https://img.shields.io/hexpm/l/plug.svg]] 4 | [[https://travis-ci.org/rimerosolutions/maven-wrapper/][file:https://travis-ci.org/rimerosolutions/maven-wrapper.png]] 5 | [[http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22wrapper-maven-plugin%22][file:https://img.shields.io/maven-central/v/com.rimerosolutions.maven.plugins/wrapper-maven-plugin.svg]] 6 | 7 | *IMPORTANT: This project is officially retired* 8 | - I haven't updated this for a while 9 | - There was a [[https://github.com/bdemers/maven-wrapper][lack of clarity and communication with bdemers]] few years ago that led me to fork his project 10 | - Takari then [[https://github.com/takari/maven-wrapper][also did his own thing]] 11 | - I see that the maven wrapper is [[https://maven.apache.org/wrapper/][now officially part of the Maven project]] 12 | 13 | * Overview 14 | This is a copy of the [[http://www.gradle.org/docs/current/userguide/gradle_wrapper.html][Gradle wrapper]] ported for use with [[http://maven.apache.org][Apache Maven]]. =maven-wrapper= is available from [[http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.rimerosolutions.maven.plugins%22][Maven Central]]. 15 | 16 | The Maven Command Line Wrapper will auto-download and install Apache Maven from the Internet and then run your Maven goals. 17 | =maven-wrapper= ships as Maven plugin that generates wrapper scripts and a configuration file to bootstrap Maven download and installation. 18 | 19 | ** Rationale 20 | This is a fork of [[https://github.com/bdemers/maven-wrapper][bdemers' maven-wrapper]] in order to provide the Maven Wrapper as a Maven plugin, for more flexible reuse/integration. Once you have a Maven project that you want to distribute, you can generate a wrapper so that: 21 | 22 | - The target audience can easily execute Maven goals without an existing Maven application as a pre-requisite. 23 | - You can control the version of Maven that is to be used to build the project, if are versions compatibility concerns. 24 | 25 | ** Integration example 26 | 27 | For a full and small practical integration example, checkout the [[https://github.com/rimerosolutions/maven-wrapper-example][Maven Command Line Wrapper Example]] project. 28 | 29 | If you used to run 30 | 31 | : mvn clean install 32 | 33 | Then you would now run (without a leading =./= for MS Windows) 34 | : ./mvnw clean install 35 | 36 | A wrapper created with Maven 3.0.4 will request Maven 3.0.4, if it's not already installed on the user's machine. 37 | However, you can still request a specific Maven version by overriding the default behaviour (Maven plugin configuration). 38 | 39 | Notes: You need a valid JDK at least 1.6. The plugin was tested with Maven 3.0.2 and above. 40 | 41 | * Maven Goals and Usage 42 | For the list of goals and a usage guide, please consult the [[https://github.com/rimerosolutions/maven-wrapper/wiki][Wiki]]. 43 | 44 | * Generating the Maven wrapper 45 | After integrating the wrapper into your Maven project (plugin section), run the following command to generate the wrapper. 46 | 47 | : mvn wrapper:wrapper 48 | 49 | The =mvnw= and =mwnw.bat= command wrappers are generated at the root of the project folder. 50 | 51 | The =maven= folder is generated with the relevant jar and properties file in the project directory. 52 | 53 | You can now start using either the =mvnw= or =mvnw.bat= commands on any project without an existing maven installation! 54 | 55 | * Articles 56 | [[http://jakub.marchwicki.pl/posts/2015/06/04/maven-wrapper/]] 57 | 58 | * Contributing 59 | Pull requests, issues creation, suggestions, documentation improvements are welcome. 60 | 61 | Big thank you to all of you who contributed to this project so far. 62 | -------------------------------------------------------------------------------- /maven/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rimerosolutions/maven-wrapper/ee32ba95b3542663d53ef6e9a0ca147b9bbc11fc/maven/maven-wrapper.jar -------------------------------------------------------------------------------- /maven/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Maven download properties 2 | #Sun Jun 05 16:36:09 EDT 2016 3 | checksumAlgorithm=MD5 4 | verifyDownload=true 5 | distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.2.5/apache-maven-3.2.5-bin.zip 6 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # 58 | # Look for the Apple JDKs first to preserve the existing behaviour, and then look 59 | # for the new JDKs provided by Oracle. 60 | # 61 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then 62 | # 63 | # Apple JDKs 64 | # 65 | export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home 66 | fi 67 | 68 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then 69 | # 70 | # Apple JDKs 71 | # 72 | export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 73 | fi 74 | 75 | if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then 76 | # 77 | # Oracle JDKs 78 | # 79 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 80 | fi 81 | 82 | if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then 83 | # 84 | # Apple JDKs 85 | # 86 | export JAVA_HOME=`/usr/libexec/java_home` 87 | fi 88 | ;; 89 | esac 90 | 91 | if [ -z "$JAVA_HOME" ] ; then 92 | if [ -r /etc/gentoo-release ] ; then 93 | JAVA_HOME=`java-config --jre-home` 94 | fi 95 | fi 96 | 97 | if [ -z "$M2_HOME" ] ; then 98 | ## resolve links - $0 may be a link to maven's home 99 | PRG="$0" 100 | 101 | # need this for relative symlinks 102 | while [ -h "$PRG" ] ; do 103 | ls=`ls -ld "$PRG"` 104 | link=`expr "$ls" : '.*-> \(.*\)$'` 105 | if expr "$link" : '/.*' > /dev/null; then 106 | PRG="$link" 107 | else 108 | PRG="`dirname "$PRG"`/$link" 109 | fi 110 | done 111 | 112 | saveddir=`pwd` 113 | 114 | M2_HOME=`dirname "$PRG"`/.. 115 | 116 | # make it fully qualified 117 | M2_HOME=`cd "$M2_HOME" && pwd` 118 | 119 | cd "$saveddir" 120 | # echo Using m2 at $M2_HOME 121 | fi 122 | 123 | # For Cygwin, ensure paths are in UNIX format before anything is touched 124 | if $cygwin ; then 125 | [ -n "$M2_HOME" ] && 126 | M2_HOME=`cygpath --unix "$M2_HOME"` 127 | [ -n "$JAVA_HOME" ] && 128 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 129 | [ -n "$CLASSPATH" ] && 130 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 131 | fi 132 | 133 | # For Migwn, ensure paths are in UNIX format before anything is touched 134 | if $mingw ; then 135 | [ -n "$M2_HOME" ] && 136 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 137 | [ -n "$JAVA_HOME" ] && 138 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 139 | # TODO classpath? 140 | fi 141 | 142 | if [ -z "$JAVA_HOME" ]; then 143 | javaExecutable="`which javac`" 144 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 145 | # readlink(1) is not available as standard on Solaris 10. 146 | readLink=`which readlink` 147 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 148 | if $darwin ; then 149 | javaHome="`dirname \"$javaExecutable\"`" 150 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 151 | else 152 | javaExecutable="`readlink -f \"$javaExecutable\"`" 153 | fi 154 | javaHome="`dirname \"$javaExecutable\"`" 155 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 156 | JAVA_HOME="$javaHome" 157 | export JAVA_HOME 158 | fi 159 | fi 160 | fi 161 | 162 | if [ -z "$JAVACMD" ] ; then 163 | if [ -n "$JAVA_HOME" ] ; then 164 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 165 | # IBM's JDK on AIX uses strange locations for the executables 166 | JAVACMD="$JAVA_HOME/jre/sh/java" 167 | else 168 | JAVACMD="$JAVA_HOME/bin/java" 169 | fi 170 | else 171 | JAVACMD="`which java`" 172 | fi 173 | fi 174 | 175 | if [ ! -x "$JAVACMD" ] ; then 176 | echo "Error: JAVA_HOME is not defined correctly." >&2 177 | echo " We cannot execute $JAVACMD" >&2 178 | exit 1 179 | fi 180 | 181 | if [ -z "$JAVA_HOME" ] ; then 182 | echo "Warning: JAVA_HOME environment variable is not set." 183 | fi 184 | 185 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 186 | 187 | # For Cygwin, switch paths to Windows format before running java 188 | if $cygwin; then 189 | [ -n "$M2_HOME" ] && 190 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 191 | [ -n "$JAVA_HOME" ] && 192 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 193 | [ -n "$CLASSPATH" ] && 194 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 195 | fi 196 | 197 | # traverses directory structure from process work directory to filesystem root 198 | # first directory with .mvn subdirectory is considered project base directory 199 | find_maven_basedir() { 200 | local basedir=$(pwd) 201 | local wdir=$(pwd) 202 | while [ "$wdir" != '/' ] ; do 203 | wdir=$(cd "$wdir/.."; pwd) 204 | if [ -d "$wdir"/.mvn ] ; then 205 | basedir=$wdir 206 | break 207 | fi 208 | done 209 | echo "${basedir}" 210 | } 211 | 212 | # concatenates all lines of a file 213 | concat_lines() { 214 | if [ -f "$1" ]; then 215 | echo "$(tr -s '\n' ' ' < "$1")" 216 | fi 217 | } 218 | 219 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} 220 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 221 | 222 | # Provide a "standardized" way to retrieve the CLI args that will 223 | # work with both Windows and non-Windows executions. 224 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 225 | export MAVEN_CMD_LINE_ARGS 226 | 227 | WRAPPER_LAUNCHER="org.apache.maven.wrapper.MavenWrapperMain" 228 | 229 | exec "$JAVACMD" \ 230 | $MAVEN_OPTS \ 231 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 232 | -classpath \ 233 | "$MAVEN_PROJECTBASEDIR/maven/maven-wrapper.jar" \ 234 | ${WRAPPER_LAUNCHER} "$@" 235 | -------------------------------------------------------------------------------- /mvnw.bat: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto chkMHome 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | :chkMHome 80 | if not "%M2_HOME%"=="" goto valMHome 81 | 82 | SET "M2_HOME=%~dp0.." 83 | if not "%M2_HOME%"=="" goto valMHome 84 | 85 | echo. 86 | echo Error: M2_HOME not found in your environment. >&2 87 | echo Please set the M2_HOME variable in your environment to match the >&2 88 | echo location of the Maven installation. >&2 89 | echo. 90 | goto error 91 | 92 | :valMHome 93 | 94 | :stripMHome 95 | if not "_%M2_HOME:~-1%"=="_\" goto checkMCmd 96 | set "M2_HOME=%M2_HOME:~0,-1%" 97 | goto stripMHome 98 | 99 | :checkMCmd 100 | if exist "%M2_HOME%\bin\mvn.cmd" goto init 101 | 102 | echo. 103 | echo Error: M2_HOME is set to an invalid directory. >&2 104 | echo M2_HOME = "%M2_HOME%" >&2 105 | echo Please set the M2_HOME variable in your environment to match the >&2 106 | echo location of the Maven installation >&2 107 | echo. 108 | goto error 109 | @REM ==== END VALIDATION ==== 110 | 111 | :init 112 | 113 | set MAVEN_CMD_LINE_ARGS=%* 114 | 115 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 116 | @REM Fallback to current working directory if not found. 117 | 118 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 119 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 120 | 121 | set EXEC_DIR=%CD% 122 | set WDIR=%EXEC_DIR% 123 | :findBaseDir 124 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 125 | cd .. 126 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 127 | set WDIR=%CD% 128 | goto findBaseDir 129 | 130 | :baseDirFound 131 | set MAVEN_PROJECTBASEDIR=%WDIR% 132 | cd "%EXEC_DIR%" 133 | goto endDetectBaseDir 134 | 135 | :baseDirNotFound 136 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 137 | cd "%EXEC_DIR%" 138 | 139 | :endDetectBaseDir 140 | 141 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 142 | 143 | @setlocal EnableExtensions EnableDelayedExpansion 144 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 145 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 146 | 147 | :endReadAdditionalConfig 148 | 149 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 150 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\maven\maven-wrapper.jar" 151 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 152 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 153 | 154 | if ERRORLEVEL 1 goto error 155 | goto end 156 | 157 | :error 158 | set ERROR_CODE=1 159 | 160 | :end 161 | @endlocal & set ERROR_CODE=%ERROR_CODE% 162 | 163 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 164 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 165 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 166 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 167 | :skipRcPost 168 | 169 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 170 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 171 | 172 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 173 | 174 | exit /B %ERROR_CODE% 175 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | org.sonatype.oss 21 | oss-parent 22 | 7 23 | 24 | 25 | com.rimerosolutions.maven.plugins 26 | wrapper-maven-plugin 27 | 0.0.6-SNAPSHOT 28 | Maven Wrapper 29 | maven-plugin 30 | Maven Command Line Wrapper 31 | https://github.com/rimerosolutions/maven-wrapper/ 32 | 2013 33 | 34 | 35 | Rimero Solutions 36 | http://www.rimerosolutions.com 37 | 38 | 39 | 40 | 41 | The Apache Software License, Version 2.0 42 | http://www.apache.org/licenses/LICENSE-2.0.txt 43 | repo 44 | 45 | 46 | 47 | 48 | 49 | rimerosolutions 50 | Yves Zoundi 51 | rimerosolutions@gmail.com 52 | https://github.com/rimerosolutions 53 | Rimero Solutions 54 | http://www.rimerosolutions.com 55 | 56 | developer 57 | 58 | -5 59 | 60 | 61 | bdemers 62 | Brian Demers 63 | https://github.com/bdemers 64 | 65 | 66 | 67 | 68 | scm:git:https://github.com/rimerosolutions/maven-wrapper.git 69 | scm:git:https://github.com/rimerosolutions/maven-wrapper.git 70 | https://github.com/rimerosolutions/maven-wrapper 71 | 72 | 73 | 74 | UTF-8 75 | UTF-8 76 | 3.4 77 | 3.0.2 78 | 79 | 80 | 81 | 82 | org.apache.maven 83 | maven-core 84 | ${minimalMavenVersion} 85 | 86 | 87 | 88 | org.apache.maven 89 | maven-plugin-descriptor 90 | 2.2.1 91 | 92 | 93 | 94 | org.apache.maven 95 | maven-plugin-api 96 | ${minimalMavenVersion} 97 | 98 | 99 | 100 | org.apache.maven.plugin-tools 101 | maven-plugin-annotations 102 | ${maven.plugin.plugin.version} 103 | 105 | provided 106 | 107 | 108 | 109 | 110 | org.codehaus.plexus 111 | plexus-utils 112 | 3.0.1 113 | 114 | 115 | 116 | org.apache.maven.plugin-testing 117 | maven-plugin-testing-harness 118 | 2.1 119 | 120 | 121 | 122 | org.apache.maven 123 | maven-compat 124 | ${minimalMavenVersion} 125 | test 126 | 127 | 128 | 129 | junit 130 | junit 131 | 4.11 132 | test 133 | 134 | 135 | 136 | org.hamcrest 137 | hamcrest-all 138 | 1.3 139 | test 140 | 141 | 142 | 143 | org.mockito 144 | mockito-all 145 | 1.9.5 146 | test 147 | 148 | 149 | 150 | commons-lang 151 | commons-lang 152 | 2.6 153 | test 154 | 155 | 156 | 157 | commons-io 158 | commons-io 159 | 2.4 160 | test 161 | 162 | 163 | 164 | 165 | 166 | doclint-java8-disable 167 | 168 | [1.8,) 169 | 170 | 171 | 172 | 173 | org.apache.maven.plugins 174 | maven-javadoc-plugin 175 | 2.10.3 176 | 177 | -Xdoclint:none 178 | 179 | 180 | 181 | org.apache.maven.plugins 182 | maven-site-plugin 183 | 3.3 184 | 185 | 186 | 187 | org.apache.maven.plugins 188 | maven-javadoc-plugin 189 | 190 | -Xdoclint:none 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | org.apache.maven.plugins 205 | maven-plugin-plugin 206 | ${maven.plugin.plugin.version} 207 | 208 | 209 | true 210 | 211 | 212 | 213 | mojo-descriptor 214 | 215 | descriptor 216 | 217 | 218 | 219 | generated-helpmojo 220 | 221 | helpmojo 222 | 223 | 224 | 225 | 226 | 227 | org.apache.maven.plugins 228 | maven-compiler-plugin 229 | 3.3 230 | 231 | 1.6 232 | 1.6 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | org.apache.maven.plugins 242 | maven-plugin-plugin 243 | ${maven.plugin.plugin.version} 244 | 245 | 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/BootstrapMainStarter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import java.io.File; 19 | import java.lang.reflect.Method; 20 | import java.net.MalformedURLException; 21 | import java.net.URL; 22 | import java.net.URLClassLoader; 23 | 24 | /** 25 | * @author Hans Dockter 26 | */ 27 | public class BootstrapMainStarter { 28 | private static final String ERROR_TEMPLATE = "Could not locate the Maven launcher JAR in Maven distribution '%s'."; 29 | 30 | public void start(String[] args, File mavenHome) throws Exception { 31 | File mavenJar = findLauncherJar(mavenHome); 32 | ClassLoader contextClassLoader = createUrlClassLoader(mavenJar); 33 | Thread.currentThread().setContextClassLoader(contextClassLoader); 34 | Class mainClass = contextClassLoader.loadClass("org.codehaus.plexus.classworlds.launcher.Launcher"); 35 | 36 | System.setProperty("maven.home", mavenHome.getAbsolutePath()); 37 | System.setProperty("classworlds.conf", new File(mavenHome, "/bin/m2.conf").getAbsolutePath()); 38 | 39 | Method mainMethod = mainClass.getMethod("main", String[].class); 40 | mainMethod.invoke(null, new Object[] { args }); 41 | } 42 | 43 | private ClassLoader createUrlClassLoader(File mavenJar) throws MalformedURLException { 44 | URL[] urls = { mavenJar.toURI().toURL() }; 45 | ClassLoader parentClassLoader = ClassLoader.getSystemClassLoader().getParent(); 46 | URLClassLoader contextClassLoader = new URLClassLoader(urls, parentClassLoader); 47 | 48 | return contextClassLoader; 49 | } 50 | 51 | private File findLauncherJar(File mavenHome) { 52 | for (File file : new File(mavenHome, "boot").listFiles()) { 53 | if (file.getName().matches("plexus-classworlds-.*\\.jar")) { 54 | return file; 55 | } 56 | } 57 | throw new RuntimeException(String.format(ERROR_TEMPLATE, mavenHome)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/Checksum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016. Ville Koskela 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | import java.security.MessageDigest; 21 | import java.security.NoSuchAlgorithmException; 22 | import java.util.Arrays; 23 | import java.util.HashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | /** 28 | * Enumeration of checksum algorithms. 29 | * 30 | * @author Ville Koskela 31 | */ 32 | public enum Checksum { 33 | 34 | SHA1("sha1", "SHA-1") { 35 | @Override 36 | protected MessageDigest getDigest() throws NoSuchAlgorithmException { 37 | return MessageDigest.getInstance("SHA-1"); 38 | } 39 | }, 40 | MD5("md5", "MD5") { 41 | @Override 42 | protected MessageDigest getDigest() throws NoSuchAlgorithmException { 43 | return MessageDigest.getInstance("MD5"); 44 | } 45 | }; 46 | 47 | private static final Map CHECKSUM_BY_ALIAS = new HashMap(); 48 | private static final char[] HEX_DIGITS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 49 | private static final int BUFFER_SIZE = 65535; 50 | private final String defaultExtension; 51 | private final List aliases; 52 | 53 | static { 54 | for (final Checksum checksum : Checksum.values()) { 55 | for (final String alias : checksum.aliases) { 56 | assert !CHECKSUM_BY_ALIAS.containsKey(alias) : "Duplicate checksum alias detected: " + alias; 57 | CHECKSUM_BY_ALIAS.put(alias, checksum); 58 | } 59 | } 60 | } 61 | 62 | Checksum(String defaultExtension, String... aliases) { 63 | this.defaultExtension = defaultExtension; 64 | this.aliases = Arrays.asList(aliases); 65 | } 66 | 67 | public static Checksum fromAlias(String alias) { 68 | return CHECKSUM_BY_ALIAS.get(alias); 69 | } 70 | 71 | public String getDefaultExtension() { 72 | return defaultExtension; 73 | } 74 | 75 | public boolean verify(InputStream data, String checksum) { 76 | return checksum.equals(generate(data)); 77 | } 78 | 79 | public String generate(InputStream data) { 80 | try { 81 | byte[] buffer = new byte[BUFFER_SIZE]; 82 | int length = 0; 83 | MessageDigest digest = getDigest(); 84 | while ((length = data.read(buffer)) > 0) { 85 | digest.update(buffer, 0, length); 86 | } 87 | return asHex(digest.digest()); 88 | } catch (IOException e) { 89 | throw new RuntimeException("Could not generate checksum for stream.", e); 90 | } catch (NoSuchAlgorithmException e) { 91 | throw new RuntimeException("Could not generate checksum for stream.", e); 92 | } 93 | } 94 | 95 | protected abstract MessageDigest getDigest() throws NoSuchAlgorithmException; 96 | 97 | private static String asHex(byte[] bytes) { 98 | final StringBuilder sb = new StringBuilder(2 * bytes.length); 99 | 100 | for (int i = 0; i < bytes.length; i++) { 101 | byte b = bytes[i]; 102 | sb.append(HEX_DIGITS[(b & 0xF0) >> 4]).append(HEX_DIGITS[(b & 0x0F)]); 103 | } 104 | 105 | return sb.toString(); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/DefaultDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.apache.maven.wrapper; 18 | 19 | import java.io.File; 20 | import java.io.FileOutputStream; 21 | import java.io.IOException; 22 | import java.net.Authenticator; 23 | import java.net.PasswordAuthentication; 24 | import java.net.URI; 25 | import java.net.URL; 26 | import java.net.URLConnection; 27 | import java.nio.ByteBuffer; 28 | import java.nio.channels.Channels; 29 | import java.nio.channels.ReadableByteChannel; 30 | import java.nio.channels.WritableByteChannel; 31 | 32 | /** 33 | * @author Hans Dockter 34 | */ 35 | public class DefaultDownloader implements Downloader { 36 | 37 | private static final int PROGRESS_CHUNK = 20000; 38 | private static final int BUFFER_SIZE = 10000; 39 | private final String applicationName; 40 | private final String applicationVersion; 41 | 42 | public DefaultDownloader(String applicationName, String applicationVersion) { 43 | this.applicationName = applicationName; 44 | this.applicationVersion = applicationVersion; 45 | configureProxyAuthentication(); 46 | } 47 | 48 | private void configureProxyAuthentication() { 49 | if (System.getProperty("http.proxyUser") != null) { 50 | Authenticator.setDefault(new SystemPropertiesProxyAuthenticator()); 51 | } 52 | } 53 | 54 | public void download(URI address, File destination) throws Exception { 55 | if (destination.exists()) { 56 | return; 57 | } 58 | 59 | destination.getParentFile().mkdirs(); 60 | downloadInternal(address, destination); 61 | } 62 | 63 | private void downloadInternal(URI address, File destination) throws IOException { 64 | WritableByteChannel out = null; 65 | URLConnection conn; 66 | ReadableByteChannel in = null; 67 | 68 | try { 69 | URL url = address.toURL(); 70 | out = Channels.newChannel(new FileOutputStream(destination)); 71 | conn = url.openConnection(); 72 | String userAgentValue = calculateUserAgent(); 73 | conn.setRequestProperty("User-Agent", userAgentValue); 74 | in = Channels.newChannel(conn.getInputStream()); 75 | int numRead; 76 | long progressCounter = 0; 77 | 78 | ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); 79 | 80 | while ((numRead = in.read(buffer)) >= 0 || buffer.position() > 0) { 81 | progressCounter += numRead; 82 | buffer.flip(); 83 | 84 | if (progressCounter / PROGRESS_CHUNK > 0) { 85 | System.out.print("."); 86 | progressCounter = progressCounter - PROGRESS_CHUNK; 87 | } 88 | 89 | out.write(buffer); 90 | buffer.clear(); 91 | } 92 | } finally { 93 | System.out.println(""); 94 | 95 | if (in != null) { 96 | in.close(); 97 | } 98 | 99 | if (out != null) { 100 | out.close(); 101 | } 102 | } 103 | } 104 | 105 | private String calculateUserAgent() { 106 | String javaVendor = System.getProperty("java.vendor"); 107 | String javaVersion = System.getProperty("java.version"); 108 | String javaVendorVersion = System.getProperty("java.vm.version"); 109 | String osName = System.getProperty("os.name"); 110 | String osVersion = System.getProperty("os.version"); 111 | String osArch = System.getProperty("os.arch"); 112 | return String.format("%s/%s (%s;%s;%s) (%s;%s;%s)", 113 | applicationName, 114 | applicationVersion, 115 | osName, 116 | osVersion, 117 | osArch, 118 | javaVendor, 119 | javaVersion, 120 | javaVendorVersion); 121 | } 122 | 123 | private static class SystemPropertiesProxyAuthenticator extends Authenticator { 124 | @Override 125 | protected PasswordAuthentication getPasswordAuthentication() { 126 | final String username = System.getProperty("http.proxyUser"); 127 | final char[] password = System.getProperty("http.proxyPassword", "").toCharArray(); 128 | 129 | return new PasswordAuthentication(username, password); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/Downloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import java.io.File; 19 | import java.net.URI; 20 | 21 | /** 22 | * @author Hans Dockter 23 | */ 24 | public interface Downloader { 25 | void download(URI address, File destination) throws Exception; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/Installer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.apache.maven.wrapper; 18 | 19 | import java.io.BufferedOutputStream; 20 | import java.io.BufferedReader; 21 | import java.io.File; 22 | import java.io.FileInputStream; 23 | import java.io.FileOutputStream; 24 | import java.io.IOException; 25 | import java.io.InputStream; 26 | import java.io.InputStreamReader; 27 | import java.io.OutputStream; 28 | import java.io.StringWriter; 29 | import java.net.URI; 30 | import java.util.ArrayList; 31 | import java.util.Deque; 32 | import java.util.Enumeration; 33 | import java.util.LinkedList; 34 | import java.util.List; 35 | import java.util.Locale; 36 | import java.util.logging.Logger; 37 | import java.util.zip.ZipEntry; 38 | import java.util.zip.ZipFile; 39 | 40 | import org.apache.maven.wrapper.PathAssembler.LocalDistribution; 41 | 42 | /** 43 | * @author Hans Dockter 44 | */ 45 | public class Installer { 46 | private static final Logger LOG = Logger.getLogger(Installer.class.getName()); 47 | public static final String DEFAULT_DISTRIBUTION_PATH = "wrapper/dists"; 48 | 49 | private final Downloader download; 50 | 51 | private final PathAssembler pathAssembler; 52 | 53 | public Installer(Downloader download, PathAssembler pathAssembler) { 54 | this.download = download; 55 | this.pathAssembler = pathAssembler; 56 | } 57 | 58 | public File createDist(WrapperConfiguration configuration) throws Exception { 59 | Exception failure = null; 60 | 61 | for (URI distributionUri : configuration.getDistributionUris()) { 62 | try { 63 | return createDistFromUri(configuration, distributionUri); 64 | } catch (Exception e) { 65 | LOG.warning(String.format("Maven distribution '%s' failed: %s", distributionUri, e.getMessage())); 66 | 67 | if (failure == null) { 68 | failure = e; 69 | } 70 | } 71 | } 72 | 73 | if (failure == null) { 74 | throw new RuntimeException("No distributions configured. Expected to find at least 1 distribution."); 75 | } 76 | 77 | throw failure; 78 | } 79 | 80 | private File createDistFromUri(final WrapperConfiguration configuration, final URI distributionUrl) throws Exception { 81 | boolean alwaysDownload = configuration.isAlwaysDownload(); 82 | boolean alwaysUnpack = configuration.isAlwaysUnpack(); 83 | 84 | LocalDistribution localDistribution = pathAssembler.getDistribution(configuration, distributionUrl); 85 | File localZipFile = localDistribution.getZipFile(); 86 | boolean downloaded = false; 87 | 88 | if (alwaysDownload || !localZipFile.exists()) { 89 | File tmpZipFile = new File(localZipFile.getParentFile(), localZipFile.getName() + ".part"); 90 | tmpZipFile.delete(); 91 | LOG.info(String.format("Downloading %s", distributionUrl)); 92 | download.download(distributionUrl, tmpZipFile); 93 | 94 | if (configuration.isVerifyDownload()) { 95 | File localChecksumFile = new File(localZipFile.getParentFile(), localZipFile.getName() + ".checksum"); 96 | verifyDistribution(configuration.getChecksumAlgorithm(), distributionUrl, localChecksumFile, tmpZipFile); 97 | } 98 | 99 | tmpZipFile.renameTo(localZipFile); 100 | downloaded = true; 101 | } 102 | 103 | File distDir = localDistribution.getDistributionDir(); 104 | List dirs = listDirs(distDir); 105 | 106 | if (downloaded || alwaysUnpack || dirs.isEmpty()) { 107 | for (File dir : dirs) { 108 | LOG.info(String.format("Deleting directory %s", dir.getAbsolutePath())); 109 | deleteDir(dir); 110 | } 111 | 112 | LOG.info(String.format("Unzipping %s to %s", localZipFile.getAbsolutePath(), distDir.getAbsolutePath())); 113 | unzip(localZipFile, distDir); 114 | dirs = listDirs(distDir); 115 | 116 | if (dirs.isEmpty()) { 117 | throw new RuntimeException( 118 | String.format("Maven distribution '%s' does not contain any directories. Expected to find exactly 1 directory.", 119 | distributionUrl)); 120 | } 121 | 122 | setExecutablePermissions(dirs.get(0)); 123 | } 124 | 125 | if (dirs.size() != 1) { 126 | throw new RuntimeException(String.format( 127 | "Maven distribution '%s' contains too many directories. Expected to find exactly 1 directory.", distributionUrl)); 128 | } 129 | 130 | return dirs.get(0); 131 | } 132 | 133 | private void verifyDistribution(Checksum checksum, 134 | URI distributionUri, 135 | File localChecksumFile, 136 | File distributionZipFile) throws Exception { 137 | File tmpZipFile = new File(localChecksumFile.getParentFile(), localChecksumFile.getName() + ".part"); 138 | tmpZipFile.delete(); 139 | 140 | URI checksumUri = URI.create(String.format("%s.%s", distributionUri.toString(), checksum.getDefaultExtension())); 141 | LOG.info(String.format("Verifying download with %s", checksumUri)); 142 | download.download(checksumUri, tmpZipFile); 143 | tmpZipFile.renameTo(localChecksumFile); 144 | 145 | BufferedReader checksumReader = null; 146 | 147 | try { 148 | checksumReader = new BufferedReader(new InputStreamReader(new FileInputStream(localChecksumFile), "UTF-8")); 149 | 150 | if (!checksum.verify(new FileInputStream(distributionZipFile), checksumReader.readLine())) { 151 | throw new RuntimeException( 152 | String.format("Maven distribution '%s' failed to verify against '%s'.", distributionUri, checksumUri)); 153 | } 154 | } finally { 155 | if (checksumReader != null) { 156 | checksumReader.close(); 157 | } 158 | } 159 | } 160 | 161 | private List listDirs(File distDir) { 162 | List dirs = new ArrayList(); 163 | 164 | if (distDir.exists()) { 165 | for (File file : distDir.listFiles()) { 166 | if (file.isDirectory()) { 167 | dirs.add(file); 168 | } 169 | } 170 | } 171 | 172 | return dirs; 173 | } 174 | 175 | private void setExecutablePermissions(File mavenHome) { 176 | if (isWindows()) { 177 | return; 178 | } 179 | 180 | File mavenCommand = new File(mavenHome, "bin/mvn"); 181 | String errorMessage = null; 182 | 183 | try { 184 | ProcessBuilder pb = new ProcessBuilder("chmod", "755", mavenCommand.getCanonicalPath()); 185 | Process p = pb.start(); 186 | 187 | if (p.waitFor() == 0) { 188 | LOG.info(String.format("Set executable permissions for: %s", mavenCommand.getAbsolutePath())); 189 | } else { 190 | BufferedReader is = null; 191 | 192 | try { 193 | is = new BufferedReader(new InputStreamReader(p.getInputStream())); 194 | StringWriter sw = new StringWriter(); 195 | 196 | for (String line; (line = is.readLine()) != null; ) { 197 | sw.write(String.format("%s%n", line)); 198 | } 199 | 200 | errorMessage = sw.toString(); 201 | sw.close(); 202 | } finally { 203 | if (is != null) { 204 | is.close(); 205 | } 206 | } 207 | } 208 | } catch (IOException e) { 209 | errorMessage = e.getMessage(); 210 | } catch (InterruptedException e) { 211 | errorMessage = e.getMessage(); 212 | } 213 | 214 | if (errorMessage != null) { 215 | LOG.warning("Could not set executable permissions for: " + mavenCommand.getAbsolutePath()); 216 | LOG.warning("Please do this manually if you want to use maven."); 217 | } 218 | } 219 | 220 | private boolean isWindows() { 221 | String osName = System.getProperty("os.name").toLowerCase(Locale.US); 222 | 223 | if (osName.indexOf("windows") > -1) { 224 | return true; 225 | } 226 | 227 | return false; 228 | } 229 | 230 | private boolean deleteDir(File dir) { 231 | if (dir == null) { 232 | throw new IllegalArgumentException("Cannot delete null directory"); 233 | } 234 | 235 | Deque fileDeque = new LinkedList(); 236 | File[] currentFileList; 237 | fileDeque.offerFirst(dir); 238 | 239 | while (!fileDeque.isEmpty()) { 240 | if (fileDeque.peekFirst().isDirectory()) { 241 | currentFileList = fileDeque.peekFirst().listFiles(); 242 | 243 | if (currentFileList != null && currentFileList.length > 0) { 244 | for (File currentFile : currentFileList) { 245 | fileDeque.offerFirst(currentFile); 246 | } 247 | } else { 248 | if (!deleteFile(fileDeque.pollFirst())) { 249 | return false; 250 | } 251 | } 252 | } else { 253 | if (!deleteFile(fileDeque.pollFirst())) { 254 | return false; 255 | } 256 | } 257 | } 258 | 259 | return true; 260 | } 261 | 262 | private boolean deleteFile(File file) { 263 | return file != null && file.exists() && file.delete(); 264 | } 265 | 266 | public void unzip(File zip, File dest) throws IOException { 267 | Enumeration entries; 268 | ZipFile zipFile; 269 | 270 | zipFile = new ZipFile(zip); 271 | 272 | entries = zipFile.entries(); 273 | 274 | while (entries.hasMoreElements()) { 275 | ZipEntry entry = (ZipEntry) entries.nextElement(); 276 | 277 | if (entry.isDirectory()) { 278 | (new File(dest, entry.getName())).mkdirs(); 279 | continue; 280 | } 281 | 282 | copyInputStream(zipFile.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(new File(dest, entry.getName())))); 283 | } 284 | 285 | zipFile.close(); 286 | } 287 | 288 | public void copyInputStream(InputStream in, OutputStream out) throws IOException { 289 | IOException ioe = null; 290 | 291 | try { 292 | byte[] buffer = new byte[2048]; 293 | int len; 294 | 295 | while ((len = in.read(buffer)) >= 0) { 296 | out.write(buffer, 0, len); 297 | } 298 | } finally { 299 | try { 300 | if (in != null) { 301 | in.close(); 302 | } 303 | } catch (IOException ex) { 304 | if (ioe == null) { 305 | ioe = ex; 306 | } 307 | } 308 | 309 | try { 310 | if (out != null) { 311 | out.close(); 312 | } 313 | } catch (IOException ex) { 314 | if (ioe == null) { 315 | ioe = ex; 316 | } 317 | } 318 | } 319 | 320 | if (ioe != null) { 321 | throw ioe; 322 | } 323 | } 324 | 325 | } 326 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/MavenWrapperMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.apache.maven.wrapper; 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.net.URI; 23 | import java.net.URISyntaxException; 24 | import java.util.Map; 25 | import java.util.Properties; 26 | import java.util.logging.LogManager; 27 | import java.util.logging.Logger; 28 | 29 | import org.apache.maven.wrapper.cli.CommandLineParser; 30 | import org.apache.maven.wrapper.cli.SystemPropertiesCommandLineConverter; 31 | 32 | /** 33 | * @author Hans Dockter 34 | */ 35 | public class MavenWrapperMain { 36 | public static final String DEFAULT_MAVEN_USER_HOME = System.getProperty("user.home") + "/.m2"; 37 | public static final String MAVEN_PROPERTIES_FILENAME = "maven.properties"; 38 | public static final String MAVEN_USER_HOME_PROPERTY_KEY = "maven.user.home"; 39 | public static final String MAVEN_USER_HOME_ENV_KEY = "MAVEN_USER_HOME"; 40 | private static final String LOGGING_PROPERTIES_PATH = "maven_wrapper_logging.properties"; 41 | 42 | static { 43 | setupLogging(LOGGING_PROPERTIES_PATH); 44 | } 45 | 46 | public static void main(String[] args) throws Exception { 47 | File wrapperJar = wrapperJar(); 48 | File propertiesFile = wrapperProperties(wrapperJar); 49 | File rootDir = rootDir(wrapperJar); 50 | 51 | Properties systemProperties = System.getProperties(); 52 | systemProperties.putAll(parseSystemPropertiesFromArgs(args)); 53 | addSystemProperties(rootDir); 54 | 55 | WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 56 | wrapperExecutor.execute(args, new Installer(new DefaultDownloader("mvnw", wrapperVersion()), new PathAssembler(mavenUserHome())), 57 | new BootstrapMainStarter()); 58 | } 59 | 60 | private static void setupLogging(String logConfigPath) { 61 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 62 | InputStream inputStream = classLoader.getResourceAsStream(logConfigPath); 63 | 64 | try { 65 | LogManager.getLogManager().readConfiguration(inputStream); 66 | } catch (final IOException e) { 67 | Logger.getAnonymousLogger().severe(String.format("Could not load default %s file", logConfigPath)); 68 | Logger.getAnonymousLogger().severe(e.getMessage()); 69 | } 70 | } 71 | 72 | private static Map parseSystemPropertiesFromArgs(String[] args) { 73 | SystemPropertiesCommandLineConverter converter = new SystemPropertiesCommandLineConverter(); 74 | CommandLineParser commandLineParser = new CommandLineParser(); 75 | converter.configure(commandLineParser); 76 | commandLineParser.allowUnknownOptions(); 77 | return converter.convert(commandLineParser.parse(args)); 78 | } 79 | 80 | private static void addSystemProperties(File rootDir) { 81 | System.getProperties().putAll(SystemPropertiesHandler.getSystemProperties(new File(mavenUserHome(), MAVEN_PROPERTIES_FILENAME))); 82 | System.getProperties().putAll(SystemPropertiesHandler.getSystemProperties(new File(rootDir, MAVEN_PROPERTIES_FILENAME))); 83 | } 84 | 85 | private static File rootDir(File wrapperJar) { 86 | return wrapperJar.getParentFile().getParentFile(); 87 | } 88 | 89 | private static File wrapperProperties(File wrapperJar) { 90 | return new File(wrapperJar.getParent(), wrapperJar.getName().replaceFirst("\\.jar$", ".properties")); 91 | } 92 | 93 | private static File wrapperJar() { 94 | URI location; 95 | 96 | try { 97 | location = MavenWrapperMain.class.getProtectionDomain().getCodeSource().getLocation().toURI(); 98 | } catch (URISyntaxException e) { 99 | throw new RuntimeException(e); 100 | } 101 | 102 | if (!location.getScheme().equals("file")) { 103 | throw new RuntimeException(String.format("Cannot determine classpath for wrapper Jar from codebase '%s'.", location)); 104 | } 105 | 106 | return new File(location.getPath()); 107 | } 108 | 109 | static String wrapperVersion() { 110 | try { 111 | InputStream resourceAsStream = MavenWrapperMain.class 112 | .getResourceAsStream("/META-INF/maven/com.rimerosolutions.maven.plugins/wrapper-maven-plugin/pom.properties"); 113 | if (resourceAsStream == null) { 114 | throw new RuntimeException("No maven properties found."); 115 | } 116 | 117 | Properties mavenProperties = new Properties(); 118 | 119 | try { 120 | mavenProperties.load(resourceAsStream); 121 | String version = mavenProperties.getProperty("version"); 122 | 123 | if (version == null) { 124 | throw new RuntimeException("No version number specified in build receipt resource."); 125 | } 126 | 127 | return version; 128 | } finally { 129 | resourceAsStream.close(); 130 | } 131 | } catch (Exception e) { 132 | throw new RuntimeException("Could not determine wrapper version.", e); 133 | } 134 | } 135 | 136 | private static File mavenUserHome() { 137 | String mavenUserHome = System.getProperty(MAVEN_USER_HOME_PROPERTY_KEY); 138 | if (mavenUserHome != null) { 139 | return new File(mavenUserHome); 140 | } else if ((mavenUserHome = System.getenv(MAVEN_USER_HOME_ENV_KEY)) != null) { 141 | return new File(mavenUserHome); 142 | } else { 143 | return new File(DEFAULT_MAVEN_USER_HOME); 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/MavenWrapperMojo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013. Rimero Solutions 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import java.io.ByteArrayInputStream; 19 | import java.io.File; 20 | import java.io.FileInputStream; 21 | import java.io.FileOutputStream; 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.nio.ByteBuffer; 25 | import java.nio.channels.Channels; 26 | import java.nio.channels.FileChannel; 27 | import java.nio.channels.ReadableByteChannel; 28 | import java.util.ArrayDeque; 29 | import java.util.Collections; 30 | import java.util.Deque; 31 | import java.util.Iterator; 32 | import java.util.List; 33 | import java.util.Properties; 34 | 35 | import org.apache.maven.artifact.Artifact; 36 | import org.apache.maven.plugin.AbstractMojo; 37 | import org.apache.maven.plugin.MojoExecutionException; 38 | import org.apache.maven.plugin.descriptor.PluginDescriptor; 39 | import org.apache.maven.plugins.annotations.Component; 40 | import org.apache.maven.plugins.annotations.Mojo; 41 | import org.apache.maven.plugins.annotations.Parameter; 42 | import org.apache.maven.project.MavenProject; 43 | import org.apache.maven.rtinfo.RuntimeInformation; 44 | import org.codehaus.plexus.PlexusConstants; 45 | import org.codehaus.plexus.PlexusContainer; 46 | import org.codehaus.plexus.component.repository.exception.ComponentLookupException; 47 | import org.codehaus.plexus.context.Context; 48 | import org.codehaus.plexus.context.ContextException; 49 | import org.codehaus.plexus.util.IOUtil; 50 | import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; 51 | 52 | @Mojo(name = "wrapper", requiresProject = true) 53 | /** 54 | * Generates a Maven Command Line Wrapper for the current project. 55 | * 56 | * @author Yves Zoundi 57 | */ 58 | public class MavenWrapperMojo extends AbstractMojo implements Contextualizable { 59 | 60 | public static final String DIST_FILENAME_PATH_TEMPLATE = "%s/apache-maven-%s-bin.zip"; 61 | public static final String CHECKSUM_FILENAME_PATH_TEMPLATE = "%s/apache-maven-%s-bin.zip.%s"; 62 | public static final String WRAPPER_PROPERTIES_FILE_NAME = "maven-wrapper.properties"; 63 | public static final String WRAPPER_JAR_FILE_NAME = "maven-wrapper.jar"; 64 | public static final String DISTRIBUTION_URL_PROPERTY = "distributionUrl"; 65 | public static final String VERIFY_DOWNLOAD_PROPERTY = "verifyDownload"; 66 | public static final String CHECKSUM_ALGORITHM_PROPERTY = "checksumAlgorithm"; 67 | public static final String SCRIPT_FILENAME_WINDOWS = "mvnw.bat"; 68 | public static final String SCRIPT_FILENAME_UNIX = "mvnw"; 69 | 70 | private static final String DEFAULT_BASE_DISTRIBUTION_URL = "https://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven"; 71 | private static final String WRAPPER_TEMPLATES_LOCATION = "com/rimerosolutions/maven/plugins/wrapper/"; 72 | private static final String WRAPPER_PROPERTIES_COMMENTS = "Maven download properties"; 73 | private static final String ENCODING_UTF8 = "UTF-8"; 74 | 75 | static final String[] LAUNCHER_FILE_SEPARATORS = { "\\", "/" }; 76 | static final String[] LAUNCHER_FILE_BASE_NAMES = { SCRIPT_FILENAME_WINDOWS, SCRIPT_FILENAME_UNIX }; 77 | static final String[] LAUNCHERS_PARTS_WINDOWS = { "mvnw_header.bat", "", "mvnw_footer.bat" }; 78 | static final String[] LAUNCHERS_PARTS_UNIX = { "mvnw_header", "", "mvnw_footer" }; 79 | static final String[][] LAUNCHERS_PARTS = { LAUNCHERS_PARTS_WINDOWS, LAUNCHERS_PARTS_UNIX }; 80 | static final String[] LAUNCHERS_JAR_PREFIXES = { "set WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\", "\"$MAVEN_PROJECTBASEDIR/" }; 81 | private PlexusContainer container; 82 | 83 | @Component 84 | private MavenProject project; 85 | 86 | @Component 87 | private PluginDescriptor plugin; 88 | 89 | @Parameter(property = "baseDistributionUrl", defaultValue = DEFAULT_BASE_DISTRIBUTION_URL) 90 | /** 91 | * DEPRECATED: Base distribution URL for the Maven binaries download. Use 92 | * baseDistributionUrlList instead. 93 | */ 94 | private String baseDistributionUrl; 95 | 96 | @Parameter(property = "baseDistributionUrlList", required = false) 97 | /** 98 | * List of base distribution URLs for the Maven binaries download. Default 99 | * is: 100 | * https://repository.apache.org/content/repositories/releases/org/apache/ 101 | * maven/apache-maven 102 | */ 103 | private List baseDistributionUrlList; 104 | 105 | @Parameter(property = "wrapperScriptDirectory", defaultValue = "${basedir}") 106 | /** The wrapper scripts folder for Windows/Unix */ 107 | private String wrapperScriptDirectory; 108 | 109 | @Parameter(property = "wrapperDirectory", defaultValue = "${basedir}/maven") 110 | /** 111 | * The wrapper jar output folder. The location should be a sub-folder of the 112 | * wrapper scripts directory 113 | */ 114 | private String wrapperDirectory; 115 | 116 | @Parameter(property = "mavenVersion", required = false) 117 | /** The Maven version to use for the generate wrapper */ 118 | private String mavenVersion; 119 | 120 | @Parameter(property = "verifyDownload", defaultValue = "false") 121 | /** Whether to verify the download using a checksum. */ 122 | private Boolean verifyDownload; 123 | 124 | @Parameter(property = "checksumExtension", required = false) 125 | /** The checksum file extension. */ 126 | private String checksumExtension; 127 | 128 | @Parameter(property = "checksumAlgorithm", defaultValue = "SHA-1") 129 | /** The checksum algorithm. */ 130 | private String checksumAlgorithm; 131 | 132 | /** 133 | * Sets the plugin descriptor (Exposed for unit tests) 134 | * 135 | * @param plugin 136 | * The plugin descriptor 137 | */ 138 | protected void setPlugin(PluginDescriptor plugin) { 139 | this.plugin = plugin; 140 | } 141 | 142 | /** 143 | * Sets the Maven version (Exposed for unit tests only) 144 | * 145 | * @param mavenVersion 146 | * The Maven version to use for the wrapper 147 | */ 148 | protected void setMavenVersion(String mavenVersion) { 149 | this.mavenVersion = mavenVersion; 150 | } 151 | 152 | /** 153 | * Returns the Maven version if set (Exposed for unit tests only) 154 | * 155 | * @return The Maven version to use for the wrapper 156 | */ 157 | protected String getMavenVersion() { 158 | return mavenVersion; 159 | } 160 | 161 | /** 162 | * Returns the wrapper folder (Exposed for unit tests only) 163 | * 164 | * @return the wrapper output folder 165 | */ 166 | protected String getWrapperDirectory() { 167 | return this.wrapperDirectory; 168 | } 169 | 170 | /** 171 | * Returns the wrapper folder (Exposed for unit tests only) 172 | * 173 | * @return the wrapper output folder 174 | */ 175 | protected String getWrapperScriptDirectory() { 176 | return this.wrapperScriptDirectory; 177 | } 178 | 179 | /** 180 | * Returns the wrapper base distribution URL (Exposed for unit tests only) 181 | * 182 | * @return the wrapper base distribution URL 183 | */ 184 | protected String getBaseDistributionUrl() { 185 | return this.baseDistributionUrl; 186 | } 187 | 188 | /** 189 | * Returns the wrapper base distribution URL list (Exposed for unit tests 190 | * only) 191 | * 192 | * @return the wrapper base distribution URL list 193 | */ 194 | protected List getBaseDistributionUrlList() { 195 | return this.baseDistributionUrlList; 196 | } 197 | 198 | /** 199 | * Returns the checksum extension (Exposed for unit tests only) 200 | * 201 | * @return the checksum extension 202 | */ 203 | protected String getChecksumExtension() { 204 | return this.checksumExtension; 205 | } 206 | 207 | /** 208 | * Returns the checksum algorithm (Exposed for unit tests only) 209 | * 210 | * @return the checksum algorithm 211 | */ 212 | protected String getChecksumAlgorithm() { 213 | return this.checksumAlgorithm; 214 | } 215 | 216 | /** 217 | * Returns whether to verify the download (Exposed for unit tests only) 218 | * 219 | * @return true if and only if the download should be verified 220 | */ 221 | protected Boolean getVerifyDownload() { 222 | return this.verifyDownload; 223 | } 224 | 225 | public void contextualize(Context context) throws ContextException { 226 | container = (PlexusContainer) context.get(PlexusConstants.PLEXUS_KEY); 227 | } 228 | 229 | private String composePath(String fileSeparator, Deque folderDeque, String filename) { 230 | StringBuilder sb = new StringBuilder(); 231 | String folderPath = pathFromDequeWithFileSeparator(folderDeque, fileSeparator); 232 | 233 | return sb.append(folderPath).append(filename).toString(); 234 | } 235 | 236 | private String pathFromDequeWithFileSeparator(Deque pathDeque, String separator) { 237 | Iterator it = pathDeque.iterator(); 238 | StringBuilder sb = new StringBuilder(); 239 | 240 | while (it.hasNext()) { 241 | String pathName = it.next(); 242 | sb.append(pathName); 243 | sb.append(separator); 244 | } 245 | 246 | return sb.toString(); 247 | } 248 | 249 | private Deque buildPathDeque(File wrapperDestFolder, File baseDir) { 250 | File tmp = wrapperDestFolder; 251 | Deque pathNameDeque = new ArrayDeque(); 252 | 253 | while (!tmp.equals(baseDir)) { 254 | pathNameDeque.push(tmp.getName()); 255 | tmp = tmp.getParentFile(); 256 | } 257 | 258 | return pathNameDeque; 259 | } 260 | 261 | public void execute() throws MojoExecutionException { 262 | try { 263 | File wrapperFolder = new File(wrapperScriptDirectory); 264 | if (!wrapperFolder.exists()) { 265 | wrapperFolder.mkdirs(); 266 | } 267 | 268 | Artifact mainArtifact = (Artifact) plugin.getPluginArtifact(); 269 | 270 | if (mavenVersion == null) { 271 | RuntimeInformation runtimeInformation = container.lookup(RuntimeInformation.class); 272 | mavenVersion = runtimeInformation.getMavenVersion(); 273 | } 274 | 275 | File wrapperSupportFolder = new File(wrapperDirectory); 276 | if (!wrapperSupportFolder.exists()) { 277 | wrapperSupportFolder.mkdirs(); 278 | } 279 | 280 | String baseDirPath = wrapperFolder.getAbsolutePath(); 281 | String wrapperFolderPath = wrapperSupportFolder.getAbsolutePath(); 282 | 283 | if (!wrapperFolderPath.startsWith(baseDirPath)) { 284 | throw new MojoExecutionException("wrapperDirectory folder must be a sub-folder of wrapperScriptDirectory."); 285 | } 286 | 287 | generateWrapperScripts(wrapperFolder, wrapperSupportFolder); 288 | generateWrapperProperties(wrapperSupportFolder, mainArtifact); 289 | } catch (ComponentLookupException cle) { 290 | throw new MojoExecutionException("Could not lookup Maven runtime information", cle); 291 | } catch (IOException ioe) { 292 | throw new MojoExecutionException("Unexpected IO Error", ioe); 293 | } 294 | } 295 | 296 | private void generateWrapperScripts(File baseDir, File wrapperDestFolder) throws IOException { 297 | final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 298 | final Deque pathNameDeque = buildPathDeque(wrapperDestFolder, baseDir); 299 | 300 | for (int i = 0; i < LAUNCHERS_PARTS.length; i++) { 301 | String[] launcherOsParts = LAUNCHERS_PARTS[i]; 302 | InputStream[] streams = new InputStream[launcherOsParts.length]; 303 | 304 | for (int j = 0; j < launcherOsParts.length; j++) { 305 | String launcherFilePartName = launcherOsParts[j]; 306 | 307 | if (launcherFilePartName.equals("")) { 308 | String fileSeparator = LAUNCHER_FILE_SEPARATORS[i]; 309 | String jarPathLocation = composePath(fileSeparator, pathNameDeque, WRAPPER_JAR_FILE_NAME); 310 | String jarPathPrefix = LAUNCHERS_JAR_PREFIXES[i]; 311 | String jarPath = jarPathPrefix + jarPathLocation; 312 | streams[j] = new ByteArrayInputStream(jarPath.getBytes(ENCODING_UTF8)); 313 | } else { 314 | String launcherLocation = WRAPPER_TEMPLATES_LOCATION + launcherFilePartName; 315 | InputStream mvnLauncherStream = classLoader.getResourceAsStream(launcherLocation); 316 | streams[j] = mvnLauncherStream; 317 | } 318 | } 319 | 320 | File launcherFile = new File(baseDir, LAUNCHER_FILE_BASE_NAMES[i]); 321 | streamsToFile(streams, launcherFile); 322 | 323 | if (!launcherFile.setExecutable(true)) { 324 | getLog().warn("Could not set executable flag on file: " + launcherFile.getAbsolutePath()); 325 | } 326 | } 327 | } 328 | 329 | private void generateWrapperProperties(File wrapperSupportFolder, Artifact pluginArtifact) throws MojoExecutionException, IOException { 330 | List effectiveBaseDistributionUrls; 331 | if (baseDistributionUrlList == null) { 332 | effectiveBaseDistributionUrls = Collections.singletonList(baseDistributionUrl); 333 | } else if (baseDistributionUrlList.isEmpty()) { 334 | effectiveBaseDistributionUrls = Collections.singletonList(DEFAULT_BASE_DISTRIBUTION_URL); 335 | } else { 336 | effectiveBaseDistributionUrls = baseDistributionUrlList; 337 | } 338 | 339 | Properties props = new Properties(); 340 | 341 | props.put(VERIFY_DOWNLOAD_PROPERTY, verifyDownload.toString()); 342 | if (verifyDownload) { 343 | Checksum checksum = Checksum.fromAlias(checksumAlgorithm); 344 | if (checksum == null) { 345 | throw new MojoExecutionException(String.format("Unsupported checksum algorithm: %s", checksumAlgorithm)); 346 | } 347 | props.put(CHECKSUM_ALGORITHM_PROPERTY, checksum.toString()); 348 | } 349 | 350 | StringBuilder distlistsb = new StringBuilder(); 351 | 352 | for (final String effectiveBaseDistributionUrl : effectiveBaseDistributionUrls) { 353 | distlistsb.append(effectiveBaseDistributionUrl); 354 | 355 | if (!effectiveBaseDistributionUrl.endsWith("/")) { 356 | distlistsb.append('/'); 357 | } 358 | 359 | distlistsb.append(String.format(DIST_FILENAME_PATH_TEMPLATE, mavenVersion, mavenVersion)); 360 | 361 | distlistsb.append(","); 362 | } 363 | 364 | distlistsb.setLength(distlistsb.length() - 1); 365 | 366 | props.put(DISTRIBUTION_URL_PROPERTY, distlistsb.toString()); 367 | 368 | File file = new File(wrapperSupportFolder, WRAPPER_PROPERTIES_FILE_NAME); 369 | 370 | FileOutputStream fileOut = null; 371 | InputStream is = null; 372 | 373 | try { 374 | is = new FileInputStream(pluginArtifact.getFile()); 375 | streamsToFile(new InputStream[] { is }, new File(wrapperSupportFolder, WRAPPER_JAR_FILE_NAME)); 376 | fileOut = new FileOutputStream(file); 377 | props.store(fileOut, WRAPPER_PROPERTIES_COMMENTS); 378 | 379 | } finally { 380 | if (fileOut != null) { 381 | IOUtil.close(fileOut); 382 | } 383 | 384 | if (is != null) { 385 | IOUtil.close(is); 386 | } 387 | } 388 | } 389 | 390 | private static void streamsToFile(InputStream[] streams, File filePath) throws IOException { 391 | FileChannel outChannel = null; 392 | ReadableByteChannel inChannel = null; 393 | FileOutputStream fos = null; 394 | 395 | try { 396 | fos = new FileOutputStream(filePath); 397 | outChannel = fos.getChannel(); 398 | 399 | for (InputStream stream : streams) { 400 | try { 401 | inChannel = Channels.newChannel(stream); 402 | ByteBuffer buffer = ByteBuffer.allocate(1024); 403 | 404 | while (inChannel.read(buffer) >= 0 || buffer.position() > 0) { 405 | buffer.flip(); 406 | outChannel.write(buffer); 407 | buffer.clear(); 408 | } 409 | } finally { 410 | if (stream != null) { 411 | IOUtil.close(stream); 412 | } 413 | 414 | if (inChannel != null) { 415 | inChannel.close(); 416 | } 417 | } 418 | } 419 | } finally { 420 | if (fos != null) { 421 | IOUtil.close(fos); 422 | } 423 | 424 | if (outChannel != null) { 425 | outChannel.close(); 426 | } 427 | } 428 | } 429 | } 430 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/PathAssembler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2008 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import java.io.File; 19 | import java.math.BigInteger; 20 | import java.net.URI; 21 | import java.security.MessageDigest; 22 | 23 | /** 24 | * @author Hans Dockter 25 | */ 26 | public class PathAssembler { 27 | public static final String MAVEN_USER_HOME_STRING = "MAVEN_USER_HOME"; 28 | 29 | public static final String PROJECT_STRING = "PROJECT"; 30 | 31 | private File mavenUserHome; 32 | 33 | public PathAssembler() { 34 | } 35 | 36 | public PathAssembler(File mavenUserHome) { 37 | this.mavenUserHome = mavenUserHome; 38 | } 39 | 40 | /** 41 | * Determines the local locations for the distribution to use given the 42 | * supplied configuration. 43 | */ 44 | public LocalDistribution getDistribution(WrapperConfiguration configuration, URI distributionUrl) { 45 | String baseName = getDistName(distributionUrl); 46 | String distName = removeExtension(baseName); 47 | String rootDirName = rootDirName(distName, distributionUrl); 48 | File distDir = new File(getBaseDir(configuration.getDistributionBase()), configuration.getDistributionPath() + "/" + rootDirName); 49 | File distZip = new File(getBaseDir(configuration.getZipBase()), configuration.getZipPath() + "/" + rootDirName + "/" + baseName); 50 | return new LocalDistribution(distDir, distZip); 51 | } 52 | 53 | private String rootDirName(String distName, URI distributionUrl) { 54 | String urlHash = getMd5Hash(distributionUrl.toString()); 55 | return String.format("%s/%s", distName, urlHash); 56 | } 57 | 58 | private String getMd5Hash(String string) { 59 | try { 60 | MessageDigest messageDigest = MessageDigest.getInstance("MD5"); 61 | byte[] bytes = string.getBytes(); 62 | messageDigest.update(bytes); 63 | return new BigInteger(1, messageDigest.digest()).toString(32); 64 | } catch (Exception e) { 65 | throw new RuntimeException("Could not hash input string.", e); 66 | } 67 | } 68 | 69 | private String removeExtension(String name) { 70 | int p = name.lastIndexOf("."); 71 | if (p < 0) { 72 | return name; 73 | } 74 | return name.substring(0, p); 75 | } 76 | 77 | private String getDistName(URI distUrl) { 78 | String path = distUrl.getPath(); 79 | int p = path.lastIndexOf("/"); 80 | if (p < 0) { 81 | return path; 82 | } 83 | return path.substring(p + 1); 84 | } 85 | 86 | private File getBaseDir(String base) { 87 | if (base.equals(MAVEN_USER_HOME_STRING)) { 88 | return mavenUserHome; 89 | } else if (base.equals(PROJECT_STRING)) { 90 | return new File(System.getProperty("user.dir")); 91 | } else { 92 | throw new RuntimeException("Base: " + base + " is unknown"); 93 | } 94 | } 95 | 96 | public static class LocalDistribution { 97 | private final File distZip; 98 | 99 | private final File distDir; 100 | 101 | public LocalDistribution(File distDir, File distZip) { 102 | this.distDir = distDir; 103 | this.distZip = distZip; 104 | } 105 | 106 | /** 107 | * Returns the location to install the distribution into. 108 | */ 109 | public File getDistributionDir() { 110 | return distDir; 111 | } 112 | 113 | /** 114 | * Returns the location to install the distribution ZIP file to. 115 | */ 116 | public File getZipFile() { 117 | return distZip; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/SystemPropertiesHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import java.io.File; 19 | import java.io.FileInputStream; 20 | import java.io.IOException; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | import java.util.Properties; 24 | 25 | /** 26 | * @author Hans Dockter 27 | */ 28 | public class SystemPropertiesHandler { 29 | 30 | public static Map getSystemProperties(File propertiesFile) { 31 | Map propertyMap = new HashMap(); 32 | 33 | if (!propertiesFile.isFile() || !propertiesFile.canRead()) { 34 | return propertyMap; 35 | } 36 | 37 | Properties properties = new Properties(); 38 | FileInputStream inStream = null; 39 | 40 | try { 41 | inStream = new FileInputStream(propertiesFile); 42 | 43 | try { 44 | properties.load(inStream); 45 | } finally { 46 | if (inStream != null) { 47 | inStream.close(); 48 | } 49 | } 50 | } catch (IOException e) { 51 | throw new RuntimeException("Error when loading properties file=" + propertiesFile, e); 52 | } 53 | 54 | for (Map.Entry e : properties.entrySet()) { 55 | propertyMap.put(e.getKey().toString(), e.getValue().toString()); 56 | } 57 | 58 | return propertyMap; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/WrapperConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import java.net.URI; 19 | import java.util.List; 20 | 21 | public class WrapperConfiguration { 22 | public static final String ALWAYS_UNPACK_ENV = "MAVEN_WRAPPER_ALWAYS_UNPACK"; 23 | 24 | public static final String ALWAYS_DOWNLOAD_ENV = "MAVEN_WRAPPER_ALWAYS_DOWNLOAD"; 25 | 26 | private boolean alwaysUnpack = Boolean.parseBoolean(System.getenv(ALWAYS_UNPACK_ENV)); 27 | 28 | private boolean alwaysDownload = Boolean.parseBoolean(System.getenv(ALWAYS_DOWNLOAD_ENV)); 29 | 30 | private List distributionUris; 31 | 32 | private String distributionBase = PathAssembler.MAVEN_USER_HOME_STRING; 33 | 34 | private String distributionPath = Installer.DEFAULT_DISTRIBUTION_PATH; 35 | 36 | private String zipBase = PathAssembler.MAVEN_USER_HOME_STRING; 37 | 38 | private String zipPath = Installer.DEFAULT_DISTRIBUTION_PATH; 39 | 40 | private boolean verifyDownload = false; 41 | 42 | private Checksum checksumAlgorithm = null; 43 | 44 | public boolean isAlwaysDownload() { 45 | return alwaysDownload; 46 | } 47 | 48 | public void setAlwaysDownload(boolean alwaysDownload) { 49 | this.alwaysDownload = alwaysDownload; 50 | } 51 | 52 | public boolean isAlwaysUnpack() { 53 | return alwaysUnpack; 54 | } 55 | 56 | public void setAlwaysUnpack(boolean alwaysUnpack) { 57 | this.alwaysUnpack = alwaysUnpack; 58 | } 59 | 60 | public List getDistributionUris() { 61 | return distributionUris; 62 | } 63 | 64 | public void setDistributionUris(List distribution) { 65 | this.distributionUris = distribution; 66 | } 67 | 68 | public String getDistributionBase() { 69 | return distributionBase; 70 | } 71 | 72 | public void setDistributionBase(String distributionBase) { 73 | this.distributionBase = distributionBase; 74 | } 75 | 76 | public String getDistributionPath() { 77 | return distributionPath; 78 | } 79 | 80 | public void setDistributionPath(String distributionPath) { 81 | this.distributionPath = distributionPath; 82 | } 83 | 84 | public String getZipBase() { 85 | return zipBase; 86 | } 87 | 88 | public void setZipBase(String zipBase) { 89 | this.zipBase = zipBase; 90 | } 91 | 92 | public String getZipPath() { 93 | return zipPath; 94 | } 95 | 96 | public void setZipPath(String zipPath) { 97 | this.zipPath = zipPath; 98 | } 99 | 100 | public boolean isVerifyDownload() { 101 | return verifyDownload; 102 | } 103 | 104 | public void setVerifyDownload(boolean verifyDownload) { 105 | this.verifyDownload = verifyDownload; 106 | } 107 | 108 | public Checksum getChecksumAlgorithm() { 109 | return checksumAlgorithm; 110 | } 111 | 112 | public void setChecksumAlgorithm(Checksum checksumAlgorithm) { 113 | this.checksumAlgorithm = checksumAlgorithm; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/WrapperExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2008 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import java.io.File; 19 | import java.io.FileInputStream; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.net.URI; 23 | import java.net.URISyntaxException; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import java.util.Properties; 27 | 28 | /** 29 | * @author Hans Dockter 30 | */ 31 | public class WrapperExecutor { 32 | public static final String DISTRIBUTION_URL_PROPERTY = "distributionUrl"; 33 | public static final String DISTRIBUTION_BASE_PROPERTY = "distributionBase"; 34 | public static final String ZIP_STORE_BASE_PROPERTY = "zipStoreBase"; 35 | public static final String DISTRIBUTION_PATH_PROPERTY = "distributionPath"; 36 | public static final String ZIP_STORE_PATH_PROPERTY = "zipStorePath"; 37 | public static final String VERIFY_DOWNLOAD_PROPERTY = "verifyDownload"; 38 | public static final String CHECKSUM_ALGORITHM_PROPERTY = "checksumAlgorithm"; 39 | public static final String CHECKSUM_URL_PROPERTY = "checksumUrl"; 40 | private final Properties properties; 41 | 42 | private final File propertiesFile; 43 | private final WrapperConfiguration config = new WrapperConfiguration(); 44 | 45 | public static WrapperExecutor forProjectDirectory(File projectDir) { 46 | return new WrapperExecutor(new File(projectDir, "maven/wrapper/maven-wrapper.properties"), new Properties()); 47 | } 48 | 49 | public static WrapperExecutor forWrapperPropertiesFile(File propertiesFile) { 50 | if (!propertiesFile.exists()) { 51 | throw new RuntimeException(String.format("Wrapper properties file '%s' does not exist.", propertiesFile)); 52 | } 53 | 54 | return new WrapperExecutor(propertiesFile, new Properties()); 55 | } 56 | 57 | WrapperExecutor(File propertiesFile, Properties properties) { 58 | this.properties = properties; 59 | this.propertiesFile = propertiesFile; 60 | 61 | if (propertiesFile.exists()) { 62 | try { 63 | loadProperties(propertiesFile, properties); 64 | 65 | config.setDistributionBase(getProperty(DISTRIBUTION_BASE_PROPERTY, config.getDistributionBase())); 66 | config.setDistributionPath(getProperty(DISTRIBUTION_PATH_PROPERTY, config.getDistributionPath())); 67 | config.setZipBase(getProperty(ZIP_STORE_BASE_PROPERTY, config.getZipBase())); 68 | config.setZipPath(getProperty(ZIP_STORE_PATH_PROPERTY, config.getZipPath())); 69 | config.setDistributionUris(prepareDistributionUris()); 70 | config.setVerifyDownload(Boolean.valueOf(getProperty(VERIFY_DOWNLOAD_PROPERTY, "false"))); 71 | 72 | if (config.isVerifyDownload()) { 73 | config.setChecksumAlgorithm(Checksum.valueOf(getProperty(CHECKSUM_ALGORITHM_PROPERTY))); 74 | } 75 | } catch (Exception e) { 76 | throw new RuntimeException(String.format("Could not load wrapper properties from '%s'.", propertiesFile), e); 77 | } 78 | } 79 | } 80 | 81 | private List prepareDistributionUris() throws URISyntaxException { 82 | return readRequiredUriList(DISTRIBUTION_URL_PROPERTY); 83 | } 84 | 85 | private List readRequiredUriList(String key) throws URISyntaxException { 86 | List uriList = new ArrayList(); 87 | 88 | if (properties.getProperty(key) != null) { 89 | for (String value : getProperty(key).split(",")) { 90 | if (value.trim().length() == 0) { 91 | continue; 92 | } 93 | 94 | URI uri = URI.create(value); 95 | 96 | if (uri.getScheme() == null) { 97 | uri = new File(propertiesFile.getParentFile(), uri.getSchemeSpecificPart()).toURI(); 98 | } 99 | 100 | uriList.add(uri); 101 | } 102 | 103 | return uriList; 104 | } 105 | 106 | reportMissingProperty(key); 107 | return null; // previous line will fail 108 | } 109 | 110 | private static void loadProperties(File propertiesFile, Properties properties) throws IOException { 111 | InputStream inStream = new FileInputStream(propertiesFile); 112 | 113 | try { 114 | properties.load(inStream); 115 | } finally { 116 | inStream.close(); 117 | } 118 | } 119 | 120 | /** 121 | * Returns the distribution which this wrapper will use. Returns null if no 122 | * wrapper meta-data was found in the specified project directory. 123 | */ 124 | public List getDistributionUris() { 125 | return config.getDistributionUris(); 126 | } 127 | 128 | /** 129 | * Returns the configuration for this wrapper. 130 | */ 131 | public WrapperConfiguration getConfiguration() { 132 | return config; 133 | } 134 | 135 | public void execute(String[] args, Installer install, BootstrapMainStarter bootstrapMainStarter) throws Exception { 136 | File mavenHome = install.createDist(config); 137 | bootstrapMainStarter.start(args, mavenHome); 138 | } 139 | 140 | private String getProperty(String propertyName) { 141 | return getProperty(propertyName, null); 142 | } 143 | 144 | private String getProperty(String propertyName, String defaultValue) { 145 | String value = properties.getProperty(propertyName); 146 | 147 | if (value != null) { 148 | return value; 149 | } 150 | 151 | if (defaultValue != null) { 152 | return defaultValue; 153 | } 154 | 155 | return reportMissingProperty(propertyName); 156 | } 157 | 158 | private String reportMissingProperty(String propertyName) { 159 | throw new RuntimeException( 160 | String.format("No value with key '%s' specified in wrapper properties file '%s'.", propertyName, propertiesFile)); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/AbstractCommandLineConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper.cli; 17 | 18 | public abstract class AbstractCommandLineConverter implements CommandLineConverter { 19 | public T convert(Iterable args) throws CommandLineArgumentException { 20 | CommandLineParser parser = new CommandLineParser(); 21 | configure(parser); 22 | 23 | return convert(parser.parse(args)); 24 | } 25 | 26 | public T convert(ParsedCommandLine args) throws CommandLineArgumentException { 27 | return convert(args, newInstance()); 28 | } 29 | 30 | public T convert(Iterable args, T target) throws CommandLineArgumentException { 31 | CommandLineParser parser = new CommandLineParser(); 32 | configure(parser); 33 | 34 | return convert(parser.parse(args), target); 35 | } 36 | 37 | protected abstract T newInstance(); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/AbstractPropertiesCommandLineConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.apache.maven.wrapper.cli; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | public abstract class AbstractPropertiesCommandLineConverter extends AbstractCommandLineConverter> { 23 | protected abstract String getPropertyOption(); 24 | 25 | protected abstract String getPropertyOptionDetailed(); 26 | 27 | protected abstract String getPropertyOptionDescription(); 28 | 29 | public void configure(CommandLineParser parser) { 30 | CommandLineOption option = parser.option(getPropertyOption(), getPropertyOptionDetailed()); 31 | option = option.hasArguments(); 32 | option.hasDescription(getPropertyOptionDescription()); 33 | } 34 | 35 | protected Map newInstance() { 36 | return new HashMap(); 37 | } 38 | 39 | public Map convert(ParsedCommandLine options, Map properties) throws CommandLineArgumentException { 40 | for (String keyValueExpression : options.option(getPropertyOption()).getValues()) { 41 | int pos = keyValueExpression.indexOf("="); 42 | 43 | if (pos < 0) { 44 | properties.put(keyValueExpression, ""); 45 | } else { 46 | properties.put(keyValueExpression.substring(0, pos), keyValueExpression.substring(pos + 1)); 47 | } 48 | } 49 | return properties; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/CommandLineArgumentException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper.cli; 17 | 18 | /** 19 | * A {@code CommandLineArgumentException} is thrown when command-line arguments 20 | * cannot be parsed. 21 | * 22 | * @author Hans Dockter 23 | */ 24 | public class CommandLineArgumentException extends RuntimeException { 25 | private static final long serialVersionUID = 7539123031140668557L; 26 | 27 | public CommandLineArgumentException(String message) { 28 | super(message); 29 | } 30 | 31 | public CommandLineArgumentException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/CommandLineConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper.cli; 17 | 18 | /** 19 | * @author Hans Dockter 20 | */ 21 | public interface CommandLineConverter { 22 | T convert(Iterable args) throws CommandLineArgumentException; 23 | 24 | T convert(Iterable args, T target) throws CommandLineArgumentException; 25 | 26 | T convert(ParsedCommandLine args) throws CommandLineArgumentException; 27 | 28 | T convert(ParsedCommandLine args, T target) throws CommandLineArgumentException; 29 | 30 | void configure(CommandLineParser parser); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/CommandLineOption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper.cli; 17 | 18 | import java.util.HashSet; 19 | import java.util.List; 20 | import java.util.Set; 21 | 22 | public class CommandLineOption { 23 | private final Set options = new HashSet(); 24 | 25 | private Class argumentType = Void.TYPE; 26 | 27 | private String description; 28 | 29 | private String subcommand; 30 | 31 | private String deprecationWarning; 32 | 33 | private boolean incubating; 34 | 35 | public CommandLineOption(Iterable options) { 36 | for (String option : options) { 37 | this.options.add(option); 38 | } 39 | } 40 | 41 | public Set getOptions() { 42 | return options; 43 | } 44 | 45 | public CommandLineOption hasArgument() { 46 | argumentType = String.class; 47 | 48 | return this; 49 | } 50 | 51 | public CommandLineOption hasArguments() { 52 | argumentType = List.class; 53 | 54 | return this; 55 | } 56 | 57 | public String getSubcommand() { 58 | return subcommand; 59 | } 60 | 61 | public CommandLineOption mapsToSubcommand(String command) { 62 | this.subcommand = command; 63 | 64 | return this; 65 | } 66 | 67 | public String getDescription() { 68 | StringBuilder result = new StringBuilder(); 69 | 70 | if (description != null) { 71 | result.append(description); 72 | } 73 | 74 | if (deprecationWarning != null) { 75 | if (result.length() > 0) { 76 | result.append(' '); 77 | } 78 | 79 | result.append("[deprecated - "); 80 | result.append(deprecationWarning); 81 | result.append("]"); 82 | } 83 | 84 | if (incubating) { 85 | if (result.length() > 0) { 86 | result.append(' '); 87 | } 88 | 89 | result.append("[incubating]"); 90 | } 91 | 92 | return result.toString(); 93 | } 94 | 95 | public CommandLineOption hasDescription(String description) { 96 | this.description = description; 97 | 98 | return this; 99 | } 100 | 101 | public boolean getAllowsArguments() { 102 | return argumentType != Void.TYPE; 103 | } 104 | 105 | public boolean getAllowsMultipleArguments() { 106 | return argumentType == List.class; 107 | } 108 | 109 | public CommandLineOption deprecated(String deprecationWarning) { 110 | this.deprecationWarning = deprecationWarning; 111 | 112 | return this; 113 | } 114 | 115 | public CommandLineOption incubating() { 116 | incubating = true; 117 | 118 | return this; 119 | } 120 | 121 | public String getDeprecationWarning() { 122 | return deprecationWarning; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/CommandLineParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper.cli; 17 | 18 | import java.io.OutputStreamWriter; 19 | import java.io.PrintWriter; 20 | import java.io.Writer; 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.Collection; 24 | import java.util.Collections; 25 | import java.util.Comparator; 26 | import java.util.Formatter; 27 | import java.util.HashMap; 28 | import java.util.HashSet; 29 | import java.util.LinkedHashMap; 30 | import java.util.List; 31 | import java.util.Map; 32 | import java.util.Set; 33 | import java.util.TreeSet; 34 | 35 | /** 36 | *

37 | * A command-line parser which supports a command/sub-command style command-line 38 | * interface. Supports the following syntax: 39 | *

40 | * 41 | *
 42 |  * <option>* (<sub-command> <sub-command-option>*)*
 43 |  * 
44 | *
    45 | *
  • Short options are a '-' followed by a single character. For example: 46 | * {@code -a}.
  • 47 | *
  • Long options are '--' followed by multiple characters. For example: 48 | * {@code --long-option}.
  • 49 | *
  • Options can take arguments. The argument follows the option. For example: 50 | * {@code -a arg} or {@code --long arg}.
  • 51 | *
  • Arguments can be attached to the option using '='. For example: 52 | * {@code -a=arg} or {@code --long=arg}.
  • 53 | *
  • Arguments can be attached to short options. For example: {@code -aarg}. 54 | *
  • 55 | *
  • Short options can be combined. For example {@code -ab} is equivalent to 56 | * {@code -a -b}.
  • 57 | *
  • Anything else is treated as an extra argument. This includes a single 58 | * {@code -} character.
  • 59 | *
  • '--' indicates the end of the options. Anything following is not parsed 60 | * and is treated as extra arguments.
  • 61 | *
  • The parser is forgiving, and allows '--' to be used with short options 62 | * and '-' to be used with long options.
  • 63 | *
  • The set of options must be known at parse time. Sub-commands and their 64 | * options do not need to be known at parse time. Use 65 | * {@link ParsedCommandLine#getExtraArguments()} to obtain the non-option 66 | * command-line arguments.
  • 67 | *
68 | */ 69 | public class CommandLineParser { 70 | private Map optionsByString = new HashMap(); 71 | 72 | private boolean allowMixedOptions; 73 | 74 | private boolean allowUnknownOptions; 75 | 76 | private final PrintWriter deprecationPrinter; 77 | 78 | public CommandLineParser() { 79 | this(new OutputStreamWriter(System.out)); 80 | } 81 | 82 | public CommandLineParser(Writer deprecationPrinter) { 83 | this.deprecationPrinter = new PrintWriter(deprecationPrinter); 84 | } 85 | 86 | /** 87 | * Parses the given command-line. 88 | * 89 | * @param commandLine 90 | * The command-line. 91 | * @return The parsed command line. 92 | * @throws org.apache.maven.wrapper.cli.CommandLineArgumentException 93 | * On parse failure. 94 | */ 95 | public ParsedCommandLine parse(String... commandLine) throws CommandLineArgumentException { 96 | return parse(Arrays.asList(commandLine)); 97 | } 98 | 99 | /** 100 | * Parses the given command-line. 101 | * 102 | * @param commandLine 103 | * The command-line. 104 | * @return The parsed command line. 105 | * @throws org.apache.maven.wrapper.cli.CommandLineArgumentException 106 | * On parse failure. 107 | */ 108 | public ParsedCommandLine parse(Iterable commandLine) throws CommandLineArgumentException { 109 | ParsedCommandLine parsedCommandLine = new ParsedCommandLine(new HashSet(optionsByString.values())); 110 | ParserState parseState = new BeforeFirstSubCommand(parsedCommandLine); 111 | for (String arg : commandLine) { 112 | if (parseState.maybeStartOption(arg)) { 113 | if (arg.equals("--")) { 114 | parseState = new AfterOptions(parsedCommandLine); 115 | } else if (arg.matches("--[^=]+")) { 116 | OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(2)); 117 | parseState = parsedOption.onStartNextArg(); 118 | } else if (arg.matches("--[^=]+=.*")) { 119 | int endArg = arg.indexOf('='); 120 | OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(2, endArg)); 121 | parseState = parsedOption.onArgument(arg.substring(endArg + 1)); 122 | } else if (arg.matches("-[^=]=.*")) { 123 | OptionParserState parsedOption = parseState.onStartOption(arg, arg.substring(1, 2)); 124 | parseState = parsedOption.onArgument(arg.substring(3)); 125 | } else { 126 | assert arg.matches("-[^-].*"); 127 | String option = arg.substring(1); 128 | 129 | if (optionsByString.containsKey(option)) { 130 | OptionParserState parsedOption = parseState.onStartOption(arg, option); 131 | parseState = parsedOption.onStartNextArg(); 132 | } else { 133 | String option1 = arg.substring(1, 2); 134 | OptionParserState parsedOption; 135 | 136 | if (optionsByString.containsKey(option1)) { 137 | parsedOption = parseState.onStartOption("-" + option1, option1); 138 | 139 | if (parsedOption.getHasArgument()) { 140 | parseState = parsedOption.onArgument(arg.substring(2)); 141 | } else { 142 | parseState = parsedOption.onComplete(); 143 | 144 | for (int i = 2; i < arg.length(); i++) { 145 | String optionStr = arg.substring(i, i + 1); 146 | parsedOption = parseState.onStartOption("-" + optionStr, optionStr); 147 | parseState = parsedOption.onComplete(); 148 | } 149 | } 150 | } else { 151 | if (allowUnknownOptions) { 152 | // if we are 153 | // allowing 154 | // unknowns, 155 | // just pass 156 | // through the 157 | // whole arg 158 | parsedOption = parseState.onStartOption(arg, option); 159 | parseState = parsedOption.onComplete(); 160 | } else { 161 | // We are going 162 | // to throw a 163 | // CommandLineArgumentException 164 | // below, but 165 | // want the 166 | // message 167 | // to reflect 168 | // that we 169 | // didn't 170 | // recognise the 171 | // first char 172 | // (i.e. the 173 | // option 174 | // specifier) 175 | parsedOption = parseState.onStartOption("-" + option1, option1); 176 | parseState = parsedOption.onComplete(); 177 | } 178 | } 179 | } 180 | } 181 | } else { 182 | parseState = parseState.onNonOption(arg); 183 | } 184 | } 185 | 186 | parseState.onCommandLineEnd(); 187 | return parsedCommandLine; 188 | } 189 | 190 | public CommandLineParser allowMixedSubcommandsAndOptions() { 191 | allowMixedOptions = true; 192 | return this; 193 | } 194 | 195 | public CommandLineParser allowUnknownOptions() { 196 | allowUnknownOptions = true; 197 | return this; 198 | } 199 | 200 | /** 201 | * Prints a usage message to the given stream. 202 | * 203 | * @param out 204 | * The output stream to write to. 205 | */ 206 | public void printUsage(Appendable out) { 207 | Formatter formatter = new Formatter(out); 208 | Set orderedOptions = new TreeSet(new OptionComparator()); 209 | orderedOptions.addAll(optionsByString.values()); 210 | Map lines = new LinkedHashMap(); 211 | 212 | for (CommandLineOption option : orderedOptions) { 213 | Set orderedOptionStrings = new TreeSet(new OptionStringComparator()); 214 | orderedOptionStrings.addAll(option.getOptions()); 215 | List prefixedStrings = new ArrayList(); 216 | 217 | for (String optionString : orderedOptionStrings) { 218 | if (optionString.length() == 1) { 219 | prefixedStrings.add("-" + optionString); 220 | } else { 221 | prefixedStrings.add("--" + optionString); 222 | } 223 | } 224 | 225 | String key = join(prefixedStrings, ", "); 226 | String value = option.getDescription(); 227 | 228 | if (value == null || value.length() == 0) { 229 | value = ""; 230 | } 231 | 232 | lines.put(key, value); 233 | } 234 | 235 | int max = 0; 236 | 237 | for (String optionStr : lines.keySet()) { 238 | max = Math.max(max, optionStr.length()); 239 | } 240 | 241 | for (Map.Entry entry : lines.entrySet()) { 242 | if (entry.getValue().length() == 0) { 243 | formatter.format("%s%n", entry.getKey()); 244 | } else { 245 | formatter.format("%-" + max + "s %s%n", entry.getKey(), entry.getValue()); 246 | } 247 | } 248 | 249 | formatter.flush(); 250 | formatter.close(); 251 | } 252 | 253 | private static String join(Collection things, String separator) { 254 | StringBuilder sb = new StringBuilder(); 255 | boolean first = true; 256 | 257 | if (separator == null) { 258 | separator = ""; 259 | } 260 | 261 | for (Object thing : things) { 262 | if (!first) { 263 | sb.append(separator); 264 | } 265 | sb.append(thing.toString()); 266 | first = false; 267 | } 268 | return sb.toString(); 269 | } 270 | 271 | /** 272 | * Defines a new option. By default, the option takes no arguments and has 273 | * no description. 274 | * 275 | * @param options 276 | * The options values. 277 | * @return The option, which can be further configured. 278 | */ 279 | public CommandLineOption option(String... options) { 280 | for (String option : options) { 281 | if (optionsByString.containsKey(option)) { 282 | throw new IllegalArgumentException(String.format("Option '%s' is already defined.", option)); 283 | } 284 | 285 | if (option.startsWith("-")) { 286 | throw new IllegalArgumentException(String.format("Cannot add option '%s' as an option cannot start with '-'.", option)); 287 | } 288 | } 289 | 290 | CommandLineOption option = new CommandLineOption(Arrays.asList(options)); 291 | 292 | for (String optionStr : option.getOptions()) { 293 | this.optionsByString.put(optionStr, option); 294 | } 295 | 296 | return option; 297 | } 298 | 299 | private static class OptionString { 300 | private final String arg; 301 | 302 | private final String option; 303 | 304 | private OptionString(String arg, String option) { 305 | this.arg = arg; 306 | this.option = option; 307 | } 308 | 309 | public String getDisplayName() { 310 | return arg.startsWith("--") ? "--" + option : "-" + option; 311 | } 312 | 313 | @Override 314 | public String toString() { 315 | return getDisplayName(); 316 | } 317 | } 318 | 319 | private static abstract class ParserState { 320 | public abstract boolean maybeStartOption(String arg); 321 | 322 | boolean isOption(String arg) { 323 | return arg.matches("-.+"); 324 | } 325 | 326 | public abstract OptionParserState onStartOption(String arg, String option); 327 | 328 | public abstract ParserState onNonOption(String arg); 329 | 330 | public void onCommandLineEnd() { 331 | } 332 | } 333 | 334 | private abstract class OptionAwareParserState extends ParserState { 335 | protected final ParsedCommandLine commandLine; 336 | 337 | protected OptionAwareParserState(ParsedCommandLine commandLine) { 338 | this.commandLine = commandLine; 339 | } 340 | 341 | @Override 342 | public boolean maybeStartOption(String arg) { 343 | return isOption(arg); 344 | } 345 | 346 | @Override 347 | public ParserState onNonOption(String arg) { 348 | commandLine.addExtraValue(arg); 349 | return allowMixedOptions ? new AfterFirstSubCommand(commandLine) : new AfterOptions(commandLine); 350 | } 351 | } 352 | 353 | private class BeforeFirstSubCommand extends OptionAwareParserState { 354 | private BeforeFirstSubCommand(ParsedCommandLine commandLine) { 355 | super(commandLine); 356 | } 357 | 358 | @Override 359 | public OptionParserState onStartOption(String arg, String option) { 360 | OptionString optionString = new OptionString(arg, option); 361 | CommandLineOption commandLineOption = optionsByString.get(option); 362 | 363 | if (commandLineOption == null) { 364 | if (allowUnknownOptions) { 365 | return new UnknownOptionParserState(arg, commandLine, this); 366 | } else { 367 | throw new CommandLineArgumentException(String.format("Unknown command-line option '%s'.", optionString)); 368 | } 369 | } 370 | 371 | return new KnownOptionParserState(optionString, commandLineOption, commandLine, this); 372 | } 373 | } 374 | 375 | private class AfterFirstSubCommand extends OptionAwareParserState { 376 | private AfterFirstSubCommand(ParsedCommandLine commandLine) { 377 | super(commandLine); 378 | } 379 | 380 | @Override 381 | public OptionParserState onStartOption(String arg, String option) { 382 | CommandLineOption commandLineOption = optionsByString.get(option); 383 | 384 | if (commandLineOption == null) { 385 | return new UnknownOptionParserState(arg, commandLine, this); 386 | } 387 | 388 | return new KnownOptionParserState(new OptionString(arg, option), commandLineOption, commandLine, this); 389 | } 390 | } 391 | 392 | private static class AfterOptions extends ParserState { 393 | private final ParsedCommandLine commandLine; 394 | 395 | private AfterOptions(ParsedCommandLine commandLine) { 396 | this.commandLine = commandLine; 397 | } 398 | 399 | @Override 400 | public boolean maybeStartOption(String arg) { 401 | return false; 402 | } 403 | 404 | @Override 405 | public OptionParserState onStartOption(String arg, String option) { 406 | return new UnknownOptionParserState(arg, commandLine, this); 407 | } 408 | 409 | @Override 410 | public ParserState onNonOption(String arg) { 411 | commandLine.addExtraValue(arg); 412 | return this; 413 | } 414 | } 415 | 416 | private static class MissingOptionArgState extends ParserState { 417 | private final OptionParserState option; 418 | 419 | private MissingOptionArgState(OptionParserState option) { 420 | this.option = option; 421 | } 422 | 423 | @Override 424 | public boolean maybeStartOption(String arg) { 425 | return isOption(arg); 426 | } 427 | 428 | @Override 429 | public OptionParserState onStartOption(String arg, String option) { 430 | return this.option.onComplete().onStartOption(arg, option); 431 | } 432 | 433 | @Override 434 | public ParserState onNonOption(String arg) { 435 | return option.onArgument(arg); 436 | } 437 | 438 | @Override 439 | public void onCommandLineEnd() { 440 | option.onComplete(); 441 | } 442 | } 443 | 444 | private static abstract class OptionParserState { 445 | public abstract ParserState onStartNextArg(); 446 | 447 | public abstract ParserState onArgument(String argument); 448 | 449 | public abstract boolean getHasArgument(); 450 | 451 | public abstract ParserState onComplete(); 452 | } 453 | 454 | private class KnownOptionParserState extends OptionParserState { 455 | private final OptionString optionString; 456 | 457 | private final CommandLineOption option; 458 | 459 | private final ParsedCommandLine commandLine; 460 | 461 | private final ParserState state; 462 | 463 | private final List values = new ArrayList(); 464 | 465 | private KnownOptionParserState(OptionString optionString, CommandLineOption option, ParsedCommandLine commandLine, 466 | ParserState state) { 467 | this.optionString = optionString; 468 | this.option = option; 469 | this.commandLine = commandLine; 470 | this.state = state; 471 | } 472 | 473 | @Override 474 | public ParserState onArgument(String argument) { 475 | if (!getHasArgument()) { 476 | throw new CommandLineArgumentException(String.format("Command-line option '%s' does not take an argument.", optionString)); 477 | } 478 | 479 | if (argument.length() == 0) { 480 | throw new CommandLineArgumentException( 481 | String.format("An empty argument was provided for command-line option '%s'.", optionString)); 482 | } 483 | 484 | values.add(argument); 485 | return onComplete(); 486 | } 487 | 488 | @Override 489 | public ParserState onStartNextArg() { 490 | if (option.getAllowsArguments() && values.isEmpty()) { 491 | return new MissingOptionArgState(this); 492 | } 493 | 494 | return onComplete(); 495 | } 496 | 497 | @Override 498 | public boolean getHasArgument() { 499 | return option.getAllowsArguments(); 500 | } 501 | 502 | @Override 503 | public ParserState onComplete() { 504 | if (getHasArgument() && values.isEmpty()) { 505 | throw new CommandLineArgumentException( 506 | String.format("No argument was provided for command-line option '%s'.", optionString)); 507 | } 508 | 509 | ParsedCommandLineOption parsedOption = commandLine.addOption(optionString.option, option); 510 | 511 | if (values.size() + parsedOption.getValues().size() > 1 && !option.getAllowsMultipleArguments()) { 512 | throw new CommandLineArgumentException( 513 | String.format("Multiple arguments were provided for command-line option '%s'.", optionString)); 514 | } 515 | 516 | for (String value : values) { 517 | parsedOption.addArgument(value); 518 | } 519 | 520 | if (option.getDeprecationWarning() != null) { 521 | deprecationPrinter.println("The " + optionString + " option is deprecated - " + option.getDeprecationWarning()); 522 | } 523 | 524 | if (option.getSubcommand() != null) { 525 | return state.onNonOption(option.getSubcommand()); 526 | } 527 | 528 | return state; 529 | } 530 | } 531 | 532 | private static class UnknownOptionParserState extends OptionParserState { 533 | private final ParserState state; 534 | 535 | private final String arg; 536 | 537 | private final ParsedCommandLine commandLine; 538 | 539 | private UnknownOptionParserState(String arg, ParsedCommandLine commandLine, ParserState state) { 540 | this.arg = arg; 541 | this.commandLine = commandLine; 542 | this.state = state; 543 | } 544 | 545 | @Override 546 | public boolean getHasArgument() { 547 | return true; 548 | } 549 | 550 | @Override 551 | public ParserState onStartNextArg() { 552 | return onComplete(); 553 | } 554 | 555 | @Override 556 | public ParserState onArgument(String argument) { 557 | return onComplete(); 558 | } 559 | 560 | @Override 561 | public ParserState onComplete() { 562 | commandLine.addExtraValue(arg); 563 | 564 | return state; 565 | } 566 | } 567 | 568 | private static final class OptionComparator implements Comparator { 569 | public int compare(CommandLineOption option1, CommandLineOption option2) { 570 | String min1 = Collections.min(option1.getOptions(), new OptionStringComparator()); 571 | String min2 = Collections.min(option2.getOptions(), new OptionStringComparator()); 572 | return new CaseInsensitiveStringComparator().compare(min1, min2); 573 | } 574 | } 575 | 576 | private static final class CaseInsensitiveStringComparator implements Comparator { 577 | public int compare(String option1, String option2) { 578 | int diff = option1.compareToIgnoreCase(option2); 579 | 580 | if (diff != 0) { 581 | return diff; 582 | } 583 | 584 | return option1.compareTo(option2); 585 | } 586 | } 587 | 588 | private static final class OptionStringComparator implements Comparator { 589 | public int compare(String option1, String option2) { 590 | boolean short1 = option1.length() == 1; 591 | boolean short2 = option2.length() == 1; 592 | 593 | if (short1 && !short2) { 594 | return -1; 595 | } 596 | 597 | if (!short1 && short2) { 598 | return 1; 599 | } 600 | 601 | return new CaseInsensitiveStringComparator().compare(option1, option2); 602 | } 603 | } 604 | } 605 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/ParsedCommandLine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper.cli; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Collection; 20 | import java.util.HashMap; 21 | import java.util.HashSet; 22 | import java.util.List; 23 | import java.util.Map; 24 | import java.util.Set; 25 | 26 | public class ParsedCommandLine { 27 | private final Map optionsByString = new HashMap(); 28 | 29 | private final Set presentOptions = new HashSet(); 30 | 31 | private final List extraArguments = new ArrayList(); 32 | 33 | ParsedCommandLine(Iterable options) { 34 | for (CommandLineOption option : options) { 35 | ParsedCommandLineOption parsedOption = new ParsedCommandLineOption(); 36 | 37 | for (String optionStr : option.getOptions()) { 38 | optionsByString.put(optionStr, parsedOption); 39 | } 40 | } 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return String.format("options: %s, extraArguments: %s", quoteAndJoin(presentOptions), quoteAndJoin(extraArguments)); 46 | } 47 | 48 | private String quoteAndJoin(Iterable strings) { 49 | StringBuilder output = new StringBuilder(); 50 | boolean isFirst = true; 51 | 52 | for (String string : strings) { 53 | if (!isFirst) { 54 | output.append(", "); 55 | } 56 | 57 | output.append("'"); 58 | output.append(string); 59 | output.append("'"); 60 | isFirst = false; 61 | } 62 | 63 | return output.toString(); 64 | } 65 | 66 | /** 67 | * Returns true if the given option is present in this command-line. 68 | * 69 | * @param option 70 | * The option, without the '-' or '--' prefix. 71 | * @return true if the option is present. 72 | */ 73 | public boolean hasOption(String option) { 74 | option(option); 75 | 76 | return presentOptions.contains(option); 77 | } 78 | 79 | /** 80 | * See also {@link #hasOption}. 81 | * 82 | * @param logLevelOptions 83 | * the options to check 84 | * @return true if any of the passed options is present 85 | */ 86 | public boolean hasAnyOption(Collection logLevelOptions) { 87 | for (String option : logLevelOptions) { 88 | if (hasOption(option)) { 89 | return true; 90 | } 91 | } 92 | 93 | return false; 94 | } 95 | 96 | /** 97 | * Returns the value of the given option. 98 | * 99 | * @param option 100 | * The option, without the '-' or '--' prefix. 101 | * @return The option. never returns null. 102 | */ 103 | public ParsedCommandLineOption option(String option) { 104 | ParsedCommandLineOption parsedOption = optionsByString.get(option); 105 | 106 | if (parsedOption == null) { 107 | throw new IllegalArgumentException(String.format("Option '%s' not defined.", option)); 108 | } 109 | 110 | return parsedOption; 111 | } 112 | 113 | public List getExtraArguments() { 114 | return extraArguments; 115 | } 116 | 117 | void addExtraValue(String value) { 118 | extraArguments.add(value); 119 | } 120 | 121 | ParsedCommandLineOption addOption(String optionStr, CommandLineOption option) { 122 | ParsedCommandLineOption parsedOption = optionsByString.get(optionStr); 123 | presentOptions.addAll(option.getOptions()); 124 | 125 | return parsedOption; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/ParsedCommandLineOption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper.cli; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | public class ParsedCommandLineOption { 22 | private final List values = new ArrayList(); 23 | 24 | public String getValue() { 25 | if (!hasValue()) { 26 | throw new IllegalStateException("Option does not have any value."); 27 | } 28 | 29 | if (values.size() > 1) { 30 | throw new IllegalStateException("Option has multiple values."); 31 | } 32 | 33 | return values.get(0); 34 | } 35 | 36 | public List getValues() { 37 | return values; 38 | } 39 | 40 | public void addArgument(String argument) { 41 | values.add(argument); 42 | } 43 | 44 | public boolean hasValue() { 45 | return !values.isEmpty(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/ProjectPropertiesCommandLineConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.apache.maven.wrapper.cli; 18 | 19 | public class ProjectPropertiesCommandLineConverter extends AbstractPropertiesCommandLineConverter { 20 | 21 | @Override 22 | protected String getPropertyOption() { 23 | return "P"; 24 | } 25 | 26 | @Override 27 | protected String getPropertyOptionDetailed() { 28 | return "project-prop"; 29 | } 30 | 31 | @Override 32 | protected String getPropertyOptionDescription() { 33 | return "Set project property for the build script (e.g. -Pmyprop=myvalue)."; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/apache/maven/wrapper/cli/SystemPropertiesCommandLineConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper.cli; 17 | 18 | public class SystemPropertiesCommandLineConverter extends AbstractPropertiesCommandLineConverter { 19 | 20 | @Override 21 | protected String getPropertyOption() { 22 | return "D"; 23 | } 24 | 25 | @Override 26 | protected String getPropertyOptionDetailed() { 27 | return "system-prop"; 28 | } 29 | 30 | @Override 31 | protected String getPropertyOptionDescription() { 32 | return "Set system property of the JVM (e.g. -Dmyprop=myvalue)."; 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/resources/com/rimerosolutions/maven/plugins/wrapper/mvnw_footer: -------------------------------------------------------------------------------- 1 | " \ 2 | ${WRAPPER_LAUNCHER} "$@" 3 | -------------------------------------------------------------------------------- /src/main/resources/com/rimerosolutions/maven/plugins/wrapper/mvnw_footer.bat: -------------------------------------------------------------------------------- 1 | " 2 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 3 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 4 | 5 | if ERRORLEVEL 1 goto error 6 | goto end 7 | 8 | :error 9 | set ERROR_CODE=1 10 | 11 | :end 12 | @endlocal & set ERROR_CODE=%ERROR_CODE% 13 | 14 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 15 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 16 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 17 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 18 | :skipRcPost 19 | 20 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 21 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 22 | 23 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 24 | 25 | exit /B %ERROR_CODE% 26 | -------------------------------------------------------------------------------- /src/main/resources/com/rimerosolutions/maven/plugins/wrapper/mvnw_header: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # 58 | # Look for the Apple JDKs first to preserve the existing behaviour, and then look 59 | # for the new JDKs provided by Oracle. 60 | # 61 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then 62 | # 63 | # Apple JDKs 64 | # 65 | export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home 66 | fi 67 | 68 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then 69 | # 70 | # Apple JDKs 71 | # 72 | export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 73 | fi 74 | 75 | if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then 76 | # 77 | # Oracle JDKs 78 | # 79 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 80 | fi 81 | 82 | if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then 83 | # 84 | # Apple JDKs 85 | # 86 | export JAVA_HOME=`/usr/libexec/java_home` 87 | fi 88 | ;; 89 | esac 90 | 91 | if [ -z "$JAVA_HOME" ] ; then 92 | if [ -r /etc/gentoo-release ] ; then 93 | JAVA_HOME=`java-config --jre-home` 94 | fi 95 | fi 96 | 97 | if [ -z "$M2_HOME" ] ; then 98 | ## resolve links - $0 may be a link to maven's home 99 | PRG="$0" 100 | 101 | # need this for relative symlinks 102 | while [ -h "$PRG" ] ; do 103 | ls=`ls -ld "$PRG"` 104 | link=`expr "$ls" : '.*-> \(.*\)$'` 105 | if expr "$link" : '/.*' > /dev/null; then 106 | PRG="$link" 107 | else 108 | PRG="`dirname "$PRG"`/$link" 109 | fi 110 | done 111 | 112 | saveddir=`pwd` 113 | 114 | M2_HOME=`dirname "$PRG"`/.. 115 | 116 | # make it fully qualified 117 | M2_HOME=`cd "$M2_HOME" && pwd` 118 | 119 | cd "$saveddir" 120 | # echo Using m2 at $M2_HOME 121 | fi 122 | 123 | # For Cygwin, ensure paths are in UNIX format before anything is touched 124 | if $cygwin ; then 125 | [ -n "$M2_HOME" ] && 126 | M2_HOME=`cygpath --unix "$M2_HOME"` 127 | [ -n "$JAVA_HOME" ] && 128 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 129 | [ -n "$CLASSPATH" ] && 130 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 131 | fi 132 | 133 | # For Migwn, ensure paths are in UNIX format before anything is touched 134 | if $mingw ; then 135 | [ -n "$M2_HOME" ] && 136 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 137 | [ -n "$JAVA_HOME" ] && 138 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 139 | # TODO classpath? 140 | fi 141 | 142 | if [ -z "$JAVA_HOME" ]; then 143 | javaExecutable="`which javac`" 144 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 145 | # readlink(1) is not available as standard on Solaris 10. 146 | readLink=`which readlink` 147 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 148 | if $darwin ; then 149 | javaHome="`dirname \"$javaExecutable\"`" 150 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 151 | else 152 | javaExecutable="`readlink -f \"$javaExecutable\"`" 153 | fi 154 | javaHome="`dirname \"$javaExecutable\"`" 155 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 156 | JAVA_HOME="$javaHome" 157 | export JAVA_HOME 158 | fi 159 | fi 160 | fi 161 | 162 | if [ -z "$JAVACMD" ] ; then 163 | if [ -n "$JAVA_HOME" ] ; then 164 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 165 | # IBM's JDK on AIX uses strange locations for the executables 166 | JAVACMD="$JAVA_HOME/jre/sh/java" 167 | else 168 | JAVACMD="$JAVA_HOME/bin/java" 169 | fi 170 | else 171 | JAVACMD="`which java`" 172 | fi 173 | fi 174 | 175 | if [ ! -x "$JAVACMD" ] ; then 176 | echo "Error: JAVA_HOME is not defined correctly." >&2 177 | echo " We cannot execute $JAVACMD" >&2 178 | exit 1 179 | fi 180 | 181 | if [ -z "$JAVA_HOME" ] ; then 182 | echo "Warning: JAVA_HOME environment variable is not set." 183 | fi 184 | 185 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 186 | 187 | # For Cygwin, switch paths to Windows format before running java 188 | if $cygwin; then 189 | [ -n "$M2_HOME" ] && 190 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 191 | [ -n "$JAVA_HOME" ] && 192 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 193 | [ -n "$CLASSPATH" ] && 194 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 195 | fi 196 | 197 | # traverses directory structure from process work directory to filesystem root 198 | # first directory with .mvn subdirectory is considered project base directory 199 | find_maven_basedir() { 200 | local basedir=$(pwd) 201 | local wdir=$(pwd) 202 | while [ "$wdir" != '/' ] ; do 203 | wdir=$(cd "$wdir/.."; pwd) 204 | if [ -d "$wdir"/.mvn ] ; then 205 | basedir=$wdir 206 | break 207 | fi 208 | done 209 | echo "${basedir}" 210 | } 211 | 212 | # concatenates all lines of a file 213 | concat_lines() { 214 | if [ -f "$1" ]; then 215 | echo "$(tr -s '\n' ' ' < "$1")" 216 | fi 217 | } 218 | 219 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} 220 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 221 | 222 | # Provide a "standardized" way to retrieve the CLI args that will 223 | # work with both Windows and non-Windows executions. 224 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 225 | export MAVEN_CMD_LINE_ARGS 226 | 227 | WRAPPER_LAUNCHER="org.apache.maven.wrapper.MavenWrapperMain" 228 | 229 | exec "$JAVACMD" \ 230 | $MAVEN_OPTS \ 231 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 232 | -classpath \ 233 | -------------------------------------------------------------------------------- /src/main/resources/com/rimerosolutions/maven/plugins/wrapper/mvnw_header.bat: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto chkMHome 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | :chkMHome 80 | if not "%M2_HOME%"=="" goto valMHome 81 | 82 | SET "M2_HOME=%~dp0.." 83 | if not "%M2_HOME%"=="" goto valMHome 84 | 85 | echo. 86 | echo Error: M2_HOME not found in your environment. >&2 87 | echo Please set the M2_HOME variable in your environment to match the >&2 88 | echo location of the Maven installation. >&2 89 | echo. 90 | goto error 91 | 92 | :valMHome 93 | 94 | :stripMHome 95 | if not "_%M2_HOME:~-1%"=="_\" goto checkMCmd 96 | set "M2_HOME=%M2_HOME:~0,-1%" 97 | goto stripMHome 98 | 99 | :checkMCmd 100 | if exist "%M2_HOME%\bin\mvn.cmd" goto init 101 | 102 | echo. 103 | echo Error: M2_HOME is set to an invalid directory. >&2 104 | echo M2_HOME = "%M2_HOME%" >&2 105 | echo Please set the M2_HOME variable in your environment to match the >&2 106 | echo location of the Maven installation >&2 107 | echo. 108 | goto error 109 | @REM ==== END VALIDATION ==== 110 | 111 | :init 112 | 113 | set MAVEN_CMD_LINE_ARGS=%* 114 | 115 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 116 | @REM Fallback to current working directory if not found. 117 | 118 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 119 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 120 | 121 | set EXEC_DIR=%CD% 122 | set WDIR=%EXEC_DIR% 123 | :findBaseDir 124 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 125 | cd .. 126 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 127 | set WDIR=%CD% 128 | goto findBaseDir 129 | 130 | :baseDirFound 131 | set MAVEN_PROJECTBASEDIR=%WDIR% 132 | cd "%EXEC_DIR%" 133 | goto endDetectBaseDir 134 | 135 | :baseDirNotFound 136 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 137 | cd "%EXEC_DIR%" 138 | 139 | :endDetectBaseDir 140 | 141 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 142 | 143 | @setlocal EnableExtensions EnableDelayedExpansion 144 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 145 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 146 | 147 | :endReadAdditionalConfig 148 | 149 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 150 | -------------------------------------------------------------------------------- /src/main/resources/maven_wrapper_logging.properties: -------------------------------------------------------------------------------- 1 | ############################################################ 2 | # Default Logging Configuration File 3 | # 4 | # To also add the FileHandler, use the following line instead. 5 | handlers= java.util.logging.ConsoleHandler 6 | 7 | # Default global logging level. 8 | # This specifies which kinds of events are logged across 9 | # all loggers. For any given facility this global level 10 | # can be overriden by a facility specific level 11 | # Note that the ConsoleHandler also has a separate level 12 | # setting to limit messages printed to the console. 13 | .level= INFO 14 | 15 | # Limit the message that are printed on the console to INFO and above. 16 | java.util.logging.ConsoleHandler.level = INFO -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/wrapper/DownloaderTest.java: -------------------------------------------------------------------------------- 1 | package org.apache.maven.wrapper; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.io.File; 6 | import java.net.URI; 7 | 8 | import org.apache.commons.io.FileUtils; 9 | import org.junit.After; 10 | import org.junit.Before; 11 | import org.junit.Test; 12 | 13 | public class DownloaderTest { 14 | private DefaultDownloader download; 15 | private File testDir; 16 | private File downloadFile; 17 | private File rootDir; 18 | private URI sourceRoot; 19 | private File remoteFile; 20 | 21 | @Before 22 | public void setUp() throws Exception { 23 | download = new DefaultDownloader("mvnw", "aVersion"); 24 | testDir = new File("target/test-files/DownloadTest"); 25 | rootDir = new File(testDir, "root"); 26 | downloadFile = new File(rootDir, "file"); 27 | 28 | FileUtils.deleteQuietly(downloadFile); 29 | 30 | remoteFile = new File(testDir, "remoteFile"); 31 | FileUtils.write(remoteFile, "sometext"); 32 | sourceRoot = remoteFile.toURI(); 33 | } 34 | 35 | @Test 36 | public void testDownload() throws Exception { 37 | assert !downloadFile.exists(); 38 | download.download(sourceRoot, downloadFile); 39 | assert downloadFile.exists(); 40 | assertEquals("sometext", FileUtils.readFileToString(downloadFile)); 41 | } 42 | 43 | @After 44 | public void tearDown() { 45 | FileUtils.deleteQuietly(downloadFile); 46 | FileUtils.deleteQuietly(remoteFile); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/wrapper/InstallerTest.java: -------------------------------------------------------------------------------- 1 | package org.apache.maven.wrapper; 2 | 3 | import static org.mockito.AdditionalMatchers.or; 4 | import static org.mockito.Matchers.any; 5 | import static org.mockito.Matchers.eq; 6 | import static org.mockito.Mockito.doAnswer; 7 | import static org.mockito.Mockito.mock; 8 | import static org.mockito.Mockito.times; 9 | import static org.mockito.Mockito.verify; 10 | import static org.mockito.Mockito.when; 11 | 12 | import java.io.File; 13 | import java.io.FileInputStream; 14 | import java.io.FileOutputStream; 15 | import java.io.IOException; 16 | import java.io.InputStream; 17 | import java.net.URI; 18 | import java.util.Arrays; 19 | import java.util.Collections; 20 | import java.util.zip.ZipEntry; 21 | import java.util.zip.ZipOutputStream; 22 | 23 | import org.apache.commons.io.FileUtils; 24 | import org.apache.maven.wrapper.PathAssembler.LocalDistribution; 25 | import org.junit.Assert; 26 | import org.junit.Before; 27 | import org.junit.Test; 28 | import org.mockito.invocation.InvocationOnMock; 29 | import org.mockito.stubbing.Answer; 30 | 31 | /** 32 | * @author Hans Dockter 33 | */ 34 | public class InstallerTest { 35 | private File testDir = new File("target/test-files/SystemPropertiesHandlerTest-" + System.currentTimeMillis()); 36 | private Installer install; 37 | private File distributionDir; 38 | private File zipStore; 39 | private File mavenHomeDir; 40 | private File zipDestination; 41 | private File checksumDestination; 42 | private WrapperConfiguration configuration = new WrapperConfiguration(); 43 | private Downloader download; 44 | private PathAssembler pathAssembler; 45 | private LocalDistribution localDistribution; 46 | private static URI WORKING_DISTRIBUTION_URI = URI.create("http://server/maven-0.9.zip"); 47 | private static URI BROKEN_DISTRIBUTION_URI = URI.create("http://server.down/maven-0.9.zip"); 48 | private static URI CHECKSUM_URI = URI.create("http://server/maven-0.9.zip.sha1"); 49 | 50 | @Before 51 | public void setup() throws Exception { 52 | testDir.mkdirs(); 53 | configuration.setZipBase(PathAssembler.PROJECT_STRING); 54 | configuration.setZipPath("someZipPath"); 55 | configuration.setDistributionBase(PathAssembler.MAVEN_USER_HOME_STRING); 56 | configuration.setDistributionPath("someDistPath"); 57 | configuration.setDistributionUris(Collections.singletonList(WORKING_DISTRIBUTION_URI)); 58 | configuration.setAlwaysDownload(false); 59 | configuration.setAlwaysUnpack(false); 60 | distributionDir = new File(testDir, "someDistPath"); 61 | mavenHomeDir = new File(distributionDir, "maven-0.9"); 62 | zipStore = new File(testDir, "zips"); 63 | zipDestination = new File(zipStore, "maven-0.9.zip"); 64 | checksumDestination = new File(zipStore, "maven-0.9.zip.checksum"); 65 | 66 | download = mock(Downloader.class); 67 | pathAssembler = mock(PathAssembler.class); 68 | localDistribution = mock(LocalDistribution.class); 69 | 70 | doAnswer(new Answer() { 71 | @Override 72 | public Void answer(final InvocationOnMock invocationOnMock) throws Throwable { 73 | File downloadTarget = (File) invocationOnMock.getArguments()[1]; 74 | FileUtils.copyFile(zipDestination, downloadTarget); 75 | return null; 76 | } 77 | }).when(download).download(eq(WORKING_DISTRIBUTION_URI), any(File.class)); 78 | 79 | doAnswer(new Answer() { 80 | @Override 81 | public Void answer(final InvocationOnMock invocationOnMock) throws Throwable { 82 | URI address = (URI) invocationOnMock.getArguments()[0]; 83 | throw new IOException("Connection refused to '" + address + "'."); 84 | } 85 | }).when(download).download(eq(BROKEN_DISTRIBUTION_URI), any(File.class)); 86 | 87 | doAnswer(new Answer() { 88 | @Override 89 | public Void answer(final InvocationOnMock invocationOnMock) throws Throwable { 90 | File downloadTarget = (File) invocationOnMock.getArguments()[1]; 91 | FileUtils.copyFile(checksumDestination, downloadTarget); 92 | return null; 93 | } 94 | }).when(download).download(eq(CHECKSUM_URI), any(File.class)); 95 | when(localDistribution.getZipFile()).thenReturn(zipDestination); 96 | when(localDistribution.getDistributionDir()).thenReturn(distributionDir); 97 | when(pathAssembler.getDistribution(configuration, WORKING_DISTRIBUTION_URI)).thenReturn(localDistribution); 98 | when(pathAssembler.getDistribution(configuration, BROKEN_DISTRIBUTION_URI)).thenReturn(localDistribution); 99 | 100 | install = new Installer(download, pathAssembler); 101 | } 102 | 103 | private void createTestZip(File zipDestination) throws Exception { 104 | File explodedZipDir = new File(testDir, "explodedZip"); 105 | explodedZipDir.mkdirs(); 106 | zipDestination.getParentFile().mkdirs(); 107 | File mavenScript = new File(explodedZipDir, "maven-0.9/bin/mvn"); 108 | mavenScript.getParentFile().mkdirs(); 109 | FileUtils.write(mavenScript, "something"); 110 | 111 | zipTo(explodedZipDir, zipDestination); 112 | } 113 | 114 | private void createChecksum(final File checksumDestination, final String checksum) throws Exception { 115 | FileUtils.write(checksumDestination, checksum); 116 | } 117 | 118 | public void testCreateDist() throws Exception { 119 | File homeDir = install.createDist(configuration); 120 | 121 | Assert.assertEquals(mavenHomeDir, homeDir); 122 | Assert.assertTrue(homeDir.isDirectory()); 123 | Assert.assertTrue(new File(homeDir, "bin/mvn").exists()); 124 | Assert.assertTrue(zipDestination.exists()); 125 | 126 | Assert.assertEquals(localDistribution, pathAssembler.getDistribution(configuration, WORKING_DISTRIBUTION_URI)); 127 | Assert.assertEquals(distributionDir, localDistribution.getDistributionDir()); 128 | Assert.assertEquals(zipDestination, localDistribution.getZipFile()); 129 | 130 | download.download(new URI("http://some/test"), distributionDir); 131 | verify(download).download(new URI("http://some/test"), 132 | distributionDir); 133 | } 134 | 135 | @Test 136 | public void testCreateDistWithExistingDistribution() throws Exception { 137 | FileUtils.touch(zipDestination); 138 | mavenHomeDir.mkdirs(); 139 | File someFile = new File(mavenHomeDir, "some-file"); 140 | FileUtils.touch(someFile); 141 | 142 | File homeDir = install.createDist(configuration); 143 | 144 | Assert.assertEquals(mavenHomeDir, homeDir); 145 | Assert.assertTrue(mavenHomeDir.isDirectory()); 146 | Assert.assertTrue(new File(homeDir, "some-file").exists()); 147 | Assert.assertTrue(zipDestination.exists()); 148 | 149 | Assert.assertEquals(localDistribution, pathAssembler.getDistribution(configuration, WORKING_DISTRIBUTION_URI)); 150 | Assert.assertEquals(distributionDir, localDistribution.getDistributionDir()); 151 | Assert.assertEquals(zipDestination, localDistribution.getZipFile()); 152 | } 153 | 154 | @Test 155 | public void testCreateDistWithExistingDistAndZipAndAlwaysUnpackTrue() throws Exception { 156 | createTestZip(zipDestination); 157 | mavenHomeDir.mkdirs(); 158 | File garbage = new File(mavenHomeDir, "garbage"); 159 | FileUtils.touch(garbage); 160 | configuration.setAlwaysUnpack(true); 161 | 162 | File homeDir = install.createDist(configuration); 163 | 164 | Assert.assertEquals(mavenHomeDir, homeDir); 165 | Assert.assertTrue(mavenHomeDir.isDirectory()); 166 | Assert.assertFalse(new File(homeDir, "garbage").exists()); 167 | Assert.assertTrue(zipDestination.exists()); 168 | 169 | Assert.assertEquals(localDistribution, pathAssembler.getDistribution(configuration, WORKING_DISTRIBUTION_URI)); 170 | Assert.assertEquals(distributionDir, localDistribution.getDistributionDir()); 171 | Assert.assertEquals(zipDestination, localDistribution.getZipFile()); 172 | } 173 | 174 | @Test 175 | public void testCreateDistWithExistingZipAndDistAndAlwaysDownloadTrue() throws Exception { 176 | createTestZip(zipDestination); 177 | File garbage = new File(mavenHomeDir, "garbage"); 178 | FileUtils.touch(garbage); 179 | configuration.setAlwaysUnpack(true); 180 | 181 | File homeDir = install.createDist(configuration); 182 | 183 | Assert.assertEquals(mavenHomeDir, homeDir); 184 | Assert.assertTrue(mavenHomeDir.isDirectory()); 185 | Assert.assertTrue(new File(homeDir, "bin/mvn").exists()); 186 | Assert.assertFalse(new File(homeDir, "garbage").exists()); 187 | Assert.assertTrue(zipDestination.exists()); 188 | 189 | Assert.assertEquals(localDistribution, pathAssembler.getDistribution(configuration, WORKING_DISTRIBUTION_URI)); 190 | Assert.assertEquals(distributionDir, localDistribution.getDistributionDir()); 191 | Assert.assertEquals(zipDestination, localDistribution.getZipFile()); 192 | 193 | // download.download(new URI("http://some/test"), distributionDir); 194 | // verify(download).download(new URI("http://some/test"), 195 | // distributionDir); 196 | } 197 | 198 | @Test 199 | public void testVerifyDownload() throws Exception { 200 | configuration.setAlwaysDownload(true); 201 | configuration.setVerifyDownload(true); 202 | // configuration.setChecksum(Collections.singletonList(CHECKSUM_URI)); 203 | configuration.setChecksumAlgorithm(Checksum.SHA1); 204 | 205 | createTestZip(zipDestination); 206 | createChecksum(checksumDestination, Checksum.SHA1.generate(new FileInputStream(zipDestination))); 207 | mavenHomeDir.mkdirs(); 208 | File garbage = new File(mavenHomeDir, "garbage"); 209 | FileUtils.touch(garbage); 210 | configuration.setAlwaysUnpack(true); 211 | 212 | File homeDir = install.createDist(configuration); 213 | 214 | Assert.assertEquals(mavenHomeDir, homeDir); 215 | Assert.assertTrue(mavenHomeDir.isDirectory()); 216 | Assert.assertTrue(new File(homeDir, "bin/mvn").exists()); 217 | Assert.assertFalse(new File(homeDir, "garbage").exists()); 218 | Assert.assertTrue(zipDestination.exists()); 219 | 220 | Assert.assertEquals(localDistribution, pathAssembler.getDistribution(configuration, WORKING_DISTRIBUTION_URI)); 221 | Assert.assertEquals(distributionDir, localDistribution.getDistributionDir()); 222 | Assert.assertEquals(zipDestination, localDistribution.getZipFile()); 223 | } 224 | 225 | @Test 226 | public void testVerifyDownloadFails() throws Exception { 227 | configuration.setAlwaysDownload(true); 228 | configuration.setVerifyDownload(true); 229 | configuration.setChecksumAlgorithm(Checksum.SHA1); 230 | 231 | createTestZip(zipDestination); 232 | createChecksum(checksumDestination, "Foo-Bar"); 233 | mavenHomeDir.mkdirs(); 234 | File garbage = new File(mavenHomeDir, "garbage"); 235 | FileUtils.touch(garbage); 236 | configuration.setAlwaysUnpack(true); 237 | 238 | try { 239 | install.createDist(configuration); 240 | Assert.fail("Expected RuntimeException"); 241 | } catch (final RuntimeException e) { 242 | Assert.assertEquals("Maven distribution '" + WORKING_DISTRIBUTION_URI.toString() + "' failed to verify against '" 243 | + CHECKSUM_URI.toString() + "'.", e.getMessage()); 244 | } 245 | } 246 | 247 | @Test 248 | public void testMultipleDistributionsFirstSucceeds() throws Exception { 249 | configuration.setAlwaysDownload(true); 250 | configuration.setDistributionUris(Arrays.asList(WORKING_DISTRIBUTION_URI, BROKEN_DISTRIBUTION_URI)); 251 | 252 | createTestZip(zipDestination); 253 | mavenHomeDir.mkdirs(); 254 | File garbage = new File(mavenHomeDir, "garbage"); 255 | FileUtils.touch(garbage); 256 | configuration.setAlwaysUnpack(true); 257 | 258 | File homeDir = install.createDist(configuration); 259 | 260 | Assert.assertEquals(mavenHomeDir, homeDir); 261 | Assert.assertTrue(mavenHomeDir.isDirectory()); 262 | Assert.assertTrue(new File(homeDir, "bin/mvn").exists()); 263 | Assert.assertFalse(new File(homeDir, "garbage").exists()); 264 | Assert.assertTrue(zipDestination.exists()); 265 | 266 | Assert.assertEquals(localDistribution, pathAssembler.getDistribution(configuration, WORKING_DISTRIBUTION_URI)); 267 | Assert.assertEquals(distributionDir, localDistribution.getDistributionDir()); 268 | Assert.assertEquals(zipDestination, localDistribution.getZipFile()); 269 | 270 | verify(download).download(eq(WORKING_DISTRIBUTION_URI), any(File.class)); 271 | } 272 | 273 | @Test 274 | public void testMultipleDistributionsFirstFail() throws Exception { 275 | configuration.setAlwaysDownload(true); 276 | configuration.setDistributionUris(Arrays.asList(BROKEN_DISTRIBUTION_URI, WORKING_DISTRIBUTION_URI)); 277 | 278 | createTestZip(zipDestination); 279 | mavenHomeDir.mkdirs(); 280 | File garbage = new File(mavenHomeDir, "garbage"); 281 | FileUtils.touch(garbage); 282 | configuration.setAlwaysUnpack(true); 283 | 284 | File homeDir = install.createDist(configuration); 285 | 286 | Assert.assertEquals(mavenHomeDir, homeDir); 287 | Assert.assertTrue(mavenHomeDir.isDirectory()); 288 | Assert.assertTrue(new File(homeDir, "bin/mvn").exists()); 289 | Assert.assertFalse(new File(homeDir, "garbage").exists()); 290 | Assert.assertTrue(zipDestination.exists()); 291 | 292 | Assert.assertEquals(localDistribution, pathAssembler.getDistribution(configuration, WORKING_DISTRIBUTION_URI)); 293 | Assert.assertEquals(distributionDir, localDistribution.getDistributionDir()); 294 | Assert.assertEquals(zipDestination, localDistribution.getZipFile()); 295 | 296 | verify(download, times(2)).download(or(eq(BROKEN_DISTRIBUTION_URI), eq(WORKING_DISTRIBUTION_URI)), any(File.class)); 297 | } 298 | 299 | @Test 300 | public void testMultipleDistributionsBothFail() throws Exception { 301 | configuration.setAlwaysDownload(true); 302 | configuration.setDistributionUris(Arrays.asList(BROKEN_DISTRIBUTION_URI, BROKEN_DISTRIBUTION_URI)); 303 | 304 | createTestZip(zipDestination); 305 | mavenHomeDir.mkdirs(); 306 | File garbage = new File(mavenHomeDir, "garbage"); 307 | FileUtils.touch(garbage); 308 | configuration.setAlwaysUnpack(true); 309 | 310 | try { 311 | install.createDist(configuration); 312 | Assert.fail("Expected RuntimeException"); 313 | } catch (final IOException e) { 314 | Assert.assertEquals("Connection refused to '" + BROKEN_DISTRIBUTION_URI + "'.", e.getMessage()); 315 | } 316 | 317 | verify(download, times(2)).download(eq(BROKEN_DISTRIBUTION_URI), any(File.class)); 318 | } 319 | 320 | private static void zipTo(File directoryToZip, File destFile) throws IOException { 321 | FileOutputStream fos = null; 322 | ZipOutputStream zout = null; 323 | 324 | try { 325 | fos = new FileOutputStream(destFile); 326 | zout = new ZipOutputStream(fos); 327 | 328 | for (File f : directoryToZip.listFiles()) { 329 | zipFiles("", zout, f); 330 | } 331 | } finally { 332 | if (zout != null) { 333 | zout.close(); 334 | } 335 | 336 | if (fos != null) { 337 | fos.close(); 338 | } 339 | } 340 | } 341 | 342 | private static void zipFile(String prefixPath, ZipOutputStream zout, File f) throws IOException { 343 | InputStream fin = null; 344 | 345 | try { 346 | ZipEntry ze = new ZipEntry(prefixPath + f.getName()); 347 | ze.setTime(f.lastModified()); 348 | zout.putNextEntry(ze); 349 | fin = new FileInputStream(f); 350 | byte[] buffer = new byte[4096]; 351 | 352 | for (int n; (n = fin.read(buffer)) > 0;) { 353 | zout.write(buffer, 0, n); 354 | } 355 | 356 | zout.closeEntry(); 357 | } finally { 358 | if (fin != null) { 359 | fin.close(); 360 | } 361 | } 362 | 363 | } 364 | 365 | private static void zipFolder(String prefixPath, ZipOutputStream zout, File f) throws IOException { 366 | ZipEntry ze = new ZipEntry(prefixPath + f.getName() + '/'); 367 | ze.setTime(f.lastModified()); 368 | zout.putNextEntry(ze); 369 | zout.closeEntry(); 370 | 371 | for (File file : f.listFiles()) { 372 | zipFiles(prefixPath + f.getName(), zout, file); 373 | } 374 | } 375 | 376 | private static void zipFiles(String prefix, ZipOutputStream zout, File f) throws IOException { 377 | String prefixPath = prefix + "/"; 378 | 379 | if (prefixPath.startsWith("/")) { 380 | prefixPath = prefixPath.substring(1); 381 | } 382 | 383 | if (f.isFile()) { 384 | zipFile(prefixPath, zout, f); 385 | } else { 386 | zipFolder(prefixPath, zout, f); 387 | } 388 | } 389 | 390 | } 391 | -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/wrapper/MavenWrapperMojoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013. Rimero Solutions 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import static org.mockito.Mockito.mock; 19 | import static org.mockito.Mockito.verify; 20 | import static org.mockito.Mockito.when; 21 | import static org.mockito.Mockito.times; 22 | 23 | import java.io.File; 24 | import java.io.FileInputStream; 25 | import java.io.IOException; 26 | import java.io.InputStream; 27 | import java.util.Arrays; 28 | import java.util.Collections; 29 | import java.util.List; 30 | import java.util.Properties; 31 | 32 | import org.apache.commons.io.IOUtils; 33 | import org.apache.maven.artifact.Artifact; 34 | import org.apache.maven.plugin.descriptor.PluginDescriptor; 35 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 36 | import org.codehaus.plexus.configuration.PlexusConfiguration; 37 | 38 | /** 39 | * Unit test the Maven Wrapper Mojo 40 | * 41 | * @author Yves Zoundi 42 | */ 43 | public class MavenWrapperMojoTest extends AbstractMojoTestCase { 44 | 45 | private static final String MAVEN_WRAPPER_PLUGIN_NAME = "wrapper-maven-plugin"; 46 | private static final String TEST_WRAPPER_DIR_LOCATION = "target/test-wrapper"; 47 | private static final String TEST_SUPPORT_DIR_LOCATION = "support"; 48 | private static final String TEST_DISTRIBUTION_URL = "http://mirrors.ibiblio.org/maven2/org/apache/maven/apache-maven"; 49 | private static final List TEST_DISTRIBUTION_URL_LIST = Collections 50 | .unmodifiableList(Arrays.asList("http://mirrors.ibiblio.org/maven2/org/apache/maven/apache-maven", 51 | "https://repo1.maven.org/maven2/org/apache/maven/apache-maven")); 52 | private static final String PLUGIN_TEST_FILE_LOCATION = "src/test/resources/org/apache/maven/wrapper/plugin-config.xml"; 53 | private static final String PLUGIN_TEST_ARTIFACT_LOCATION = "src/test/resources/org/apache/maven/wrapper/dummy-wrapper-artifact.txt"; 54 | private static final String MAVEN_RUNTIME_VERSION = "0.0.1"; 55 | private static final Boolean VERIFY_DOWNLOAD = true; 56 | private static final String CHECKSUM_ALGORITHM = "MD5"; 57 | private static final String CHECKSUM_EXTENSION = "md5"; 58 | 59 | private File wrapperDir; 60 | private File wrapperSupportDir; 61 | 62 | private MavenWrapperMojo lookupMavenWrapperMojo() throws Exception { 63 | File pluginXml = new File(getBasedir(), PLUGIN_TEST_FILE_LOCATION); 64 | PlexusConfiguration pluginConfiguration = extractPluginConfiguration(MAVEN_WRAPPER_PLUGIN_NAME, pluginXml); 65 | MavenWrapperMojo mojoInstance = MavenWrapperMojo.class.newInstance(); 66 | MavenWrapperMojo mojo = (MavenWrapperMojo) configureMojo(mojoInstance, pluginConfiguration); 67 | 68 | return mojo; 69 | } 70 | 71 | private Properties readProperties() throws IOException { 72 | InputStream in = null; 73 | 74 | try { 75 | in = new FileInputStream(new File(wrapperSupportDir, MavenWrapperMojo.WRAPPER_PROPERTIES_FILE_NAME)); 76 | Properties props = new Properties(); 77 | props.load(in); 78 | 79 | return props; 80 | } finally { 81 | if (in != null) { 82 | IOUtils.closeQuietly(in); 83 | } 84 | } 85 | } 86 | 87 | private String readDistributionUrlFromWrapperProperties(final Properties properties) throws IOException { 88 | return properties.getProperty(MavenWrapperMojo.DISTRIBUTION_URL_PROPERTY); 89 | } 90 | 91 | private Boolean readVerifyDownloadFromWrapperProperties(final Properties properties) throws IOException { 92 | return Boolean.valueOf(properties.getProperty(MavenWrapperMojo.VERIFY_DOWNLOAD_PROPERTY)); 93 | } 94 | 95 | private String readChecksumAlgorithmFromWrapperProperties(final Properties properties) throws IOException { 96 | return properties.getProperty(MavenWrapperMojo.CHECKSUM_ALGORITHM_PROPERTY); 97 | } 98 | 99 | private String getExpectedDistributionUrl() { 100 | StringBuilder sb = new StringBuilder(); 101 | for (String testDistributionUrl : TEST_DISTRIBUTION_URL_LIST) { 102 | sb.append(testDistributionUrl).append('/'); 103 | sb.append(String.format(MavenWrapperMojo.DIST_FILENAME_PATH_TEMPLATE, MAVEN_RUNTIME_VERSION, MAVEN_RUNTIME_VERSION)); 104 | sb.append(","); 105 | } 106 | sb.setLength(sb.length() - 1); 107 | return sb.toString(); 108 | } 109 | 110 | protected void setUp() throws Exception { 111 | super.setUp(); 112 | wrapperDir = new File(getBasedir(), TEST_WRAPPER_DIR_LOCATION); 113 | wrapperSupportDir = new File(wrapperDir, TEST_SUPPORT_DIR_LOCATION); 114 | } 115 | 116 | public void testMojoLookup() throws Exception { 117 | MavenWrapperMojo mojo = lookupMavenWrapperMojo(); 118 | assertNotNull(mojo); 119 | } 120 | 121 | public void testMojoParameters() throws Exception { 122 | MavenWrapperMojo mojo = lookupMavenWrapperMojo(); 123 | 124 | assertNotNull(mojo.getWrapperDirectory()); 125 | assertNotNull(mojo.getBaseDistributionUrl()); 126 | assertNotNull(mojo.getBaseDistributionUrlList()); 127 | assertNotNull(mojo.getWrapperScriptDirectory()); 128 | assertNotNull(mojo.getMavenVersion()); 129 | assertNotNull(mojo.getVerifyDownload()); 130 | assertNotNull(mojo.getChecksumExtension()); 131 | assertNotNull(mojo.getChecksumAlgorithm()); 132 | 133 | assertEquals(wrapperDir.getAbsolutePath(), mojo.getWrapperScriptDirectory()); 134 | assertEquals(wrapperSupportDir.getAbsolutePath(), mojo.getWrapperDirectory()); 135 | assertEquals(MAVEN_RUNTIME_VERSION, mojo.getMavenVersion()); 136 | assertEquals(TEST_DISTRIBUTION_URL, mojo.getBaseDistributionUrl()); 137 | assertEquals(TEST_DISTRIBUTION_URL_LIST, mojo.getBaseDistributionUrlList()); 138 | assertEquals(VERIFY_DOWNLOAD, mojo.getVerifyDownload()); 139 | assertEquals(CHECKSUM_EXTENSION, mojo.getChecksumExtension()); 140 | assertEquals(CHECKSUM_ALGORITHM, mojo.getChecksumAlgorithm()); 141 | } 142 | 143 | public void testMojoExecution() throws Exception { 144 | Artifact artifact = mock(Artifact.class); 145 | when(artifact.getFile()).thenReturn(new File(getBasedir(), PLUGIN_TEST_ARTIFACT_LOCATION)); 146 | 147 | PluginDescriptor pluginDescriptor = mock(PluginDescriptor.class); 148 | when(pluginDescriptor.getPluginArtifact()).thenReturn(artifact); 149 | 150 | MavenWrapperMojo mojo = lookupMavenWrapperMojo(); 151 | 152 | mojo.setPlugin(pluginDescriptor); 153 | mojo.setMavenVersion(MAVEN_RUNTIME_VERSION); 154 | mojo.execute(); 155 | 156 | Properties properties = readProperties(); 157 | 158 | assertTrue(new File(mojo.getWrapperScriptDirectory(), MavenWrapperMojo.SCRIPT_FILENAME_UNIX).exists()); 159 | assertTrue(new File(mojo.getWrapperScriptDirectory(), MavenWrapperMojo.SCRIPT_FILENAME_WINDOWS).exists()); 160 | assertTrue(new File(mojo.getWrapperDirectory(), MavenWrapperMojo.WRAPPER_PROPERTIES_FILE_NAME).exists()); 161 | assertTrue(new File(mojo.getWrapperDirectory(), MavenWrapperMojo.WRAPPER_JAR_FILE_NAME).exists()); 162 | assertEquals(getExpectedDistributionUrl(), readDistributionUrlFromWrapperProperties(properties)); 163 | assertEquals(VERIFY_DOWNLOAD, readVerifyDownloadFromWrapperProperties(properties)); 164 | assertEquals(CHECKSUM_ALGORITHM, readChecksumAlgorithmFromWrapperProperties(properties)); 165 | 166 | verify(artifact, times(1)).getFile(); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/wrapper/PathAssemblerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2008 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.apache.maven.wrapper; 17 | 18 | import static org.hamcrest.Matchers.equalTo; 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertThat; 21 | import static org.junit.Assert.fail; 22 | 23 | import java.io.File; 24 | import java.net.URI; 25 | import java.util.Collections; 26 | import java.util.regex.Pattern; 27 | 28 | import org.hamcrest.BaseMatcher; 29 | import org.hamcrest.Description; 30 | import org.hamcrest.Matcher; 31 | import org.junit.Before; 32 | import org.junit.Test; 33 | 34 | /** 35 | * @author Hans Dockter 36 | */ 37 | public class PathAssemblerTest { 38 | private static final String TEST_MAVEN_USER_HOME = "someUserHome"; 39 | private static final URI TEST_DISTRIBUTION_URI = URI.create("http://server/dist/maven-0.9-bin.zip"); 40 | private static final URI TEST_DISTRIBUTION_NO_TYPE_URI = URI.create("http://server/dist/maven-1.0.zip"); 41 | 42 | private PathAssembler pathAssembler = new PathAssembler(new File(TEST_MAVEN_USER_HOME)); 43 | final WrapperConfiguration configuration = new WrapperConfiguration(); 44 | 45 | @Before 46 | public void setup() { 47 | configuration.setDistributionBase(PathAssembler.MAVEN_USER_HOME_STRING); 48 | configuration.setDistributionPath("somePath"); 49 | configuration.setZipBase(PathAssembler.MAVEN_USER_HOME_STRING); 50 | configuration.setZipPath("somePath"); 51 | } 52 | 53 | @Test 54 | public void distributionDirWithMavenUserHomeBase() throws Exception { 55 | configuration.setDistributionUris(Collections.singletonList(TEST_DISTRIBUTION_URI)); 56 | 57 | File distributionDir = pathAssembler.getDistribution(configuration, TEST_DISTRIBUTION_URI).getDistributionDir(); 58 | assertThat(distributionDir.getName(), matchesRegexp("[a-z0-9]+")); 59 | assertThat(distributionDir.getParentFile(), equalTo(file(TEST_MAVEN_USER_HOME + "/somePath/maven-0.9-bin"))); 60 | } 61 | 62 | @Test 63 | public void distributionDirWithProjectBase() throws Exception { 64 | configuration.setDistributionBase(PathAssembler.PROJECT_STRING); 65 | configuration.setDistributionUris(Collections.singletonList(TEST_DISTRIBUTION_URI)); 66 | 67 | File distributionDir = pathAssembler.getDistribution(configuration, TEST_DISTRIBUTION_URI).getDistributionDir(); 68 | assertThat(distributionDir.getName(), matchesRegexp("[a-z0-9]+")); 69 | assertThat(distributionDir.getParentFile(), equalTo(file(currentDirPath() + "/somePath/maven-0.9-bin"))); 70 | } 71 | 72 | @Test 73 | public void distributionDirWithUnknownBase() throws Exception { 74 | configuration.setDistributionUris(Collections.singletonList(TEST_DISTRIBUTION_NO_TYPE_URI)); 75 | configuration.setDistributionBase("unknownBase"); 76 | 77 | try { 78 | pathAssembler.getDistribution(configuration, TEST_DISTRIBUTION_NO_TYPE_URI); 79 | fail(); 80 | } catch (RuntimeException e) { 81 | assertEquals("Base: unknownBase is unknown", e.getMessage()); 82 | } 83 | } 84 | 85 | @Test 86 | public void distZipWithMavenUserHomeBase() throws Exception { 87 | configuration.setDistributionUris(Collections.singletonList(TEST_DISTRIBUTION_NO_TYPE_URI)); 88 | 89 | File dist = pathAssembler.getDistribution(configuration, TEST_DISTRIBUTION_NO_TYPE_URI).getZipFile(); 90 | assertThat(dist.getName(), equalTo("maven-1.0.zip")); 91 | assertThat(dist.getParentFile().getName(), matchesRegexp("[a-z0-9]+")); 92 | assertThat(dist.getParentFile().getParentFile(), equalTo(file(TEST_MAVEN_USER_HOME + "/somePath/maven-1.0"))); 93 | } 94 | 95 | @Test 96 | public void distZipWithProjectBase() throws Exception { 97 | configuration.setZipBase(PathAssembler.PROJECT_STRING); 98 | configuration.setDistributionUris(Collections.singletonList(TEST_DISTRIBUTION_NO_TYPE_URI)); 99 | 100 | File dist = pathAssembler.getDistribution(configuration, TEST_DISTRIBUTION_NO_TYPE_URI).getZipFile(); 101 | assertThat(dist.getName(), equalTo("maven-1.0.zip")); 102 | assertThat(dist.getParentFile().getName(), matchesRegexp("[a-z0-9]+")); 103 | assertThat(dist.getParentFile().getParentFile(), equalTo(file(currentDirPath() + "/somePath/maven-1.0"))); 104 | } 105 | 106 | private File file(String path) { 107 | return new File(path); 108 | } 109 | 110 | private String currentDirPath() { 111 | return System.getProperty("user.dir"); 112 | } 113 | 114 | public static Matcher matchesRegexp(final String pattern) { 115 | return new BaseMatcher() { 116 | public boolean matches(Object o) { 117 | return Pattern.compile(pattern).matcher((CharSequence) o).matches(); 118 | } 119 | 120 | public void describeTo(Description description) { 121 | description.appendText("a CharSequence that matches regexp ").appendValue(pattern); 122 | } 123 | }; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/wrapper/SystemPropertiesHandlerTest.java: -------------------------------------------------------------------------------- 1 | package org.apache.maven.wrapper; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.equalTo; 5 | 6 | import java.io.File; 7 | import java.io.FileOutputStream; 8 | import java.io.IOException; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | import java.util.Properties; 12 | 13 | import org.apache.commons.io.IOUtils; 14 | import org.apache.commons.io.FileUtils; 15 | import org.junit.After; 16 | import org.junit.Before; 17 | import org.junit.Test; 18 | 19 | public class SystemPropertiesHandlerTest { 20 | private File tmpDir = new File("target/test-files/SystemPropertiesHandlerTest"); 21 | 22 | @Before 23 | public void setupTempDir() { 24 | tmpDir.mkdirs(); 25 | } 26 | 27 | @After 28 | public void deleteTempDir() { 29 | if (tmpDir.exists()) { 30 | try { 31 | FileUtils.deleteDirectory(tmpDir); 32 | } catch (IOException ioe) { 33 | throw new RuntimeException("Could not cleanup temp directory." + tmpDir.getAbsolutePath()); 34 | } 35 | } 36 | } 37 | 38 | @Test 39 | public void testParsePropertiesFile() throws Exception { 40 | File propFile = new File(tmpDir, "props"); 41 | Properties props = new Properties(); 42 | props.put("a", "b"); 43 | props.put("c", "d"); 44 | props.put("e", "f"); 45 | 46 | FileOutputStream fos = null; 47 | 48 | try { 49 | fos = new FileOutputStream(propFile); 50 | props.store(fos, ""); 51 | } finally { 52 | IOUtils.closeQuietly(fos); 53 | } 54 | 55 | Map expected = new HashMap(3); 56 | expected.put("a", "b"); 57 | expected.put("c", "d"); 58 | expected.put("e", "f"); 59 | 60 | assertThat(SystemPropertiesHandler.getSystemProperties(propFile), equalTo(expected)); 61 | } 62 | 63 | @Test 64 | public void ifNoPropertyFileExistShouldReturnEmptyMap() { 65 | Map expected = new HashMap(); 66 | assertThat(SystemPropertiesHandler.getSystemProperties(new File(tmpDir, "unknown")), equalTo(expected)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/org/apache/maven/wrapper/WrapperExecutorTest.java: -------------------------------------------------------------------------------- 1 | package org.apache.maven.wrapper; 2 | 3 | import static org.mockito.Mockito.mock; 4 | import static org.mockito.Mockito.verify; 5 | import static org.mockito.Mockito.when; 6 | 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | import java.io.OutputStream; 10 | import java.net.URI; 11 | import java.util.Properties; 12 | 13 | import org.apache.commons.io.IOUtils; 14 | import org.hamcrest.Matchers; 15 | import org.junit.Assert; 16 | import org.junit.Test; 17 | import org.mockito.Mockito; 18 | 19 | public class WrapperExecutorTest { 20 | private final Installer install; 21 | private final BootstrapMainStarter start; 22 | private File propertiesFile; 23 | private Properties properties = new Properties(); 24 | private File testDir = new File("target/test-files/SystemPropertiesHandlerTest-" + System.currentTimeMillis()); 25 | private File mockInstallDir = new File(testDir, "mock-dir"); 26 | 27 | public WrapperExecutorTest() throws Exception { 28 | install = mock(Installer.class); 29 | when(install.createDist(Mockito.any(WrapperConfiguration.class))).thenReturn(mockInstallDir); 30 | start = mock(BootstrapMainStarter.class); 31 | 32 | testDir.mkdirs(); 33 | propertiesFile = new File(testDir, "maven/wrapper/maven-wrapper.properties"); 34 | 35 | properties.put("distributionUrl", "http://server/test/maven.zip"); 36 | properties.put("distributionBase", "testDistBase"); 37 | properties.put("distributionPath", "testDistPath"); 38 | properties.put("zipStoreBase", "testZipBase"); 39 | properties.put("zipStorePath", "testZipPath"); 40 | properties.put("verifyDownload", Boolean.TRUE.toString()); 41 | properties.put("checksumAlgorithm", Checksum.MD5.toString()); 42 | properties.put("checksumUrl", "http://server/test/maven.zip.md5"); 43 | 44 | writePropertiesFile(properties, propertiesFile, "header"); 45 | } 46 | 47 | @Test 48 | public void loadWrapperMetadataFromFile() throws Exception { 49 | WrapperExecutor wrapper = WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 50 | 51 | Assert.assertEquals(1, wrapper.getDistributionUris().size()); 52 | Assert.assertEquals(new URI("http://server/test/maven.zip"), wrapper.getDistributionUris().get(0)); 53 | Assert.assertEquals(1, wrapper.getConfiguration().getDistributionUris().size()); 54 | Assert.assertEquals(new URI("http://server/test/maven.zip"), wrapper.getConfiguration().getDistributionUris().get(0)); 55 | Assert.assertEquals("testDistBase", wrapper.getConfiguration().getDistributionBase()); 56 | Assert.assertEquals("testDistPath", wrapper.getConfiguration().getDistributionPath()); 57 | Assert.assertEquals("testZipBase", wrapper.getConfiguration().getZipBase()); 58 | Assert.assertEquals("testZipPath", wrapper.getConfiguration().getZipPath()); 59 | Assert.assertTrue(wrapper.getConfiguration().isVerifyDownload()); 60 | Assert.assertEquals(Checksum.MD5, wrapper.getConfiguration().getChecksumAlgorithm()); 61 | } 62 | 63 | @Test 64 | public void loadWrapperMetadataFromDirectory() throws Exception { 65 | WrapperExecutor wrapper = WrapperExecutor.forProjectDirectory(testDir); 66 | 67 | Assert.assertEquals(1, wrapper.getDistributionUris().size()); 68 | Assert.assertEquals(new URI("http://server/test/maven.zip"), wrapper.getDistributionUris().get(0)); 69 | Assert.assertEquals(1, wrapper.getConfiguration().getDistributionUris().size()); 70 | Assert.assertEquals(new URI("http://server/test/maven.zip"), wrapper.getConfiguration().getDistributionUris().get(0)); 71 | Assert.assertEquals("testDistBase", wrapper.getConfiguration().getDistributionBase()); 72 | Assert.assertEquals("testDistPath", wrapper.getConfiguration().getDistributionPath()); 73 | Assert.assertEquals("testZipBase", wrapper.getConfiguration().getZipBase()); 74 | Assert.assertEquals("testZipPath", wrapper.getConfiguration().getZipPath()); 75 | Assert.assertTrue(wrapper.getConfiguration().isVerifyDownload()); 76 | Assert.assertEquals(Checksum.MD5, wrapper.getConfiguration().getChecksumAlgorithm()); 77 | } 78 | 79 | @Test 80 | public void useDefaultMetadataNoPropertiesFile() throws Exception { 81 | WrapperExecutor wrapper = WrapperExecutor.forProjectDirectory(new File(testDir, "unknown")); 82 | 83 | Assert.assertNull(wrapper.getDistributionUris()); 84 | Assert.assertNull(wrapper.getConfiguration().getDistributionUris()); 85 | Assert.assertEquals(PathAssembler.MAVEN_USER_HOME_STRING, wrapper.getConfiguration().getDistributionBase()); 86 | Assert.assertEquals(Installer.DEFAULT_DISTRIBUTION_PATH, wrapper.getConfiguration().getDistributionPath()); 87 | Assert.assertEquals(PathAssembler.MAVEN_USER_HOME_STRING, wrapper.getConfiguration().getZipBase()); 88 | Assert.assertEquals(Installer.DEFAULT_DISTRIBUTION_PATH, wrapper.getConfiguration().getZipPath()); 89 | Assert.assertFalse(wrapper.getConfiguration().isVerifyDownload()); 90 | Assert.assertNull(wrapper.getConfiguration().getChecksumAlgorithm()); 91 | } 92 | 93 | @Test 94 | public void propertiesFileOnlyContainsDistURL() throws Exception { 95 | 96 | properties = new Properties(); 97 | properties.put("distributionUrl", "http://server/test/maven.zip"); 98 | writePropertiesFile(properties, propertiesFile, "header"); 99 | 100 | WrapperExecutor wrapper = WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 101 | 102 | Assert.assertEquals(1, wrapper.getDistributionUris().size()); 103 | Assert.assertEquals(new URI("http://server/test/maven.zip"), wrapper.getDistributionUris().get(0)); 104 | Assert.assertEquals(1, wrapper.getConfiguration().getDistributionUris().size()); 105 | Assert.assertEquals(new URI("http://server/test/maven.zip"), wrapper.getConfiguration().getDistributionUris().get(0)); 106 | Assert.assertEquals(PathAssembler.MAVEN_USER_HOME_STRING, wrapper.getConfiguration().getDistributionBase()); 107 | Assert.assertEquals(Installer.DEFAULT_DISTRIBUTION_PATH, wrapper.getConfiguration().getDistributionPath()); 108 | Assert.assertEquals(PathAssembler.MAVEN_USER_HOME_STRING, wrapper.getConfiguration().getZipBase()); 109 | Assert.assertEquals(Installer.DEFAULT_DISTRIBUTION_PATH, wrapper.getConfiguration().getZipPath()); 110 | Assert.assertFalse(wrapper.getConfiguration().isVerifyDownload()); 111 | Assert.assertNull(wrapper.getConfiguration().getChecksumAlgorithm()); 112 | } 113 | 114 | @Test 115 | public void executeInstallAndLaunch() throws Exception { 116 | WrapperExecutor wrapper = WrapperExecutor.forProjectDirectory(propertiesFile); 117 | 118 | wrapper.execute(new String[] { "arg" }, install, start); 119 | verify(install).createDist(Mockito.any(WrapperConfiguration.class)); 120 | verify(start).start(new String[] { "arg" }, mockInstallDir); 121 | } 122 | 123 | @Test 124 | public void failWhenDistNotSetInProperties() throws Exception { 125 | properties = new Properties(); 126 | writePropertiesFile(properties, propertiesFile, "header"); 127 | 128 | try { 129 | WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 130 | Assert.fail("Expected RuntimeException"); 131 | } catch (RuntimeException e) { 132 | Assert.assertEquals("Could not load wrapper properties from '" + propertiesFile + "'.", e.getMessage()); 133 | Assert.assertEquals("No value with key 'distributionUrl' specified in wrapper properties file '" + propertiesFile + "'.", 134 | e.getCause().getMessage()); 135 | } 136 | } 137 | 138 | @Test 139 | public void failWhenPropertiesFileDoesNotExist() { 140 | propertiesFile = new File(testDir, "unknown.properties"); 141 | 142 | try { 143 | WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 144 | Assert.fail("Expected RuntimeException"); 145 | } catch (RuntimeException e) { 146 | Assert.assertEquals("Wrapper properties file '" + propertiesFile + "' does not exist.", e.getMessage()); 147 | } 148 | } 149 | 150 | @Test 151 | public void failWhenVerifyDownloadWithoutAlgorithm() throws Exception { 152 | properties = new Properties(); 153 | properties.put("distributionUrl", "http://server/test/maven.zip"); 154 | properties.put("verifyDownload", Boolean.TRUE.toString()); 155 | properties.put("checksumUrl", "http://server/test/maven.md5"); 156 | writePropertiesFile(properties, propertiesFile, "header"); 157 | 158 | try { 159 | WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 160 | Assert.fail("Expected RuntimeException"); 161 | } catch (RuntimeException e) { 162 | Assert.assertEquals("Could not load wrapper properties from '" + propertiesFile + "'.", e.getMessage()); 163 | Assert.assertEquals("No value with key 'checksumAlgorithm' specified in wrapper properties file '" + propertiesFile + "'.", 164 | e.getCause().getMessage()); 165 | } 166 | } 167 | 168 | @Test 169 | public void failWhenVerifyDownloadWithInvalidAlgorithm() throws Exception { 170 | properties = new Properties(); 171 | properties.put("distributionUrl", "http://server/test/maven.zip"); 172 | properties.put("verifyDownload", Boolean.TRUE.toString()); 173 | properties.put("checksumAlgorithm", "FOO_BAR"); 174 | properties.put("checksumExtension", "md5"); 175 | writePropertiesFile(properties, propertiesFile, "header"); 176 | 177 | try { 178 | WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 179 | Assert.fail("Expected RuntimeException"); 180 | } catch (RuntimeException e) { 181 | Assert.assertEquals("Could not load wrapper properties from '" + propertiesFile + "'.", e.getMessage()); 182 | Assert.assertTrue(e.getCause().getMessage().toLowerCase().indexOf("no enum") != -1); 183 | } 184 | } 185 | 186 | @Test 187 | public void testRelativeDistUrl() throws Exception { 188 | properties = new Properties(); 189 | properties.put("distributionUrl", "some/relative/url/to/bin.zip"); 190 | writePropertiesFile(properties, propertiesFile, "header"); 191 | 192 | WrapperExecutor wrapper = WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 193 | Assert.assertEquals(1, wrapper.getDistributionUris().size()); 194 | Assert.assertNotEquals("some/relative/url/to/bin.zip", wrapper.getDistributionUris().get(0).getSchemeSpecificPart()); 195 | Assert.assertTrue(wrapper.getDistributionUris().get(0).getSchemeSpecificPart().endsWith("some/relative/url/to/bin.zip")); 196 | } 197 | 198 | @Test 199 | public void testRelativeChecksumUrl() throws Exception { 200 | properties = new Properties(); 201 | properties.put("distributionUrl", "http://server/test/maven.zip"); 202 | properties.put("verifyDownload", Boolean.TRUE.toString()); 203 | properties.put("checksumUrl", "some/relative/url/to/bin.md5"); 204 | properties.put("checksumAlgorithm", Checksum.MD5.toString()); 205 | writePropertiesFile(properties, propertiesFile, "header"); 206 | 207 | WrapperExecutor wrapper = WrapperExecutor.forWrapperPropertiesFile(propertiesFile); 208 | 209 | Assert.assertNotNull(wrapper); 210 | Assert.assertNotNull(wrapper.getConfiguration()); 211 | Assert.assertThat(wrapper.getConfiguration().getChecksumAlgorithm(), Matchers.is(Checksum.MD5)); 212 | Assert.assertTrue(wrapper.getConfiguration().isVerifyDownload()); 213 | 214 | // Assert.assertEquals(1, wrapper.getConfiguration().getChecksum().size()); 215 | // Assert.assertNotEquals("some/relative/url/to/bin.md5", wrapper.getConfiguration().getChecksum().get(0).getSchemeSpecificPart()); 216 | // Assert.assertTrue(wrapper.getConfiguration().getChecksum().get(0).getSchemeSpecificPart().endsWith("some/relative/url/to/bin.md5")); 217 | } 218 | 219 | private void writePropertiesFile(Properties properties, File propertiesFile, String message) throws Exception { 220 | propertiesFile.getParentFile().mkdirs(); 221 | 222 | OutputStream outStream = null; 223 | 224 | try { 225 | outStream = new FileOutputStream(propertiesFile); 226 | properties.store(outStream, message); 227 | } finally { 228 | IOUtils.closeQuietly(outStream); 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/test/resources/org/apache/maven/wrapper/dummy-wrapper-artifact.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/org/apache/maven/wrapper/plugin-config.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | com.rimerosolutions.maven.plugins 12 | wrapper-maven-plugin 13 | 0.0.1-SNAPSHOT 14 | 15 | 16 | http://mirrors.ibiblio.org/maven2/org/apache/maven/apache-maven 17 | 18 | 19 | http://mirrors.ibiblio.org/maven2/org/apache/maven/apache-maven 20 | https://repo1.maven.org/maven2/org/apache/maven/apache-maven 21 | 22 | 23 | ${basedir}/target/test-wrapper 24 | 25 | ${basedir}/target/test-wrapper/support 26 | 27 | 0.0.1 28 | 29 | true 30 | 31 | md5 32 | 33 | MD5 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/test/resources/org/apache/maven/wrapper/wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=http://server/test/maven.zip 2 | distributionBase=testDistBase 3 | zipStoreBase=testZipBase 4 | distributionPath=testDistPath 5 | zipStorePath=testZipPath 6 | --------------------------------------------------------------------------------