diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2003740 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: +- package-ecosystem: maven + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d302ca..91218e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,10 +2,13 @@ name: Verify on: push: + branches: + - master pull_request: jobs: build: name: Verify - uses: takari/takari-gh-actions/.github/workflows/ci.yml@v1 - + uses: takari/takari-gh-actions/.github/workflows/ci.yml@v3 + with: + jdk-matrix: '[ 11,17,21 ]' diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index bf82ff0..0000000 Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index dc3affc..346d645 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -6,7 +6,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an @@ -14,5 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..79e486c --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,70 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: +i) changes to the Program, and +ii) additions to the Program; +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and +b) its license agreement: +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and +b) a copy of this Agreement must be included with each copy of the Program. +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. diff --git a/mvnw b/mvnw index b7f0646..633bbb7 100755 --- a/mvnw +++ b/mvnw @@ -19,269 +19,221 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.1.1 -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir +# Apache Maven Wrapper startup batch script, version 3.2.0 # # Optional ENV vars # ----------------- -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output # ---------------------------------------------------------------------------- -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /usr/local/etc/mavenrc ] ; then - . /usr/local/etc/mavenrc - fi - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME - else - JAVA_HOME="/Library/Java/Home"; export JAVA_HOME - fi - fi - ;; +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +(CYGWIN*|MINGW*) [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } ;; esac -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" else JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ] ; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi fi else - JAVACMD="`\\unset -f command; \\command -v java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi + JAVACMD="$('set' +e; 'unset' -f command 2>/dev/null; 'command' -v java)" || : + JAVACCMD="$('set' +e; 'unset' -f command 2>/dev/null; 'command' -v javac)" || : -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ] ; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi fi +} - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + h=$(( ( h * 31 + $(LC_CTYPE=C printf %d "'$str") ) % 4294967296 )) + str="${str#?}" done - printf '%s' "$(cd "$basedir"; pwd)" + printf %x\\n $h } -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 } -BASE_DIR=$(find_maven_basedir "$(dirname $0)") -if [ -z "$BASE_DIR" ]; then - exit 1; -fi +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl="${value-}" ;; + distributionSha256Sum) distributionSha256Sum="${value-}" ;; + esac +done < "${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + + +case "${distributionUrl##*/}" in +(maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + (*AMD64:CYGWIN*|*AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + (:Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + (:Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + (:Linux*x86_64*) distributionPlatform=linux-amd64 ;; + (*) echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +(maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +(*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac -MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_HOME="$HOME/.m2/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" fi -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi +case "${distributionUrl-}" in +(*?-bin.zip|*?maven-mvnd-?*-?*.zip) ;; +(*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" - else - wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $wrapperUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi + die "cannot create temp dir" +fi - if command -v wget > /dev/null; then - QUIET="--quiet" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - QUIET="" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" - else - wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" - fi - [ $? -eq 0 ] || rm -f "$wrapperJarPath" - elif command -v curl > /dev/null; then - QUIET="--silent" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - QUIET="" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L - else - curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L - fi - [ $? -eq 0 ] || rm -f "$wrapperJarPath" - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaSource=`cygpath --path --windows "$javaSource"` - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaSource" ]; then - if [ ! -e "$javaClass" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaSource") - fi - if [ -e "$javaClass" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" fi -########################################################################################## -# End of extension -########################################################################################## -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +if [ -z "${MVNW_USERNAME-}" ] && command -v wget > /dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl > /dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat > "$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( new java.net.URL( args[0] ).openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" fi -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum > /dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c > /dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c > /dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +# unzip and move +if command -v unzip > /dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" +fi +printf %s\\n "$distributionUrl" > "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" -exec "$JAVACMD" \ - $MAVEN_OPTS \ - $MAVEN_DEBUG_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 019bd74..dd02e16 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,143 +1,145 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml index 7a48586..c8f6f02 100644 --- a/pom.xml +++ b/pom.xml @@ -1,21 +1,20 @@ - 4.0.0 io.takari takari - 50 + 53 io.takari.maven.plugins @@ -23,6 +22,12 @@ 3.0.2-SNAPSHOT pom + + takari-plugin-testing + takari-plugin-integration-testing + takari-plugin-testing-its + + 3.6.3 0.3.5 @@ -31,12 +36,6 @@ 1.7.36 - - takari-plugin-testing - takari-plugin-integration-testing - takari-plugin-testing-its - - @@ -111,8 +110,8 @@ org.sonatype.sisu sisu-guice - no_aop ${sisuGuiceVersion} + no_aop diff --git a/takari-plugin-integration-testing/pom.xml b/takari-plugin-integration-testing/pom.xml index 015b07e..c934ff8 100644 --- a/takari-plugin-integration-testing/pom.xml +++ b/takari-plugin-integration-testing/pom.xml @@ -1,14 +1,13 @@ - 4.0.0 @@ -49,4 +48,4 @@ - \ No newline at end of file + diff --git a/takari-plugin-testing-its/pom.xml b/takari-plugin-testing-its/pom.xml index 8325bf1..9ac2be2 100644 --- a/takari-plugin-testing-its/pom.xml +++ b/takari-plugin-testing-its/pom.xml @@ -1,14 +1,13 @@ - 4.0.0 @@ -58,12 +57,41 @@ io.takari.maven.plugins takari-plugin-integration-testing - pom ${project.version} + pom + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-dependency-plugin + [2.8,) + + unpack + + + + + + + + + + + + io.takari.maven.plugins @@ -71,10 +99,10 @@ testProperties - process-test-resources testProperties + process-test-resources @@ -85,10 +113,10 @@ unpack - generate-test-resources unpack + generate-test-resources ${project.build.directory} @@ -105,34 +133,5 @@ - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.apache.maven.plugins - maven-dependency-plugin - [2.8,) - - unpack - - - - - - - - - - - - diff --git a/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/IntegrationTest.java b/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/IntegrationTest.java index 660efeb..8108004 100644 --- a/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/IntegrationTest.java +++ b/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/IntegrationTest.java @@ -1,5 +1,7 @@ package io.takari.maven.testing.test; +import io.takari.maven.testing.TestResources; +import io.takari.maven.testing.executor.MavenRuntime; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -7,7 +9,6 @@ import java.io.Writer; import java.util.ArrayList; import java.util.List; - import org.junit.Assume; import org.junit.Rule; import org.junit.Test; @@ -15,9 +16,6 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; -import io.takari.maven.testing.TestResources; -import io.takari.maven.testing.executor.MavenRuntime; - /** *
    *
  • The test project is built with maven 3.6.3.
  • @@ -30,70 +28,71 @@ @RunWith(Parameterized.class) public class IntegrationTest { - @Parameters(name = "{0}") - public static List versions() { - List parameters = new ArrayList<>(); - parameters.add(new Object[] {"3.6.3"}); - return parameters; - } + @Parameters(name = "{0}") + public static List versions() { + List parameters = new ArrayList<>(); + parameters.add(new Object[] {"3.6.3"}); + return parameters; + } - @Rule - public final TestResources resources = new TestResources(); + @Rule + public final TestResources resources = new TestResources(); - public final MavenRuntime maven; + public final MavenRuntime maven; - private final String version; + private final String version; - public IntegrationTest(String version) throws Exception { - this.version = version; - File mavenHome = new File("target/apache-maven-3.6.3"); - this.maven = MavenRuntime.builder(mavenHome, null).forkedBuilder().build(); - } + public IntegrationTest(String version) throws Exception { + this.version = version; + File mavenHome = new File("target/apache-maven-3.6.3"); + this.maven = MavenRuntime.builder(mavenHome, null).forkedBuilder().build(); + } - @Test - public void testBasic() throws Exception { - File basedir = resources.getBasedir("basic"); - write(new File(basedir, "src/test/java/basic/TargetVersion.java"), - "package basic; class TargetVersion { static final String VERSION = \"" + version + "\"; }"); - maven.forProject(basedir) // - .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // - .execute("package") // - .assertErrorFreeLog(); - } + @Test + public void testBasic() throws Exception { + File basedir = resources.getBasedir("basic"); + write( + new File(basedir, "src/test/java/basic/TargetVersion.java"), + "package basic; class TargetVersion { static final String VERSION = \"" + version + "\"; }"); + maven.forProject(basedir) // + .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // + .execute("package") // + .assertErrorFreeLog(); + } - private void write(File file, String string) throws IOException { - try (Writer w = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) { - w.write(string); + private void write(File file, String string) throws IOException { + try (Writer w = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) { + w.write(string); + } } - } - @Test - public void testGuiceScopes() throws Exception { - // scopes were introduced in 3.2.1 https://issues.apache.org/jira/browse/MNG-5530 - Assume.assumeFalse(version.startsWith("3.0") || version.startsWith("3.1")); + @Test + public void testGuiceScopes() throws Exception { + // scopes were introduced in 3.2.1 https://issues.apache.org/jira/browse/MNG-5530 + Assume.assumeFalse(version.startsWith("3.0") || version.startsWith("3.1")); - File basedir = resources.getBasedir("guicescopes"); - maven.forProject(basedir) // - .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // - .execute("package") // - .assertErrorFreeLog(); - } + File basedir = resources.getBasedir("guicescopes"); + maven.forProject(basedir) // + .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // + .execute("package") // + .assertErrorFreeLog(); + } - @Test - public void testPomConfig() throws Exception { - File basedir = resources.getBasedir("pomconfig"); - maven.forProject(basedir) // - .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // - .execute("package") // - .assertErrorFreeLog(); - } + @Test + public void testPomConfig() throws Exception { + File basedir = resources.getBasedir("pomconfig"); + maven.forProject(basedir) // + .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // + .execute("package") // + .assertErrorFreeLog(); + } - @Test - public void testUnitTestHarnessHonoursUserSettings() throws Exception { - File basedir = resources.getBasedir("settings"); - maven.forProject(basedir) // - .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // - .execute("test") // - .assertErrorFreeLog(); - } + @Test + public void testUnitTestHarnessHonoursUserSettings() throws Exception { + File basedir = resources.getBasedir("settings"); + maven.forProject(basedir) // + .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // + .execute("test") // + .assertErrorFreeLog(); + } } diff --git a/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/JUnit5IntegrationTests.java b/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/JUnit5IntegrationTests.java index 90d68da..e4c3ae4 100644 --- a/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/JUnit5IntegrationTests.java +++ b/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/JUnit5IntegrationTests.java @@ -2,77 +2,78 @@ import static java.nio.charset.StandardCharsets.UTF_8; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; - -import org.junit.jupiter.api.Assumptions; -import org.junit.jupiter.api.extension.RegisterExtension; - import io.takari.maven.testing.TestResources5; import io.takari.maven.testing.executor.MavenInstallations; import io.takari.maven.testing.executor.MavenRuntime; import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; import io.takari.maven.testing.executor.MavenVersions; import io.takari.maven.testing.executor.junit.MavenPluginTest; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.extension.RegisterExtension; @MavenVersions("3.8.4") @MavenInstallations("target/apache-maven-3.6.3") public class JUnit5IntegrationTests { - @RegisterExtension - final TestResources5 resources = new TestResources5(); - - private final MavenRuntime maven; - - private final String version; - - JUnit5IntegrationTests(MavenRuntimeBuilder builder) throws Exception { - this.maven = builder - .withCliOptions("-B", "-e") - .build(); - this.version = this.maven.getMavenVersion(); - } - - @MavenPluginTest - void testBasic() throws Exception { - File basedir = this.resources.getBasedir("basic"); - this.write(new File(basedir, "src/test/java/basic/TargetVersion.java"), - "package basic; class TargetVersion { static final String VERSION = \"" + this.version + "\"; }"); - - this.maven.forProject(basedir) // - .execute("package") // - .assertErrorFreeLog(); - } - - private void write(File file, String string) throws IOException { - Files.write(file.toPath(), string.getBytes(UTF_8)); - } - - @MavenPluginTest - void testGuiceScopes() throws Exception { - // scopes were introduced in 3.2.1 https://issues.apache.org/jira/browse/MNG-5530 - Assumptions.assumeFalse(this.version.startsWith("3.0") || this.version.startsWith("3.1")); - - File basedir = this.resources.getBasedir("guicescopes"); - this.maven.forProject(basedir) // - .execute("package") // - .assertErrorFreeLog(); - } - - @MavenPluginTest - void testPomConfig() throws Exception { - File basedir = this.resources.getBasedir("pomconfig"); - this.maven.forProject(basedir) // - .execute("package") // - .assertErrorFreeLog(); - } - - @MavenPluginTest - void testUnitTestHarnessHonoursUserSettings() throws Exception { - File basedir = this.resources.getBasedir("settings"); - this.maven.forProject(basedir) // - .execute("test") // - .assertErrorFreeLog(); - } + @RegisterExtension + final TestResources5 resources = new TestResources5(); + + private final MavenRuntime maven; + + private final String version; + + JUnit5IntegrationTests(MavenRuntimeBuilder builder) throws Exception { + this.maven = builder.withCliOptions("-B", "-e").build(); + this.version = this.maven.getMavenVersion(); + } + + @MavenPluginTest + void testBasic() throws Exception { + File basedir = this.resources.getBasedir("basic"); + this.write( + new File(basedir, "src/test/java/basic/TargetVersion.java"), + "package basic; class TargetVersion { static final String VERSION = \"" + this.version + "\"; }"); + + this.maven + .forProject(basedir) // + .execute("package") // + .assertErrorFreeLog(); + } + + private void write(File file, String string) throws IOException { + Files.write(file.toPath(), string.getBytes(UTF_8)); + } + + @MavenPluginTest + void testGuiceScopes() throws Exception { + // scopes were introduced in 3.2.1 https://issues.apache.org/jira/browse/MNG-5530 + Assumptions.assumeFalse(this.version.startsWith("3.0") || this.version.startsWith("3.1")); + + File basedir = this.resources.getBasedir("guicescopes"); + this.maven + .forProject(basedir) // + .execute("package") // + .assertErrorFreeLog(); + } + + @MavenPluginTest + void testPomConfig() throws Exception { + File basedir = this.resources.getBasedir("pomconfig"); + this.maven + .forProject(basedir) // + .execute("package") // + .assertErrorFreeLog(); + } + + @MavenPluginTest + void testUnitTestHarnessHonoursUserSettings() throws Exception { + File basedir = this.resources.getBasedir("settings"); + this.maven + .forProject(basedir) // + .execute("test") // + .assertErrorFreeLog(); + } } diff --git a/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/JUnit5UnitTests.java b/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/JUnit5UnitTests.java index eeca103..ea814f8 100644 --- a/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/JUnit5UnitTests.java +++ b/takari-plugin-testing-its/src/test/java/io/takari/maven/testing/test/JUnit5UnitTests.java @@ -3,6 +3,8 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assumptions.assumeFalse; +import io.takari.maven.testing.TestResources5; +import io.takari.maven.testing.executor.MavenRuntime; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -10,7 +12,6 @@ import java.util.Collections; import java.util.List; import java.util.stream.Stream; - import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; @@ -18,9 +19,6 @@ import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; -import io.takari.maven.testing.TestResources5; -import io.takari.maven.testing.executor.MavenRuntime; - /** *
      *
    • The test project is built with maven 3.6.3.
    • @@ -32,75 +30,76 @@ */ class JUnit5UnitTests { - @RegisterExtension - final TestResources5 resources = new TestResources5(); - - @ParameterizedTest - @ArgumentsSource(MavenVersionsSource.class) - void testBasic(MavenRuntime maven, String version) throws Exception { - File basedir = this.resources.getBasedir("basic"); - this.write(new File(basedir, "src/test/java/basic/TargetVersion.java"), - "package basic; class TargetVersion { static final String VERSION = \"" + version + "\"; }"); - maven.forProject(basedir) // - .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // - .execute("package") // - .assertErrorFreeLog(); - } - - private void write(File file, String string) throws IOException { - Files.write(file.toPath(), string.getBytes(UTF_8)); - } - - @ParameterizedTest - @ArgumentsSource(MavenVersionsSource.class) - void testGuiceScopes(MavenRuntime maven, String version) throws Exception { - // scopes were introduced in 3.2.1 https://issues.apache.org/jira/browse/MNG-5530 - assumeFalse(version.startsWith("3.0") || version.startsWith("3.1")); - - File basedir = this.resources.getBasedir("guicescopes"); - maven.forProject(basedir) // - .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // - .execute("package") // - .assertErrorFreeLog(); - } - - @ParameterizedTest - @ArgumentsSource(MavenVersionsSource.class) - void testPomConfig(MavenRuntime maven, String version) throws Exception { - File basedir = this.resources.getBasedir("pomconfig"); - maven.forProject(basedir) // - .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // - .execute("package") // - .assertErrorFreeLog(); - } + @RegisterExtension + final TestResources5 resources = new TestResources5(); + + @ParameterizedTest + @ArgumentsSource(MavenVersionsSource.class) + void testBasic(MavenRuntime maven, String version) throws Exception { + File basedir = this.resources.getBasedir("basic"); + this.write( + new File(basedir, "src/test/java/basic/TargetVersion.java"), + "package basic; class TargetVersion { static final String VERSION = \"" + version + "\"; }"); + maven.forProject(basedir) // + .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // + .execute("package") // + .assertErrorFreeLog(); + } - @ParameterizedTest - @ArgumentsSource(MavenVersionsSource.class) - void testUnitTestHarnessHonoursUserSettings(MavenRuntime maven, String version) throws Exception { - File basedir = this.resources.getBasedir("settings"); - maven.forProject(basedir) // - .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // - .execute("test") // - .assertErrorFreeLog(); - } + private void write(File file, String string) throws IOException { + Files.write(file.toPath(), string.getBytes(UTF_8)); + } - static final class MavenVersionsSource implements ArgumentsProvider { + @ParameterizedTest + @ArgumentsSource(MavenVersionsSource.class) + void testGuiceScopes(MavenRuntime maven, String version) throws Exception { + // scopes were introduced in 3.2.1 https://issues.apache.org/jira/browse/MNG-5530 + assumeFalse(version.startsWith("3.0") || version.startsWith("3.1")); + + File basedir = this.resources.getBasedir("guicescopes"); + maven.forProject(basedir) // + .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // + .execute("package") // + .assertErrorFreeLog(); + } - private List getMavenVersions() { - return Collections.singletonList("3.6.3"); + @ParameterizedTest + @ArgumentsSource(MavenVersionsSource.class) + void testPomConfig(MavenRuntime maven, String version) throws Exception { + File basedir = this.resources.getBasedir("pomconfig"); + maven.forProject(basedir) // + .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // + .execute("package") // + .assertErrorFreeLog(); } - @Override - public Stream provideArguments( ExtensionContext context) throws Exception { - List mavenVersions = this.getMavenVersions(); - List arguments = new ArrayList<>(mavenVersions.size()); - for (String version : mavenVersions) { - File mavenHome = new File("target/apache-maven-" + version); - MavenRuntime maven = MavenRuntime.builder(mavenHome, null).forkedBuilder().build(); - arguments.add(Arguments.of(maven, version)); - } - return arguments.stream(); + @ParameterizedTest + @ArgumentsSource(MavenVersionsSource.class) + void testUnitTestHarnessHonoursUserSettings(MavenRuntime maven, String version) throws Exception { + File basedir = this.resources.getBasedir("settings"); + maven.forProject(basedir) // + .withCliOptions("-B", "-e", "-DmavenVersion=" + version) // + .execute("test") // + .assertErrorFreeLog(); } - } + static final class MavenVersionsSource implements ArgumentsProvider { + + private List getMavenVersions() { + return Collections.singletonList("3.6.3"); + } + + @Override + public Stream provideArguments(ExtensionContext context) throws Exception { + List mavenVersions = this.getMavenVersions(); + List arguments = new ArrayList<>(mavenVersions.size()); + for (String version : mavenVersions) { + File mavenHome = new File("target/apache-maven-" + version); + MavenRuntime maven = + MavenRuntime.builder(mavenHome, null).forkedBuilder().build(); + arguments.add(Arguments.of(maven, version)); + } + return arguments.stream(); + } + } } diff --git a/takari-plugin-testing-its/src/test/projects/basic/pom.xml b/takari-plugin-testing-its/src/test/projects/basic/pom.xml index 5ace948..414e288 100644 --- a/takari-plugin-testing-its/src/test/projects/basic/pom.xml +++ b/takari-plugin-testing-its/src/test/projects/basic/pom.xml @@ -18,7 +18,7 @@ takari-maven-plugin - 1.13.9 + 2.1.3 3.6.3 3.6.0 2.6.0-SNAPSHOT diff --git a/takari-plugin-testing-its/src/test/projects/classloading/pom.xml b/takari-plugin-testing-its/src/test/projects/classloading/pom.xml index 66568fb..b59d985 100644 --- a/takari-plugin-testing-its/src/test/projects/classloading/pom.xml +++ b/takari-plugin-testing-its/src/test/projects/classloading/pom.xml @@ -32,7 +32,7 @@ --> - 1.13.9 + 2.1.3 3.6.3 3.6.0 2.0.0-SNAPSHOT diff --git a/takari-plugin-testing-its/src/test/projects/guicescopes/pom.xml b/takari-plugin-testing-its/src/test/projects/guicescopes/pom.xml index b72b7e5..4a0d8f4 100644 --- a/takari-plugin-testing-its/src/test/projects/guicescopes/pom.xml +++ b/takari-plugin-testing-its/src/test/projects/guicescopes/pom.xml @@ -18,7 +18,7 @@ takari-maven-plugin - 1.13.9 + 2.1.3 3.6.3 3.6.0 2.5.0-SNAPSHOT diff --git a/takari-plugin-testing-its/src/test/projects/pomconfig/pom.xml b/takari-plugin-testing-its/src/test/projects/pomconfig/pom.xml index c8cf938..efdd8f4 100644 --- a/takari-plugin-testing-its/src/test/projects/pomconfig/pom.xml +++ b/takari-plugin-testing-its/src/test/projects/pomconfig/pom.xml @@ -18,7 +18,7 @@ takari-maven-plugin - 1.13.9 + 2.1.3 3.6.3 3.6.0 2.6.0-SNAPSHOT diff --git a/takari-plugin-testing-its/src/test/projects/settings/pom.xml b/takari-plugin-testing-its/src/test/projects/settings/pom.xml index 8a8be8c..5c5856a 100644 --- a/takari-plugin-testing-its/src/test/projects/settings/pom.xml +++ b/takari-plugin-testing-its/src/test/projects/settings/pom.xml @@ -18,7 +18,7 @@ takari-maven-plugin - 1.13.9 + 2.1.3 3.6.3 3.6.0 2.8.0-SNAPSHOT diff --git a/takari-plugin-testing-its/src/test/test.properties b/takari-plugin-testing-its/src/test/test.properties index 78350f7..7e74fb6 100644 --- a/takari-plugin-testing-its/src/test/test.properties +++ b/takari-plugin-testing-its/src/test/test.properties @@ -1 +1 @@ -repository.0=https://repo1.maven.org/maven2/ +repository.0=https://repo.maven.apache.org/maven2/ diff --git a/takari-plugin-testing/pom.xml b/takari-plugin-testing/pom.xml index fd27001..2be4bf4 100644 --- a/takari-plugin-testing/pom.xml +++ b/takari-plugin-testing/pom.xml @@ -1,14 +1,13 @@ - 4.0.0 @@ -114,4 +113,4 @@ - \ No newline at end of file + diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/AbstractTestMavenRuntime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/AbstractTestMavenRuntime.java index e3842af..9e516c9 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/AbstractTestMavenRuntime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/AbstractTestMavenRuntime.java @@ -1,12 +1,13 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing; +import com.google.inject.Module; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -18,7 +19,6 @@ import java.util.Objects; import java.util.Properties; import java.util.Set; - import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.ArtifactHandler; @@ -32,229 +32,231 @@ import org.codehaus.plexus.DefaultPlexusContainer; import org.codehaus.plexus.util.xml.Xpp3Dom; -import com.google.inject.Module; - public abstract class AbstractTestMavenRuntime { - private static final DefaultArtifactVersion MAVEN_VERSION; - - static { - DefaultArtifactVersion version = null; - String path = "/META-INF/maven/org.apache.maven/maven-core/pom.properties"; - try (InputStream is = TestMavenRuntime.class.getResourceAsStream(path)) { - Properties properties = new Properties(); - if (is != null) { - properties.load(is); - } - String property = properties.getProperty("version"); - if (property != null) { - version = new DefaultArtifactVersion(property); - } - } catch (IOException e) { - // odd, where did this come from + private static final DefaultArtifactVersion MAVEN_VERSION; + + static { + DefaultArtifactVersion version = null; + String path = "/META-INF/maven/org.apache.maven/maven-core/pom.properties"; + try (InputStream is = TestMavenRuntime.class.getResourceAsStream(path)) { + Properties properties = new Properties(); + if (is != null) { + properties.load(is); + } + String property = properties.getProperty("version"); + if (property != null) { + version = new DefaultArtifactVersion(property); + } + } catch (IOException e) { + // odd, where did this come from + } + MAVEN_VERSION = version; } - MAVEN_VERSION = version; - } - - @FunctionalInterface - private static interface RuntimeFactory { - MavenRuntime newInstance(Module[] modules) throws Exception; - } - - // ordered map of supported maven runtime factories - private static final Map FACTORIES; - - static { - Map factories = new LinkedHashMap<>(); - try { - factories.put(VersionRange.createFromVersionSpec("[3.0,3.1.1)"), Maven30xRuntime::new); - factories.put(VersionRange.createFromVersionSpec("[3.1.1,3.2.1)"), Maven311Runtime::new); - factories.put(VersionRange.createFromVersionSpec("[3.2.1,3.2.5)"), Maven321Runtime::create); - factories.put(VersionRange.createFromVersionSpec("[3.2.5]"), Maven325Runtime::new); - // the last entry is expected to handle everything else - factories.put(VersionRange.createFromVersionSpec("(3.2.5,]"), Maven331Runtime::new); - } catch (InvalidVersionSpecificationException e) { - throw new RuntimeException(e); + + @FunctionalInterface + private static interface RuntimeFactory { + MavenRuntime newInstance(Module[] modules) throws Exception; } - FACTORIES = Collections.unmodifiableMap(factories); - } - - private final Module[] modules; - private MavenRuntime runtime; - - public class TestDependency { - - private final File file; - private String groupId = "test"; - private String artifactId; - private String classifier; - private String version = "1.0"; - private String type = "jar"; - private String scope = Artifact.SCOPE_COMPILE; - private boolean optional; - - private TestDependency(File artifact) { - this.file = artifact; - this.artifactId = artifact.getName(); + + // ordered map of supported maven runtime factories + private static final Map FACTORIES; + + static { + Map factories = new LinkedHashMap<>(); + try { + factories.put(VersionRange.createFromVersionSpec("[3.0,3.1.1)"), Maven30xRuntime::new); + factories.put(VersionRange.createFromVersionSpec("[3.1.1,3.2.1)"), Maven311Runtime::new); + factories.put(VersionRange.createFromVersionSpec("[3.2.1,3.2.5)"), Maven321Runtime::create); + factories.put(VersionRange.createFromVersionSpec("[3.2.5]"), Maven325Runtime::new); + // the last entry is expected to handle everything else + factories.put(VersionRange.createFromVersionSpec("(3.2.5,]"), Maven331Runtime::new); + } catch (InvalidVersionSpecificationException e) { + throw new RuntimeException(e); + } + FACTORIES = Collections.unmodifiableMap(factories); } - public TestDependency setArtifactId(String artifactId) { - this.artifactId = artifactId; + private final Module[] modules; + private MavenRuntime runtime; + + public class TestDependency { + + private final File file; + private String groupId = "test"; + private String artifactId; + private String classifier; + private String version = "1.0"; + private String type = "jar"; + private String scope = Artifact.SCOPE_COMPILE; + private boolean optional; + + private TestDependency(File artifact) { + this.file = artifact; + this.artifactId = artifact.getName(); + } + + public TestDependency setArtifactId(String artifactId) { + this.artifactId = artifactId; + + return this; + } + + public TestDependency setGroupId(String groupId) { + this.groupId = groupId; + + return this; + } + + public TestDependency setVersion(String version) { + this.version = version; + + return this; + } + + public TestDependency setType(String type) { + this.type = type; + + return this; + } - return this; + public TestDependency setOptional(boolean optional) { + this.optional = optional; + + return this; + } + + public TestDependency setClassifier(String classifier) { + this.classifier = classifier; + + return this; + } + + public TestDependency setScope(String scope) { + this.scope = scope; + + return this; + } + + public TestDependency addTo(MavenProject project) throws Exception { + return addTo(project, true); + } + + public TestDependency addTo(MavenProject project, boolean direct) throws Exception { + ArtifactHandler handler = getContainer().lookup(ArtifactHandler.class, type); + DefaultArtifact artifact = + new DefaultArtifact(groupId, artifactId, version, scope, type, classifier, handler); + artifact.setFile(file); + artifact.setOptional(optional); + Set artifacts = project.getArtifacts(); + artifacts.add(artifact); + project.setArtifacts(artifacts); + if (direct) { + Set directDependencies = project.getDependencyArtifacts(); + directDependencies = directDependencies == null + ? new LinkedHashSet() + : new LinkedHashSet<>(directDependencies); + directDependencies.add(artifact); + project.setDependencyArtifacts(directDependencies); + } + + return this; + } } - public TestDependency setGroupId(String groupId) { - this.groupId = groupId; + AbstractTestMavenRuntime() { + this(new Module[0]); + } - return this; + AbstractTestMavenRuntime(Module... modules) { + this.modules = modules; } - public TestDependency setVersion(String version) { - this.version = version; + void createMavenRuntime() throws Exception { + runtime = newMavenRuntime(modules); + } - return this; + void shutDownMavenRuntime() { + runtime.shutdown(); + runtime = null; } - public TestDependency setType(String type) { - this.type = type; + private MavenRuntime newMavenRuntime(Module[] modules) throws Exception { + for (Map.Entry entry : FACTORIES.entrySet()) { + if (entry.getKey().containsVersion(MAVEN_VERSION)) { + return entry.getValue().newInstance(modules); + } + } + throw new AssertionError(String.format( + "Maven version %s is not supported, supprted versions: %s", MAVEN_VERSION, FACTORIES.entrySet())); + } - return this; + public MavenProject readMavenProject(File basedir) throws Exception { + MavenProject project = runtime.readMavenProject(basedir); + Objects.requireNonNull(project); + return project; } - public TestDependency setOptional(boolean optional) { - this.optional = optional; + public MavenSession newMavenSession(MavenProject project) throws Exception { + MavenSession session = runtime.newMavenSession(project.getBasedir()); + session.setCurrentProject(project); + session.setProjects(Arrays.asList(project)); + return session; + } - return this; + /** @since 2.9 */ + public MojoExecution newMojoExecution(String goal, Xpp3Dom... parameters) { + MojoExecution execution = runtime.newMojoExecution(goal); + if (parameters != null) { + // TODO decide if this should go to runtime.newMojoExecution + Xpp3Dom configuration = execution.getConfiguration(); + for (Xpp3Dom parameter : parameters) { + configuration.addChild(parameter); + } + } + return execution; } - public TestDependency setClassifier(String classifier) { - this.classifier = classifier; + public void executeMojo(File basedir, String goal, Xpp3Dom... parameters) throws Exception { + MavenProject project = readMavenProject(basedir); + MavenSession session = newMavenSession(project); + executeMojo(session, project, goal, parameters); + } - return this; + public void executeMojo(MavenSession session, MavenProject project, String goal, Xpp3Dom... parameters) + throws Exception { + MojoExecution execution = newMojoExecution(goal, parameters); + executeMojo(session, project, execution); } - public TestDependency setScope(String scope) { - this.scope = scope; + public void executeMojo(MavenProject project, String goal, Xpp3Dom... parameters) throws Exception { + MavenSession session = newMavenSession(project); + executeMojo(session, project, goal, parameters); + } - return this; + public void executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception { + runtime.executeMojo(session, project, execution); } - public TestDependency addTo(MavenProject project) throws Exception { - return addTo(project, true); + public Mojo lookupConfiguredMojo(MavenSession session, MojoExecution execution) throws Exception { + return runtime.lookupConfiguredMojo(session, execution); } - public TestDependency addTo(MavenProject project, boolean direct) throws Exception { - ArtifactHandler handler = getContainer().lookup(ArtifactHandler.class, type); - DefaultArtifact artifact = new DefaultArtifact(groupId, artifactId, version, scope, type, classifier, handler); - artifact.setFile(file); - artifact.setOptional(optional); - Set artifacts = project.getArtifacts(); - artifacts.add(artifact); - project.setArtifacts(artifacts); - if (direct) { - Set directDependencies = project.getDependencyArtifacts(); - directDependencies = directDependencies == null ? new LinkedHashSet() : new LinkedHashSet<>(directDependencies); - directDependencies.add(artifact); - project.setDependencyArtifacts(directDependencies); - } - - return this; + public DefaultPlexusContainer getContainer() { + return runtime.getContainer(); } - } - - AbstractTestMavenRuntime() { - this(new Module[0]); - } - - AbstractTestMavenRuntime(Module... modules) { - this.modules = modules; - } - - void createMavenRuntime() throws Exception { - runtime = newMavenRuntime(modules); - } - - void shutDownMavenRuntime() { - runtime.shutdown(); - runtime = null; - } - - private MavenRuntime newMavenRuntime(Module[] modules) throws Exception { - for (Map.Entry entry : FACTORIES.entrySet()) { - if (entry.getKey().containsVersion(MAVEN_VERSION)) { - return entry.getValue().newInstance(modules); - } + + public T lookup(Class role) throws Exception { + return runtime.lookup(role); } - throw new AssertionError(String.format("Maven version %s is not supported, supprted versions: %s", MAVEN_VERSION, FACTORIES.entrySet())); - } - - public MavenProject readMavenProject(File basedir) throws Exception { - MavenProject project = runtime.readMavenProject(basedir); - Objects.requireNonNull(project); - return project; - } - - public MavenSession newMavenSession(MavenProject project) throws Exception { - MavenSession session = runtime.newMavenSession(project.getBasedir()); - session.setCurrentProject(project); - session.setProjects(Arrays.asList(project)); - return session; - } - - /** @since 2.9 */ - public MojoExecution newMojoExecution(String goal, Xpp3Dom... parameters) { - MojoExecution execution = runtime.newMojoExecution(goal); - if (parameters != null) { - // TODO decide if this should go to runtime.newMojoExecution - Xpp3Dom configuration = execution.getConfiguration(); - for (Xpp3Dom parameter : parameters) { - configuration.addChild(parameter); - } + + public static Xpp3Dom newParameter(String name, String value) { + Xpp3Dom child = new Xpp3Dom(name); + child.setValue(value); + return child; } - return execution; - } - - public void executeMojo(File basedir, String goal, Xpp3Dom... parameters) throws Exception { - MavenProject project = readMavenProject(basedir); - MavenSession session = newMavenSession(project); - executeMojo(session, project, goal, parameters); - } - - public void executeMojo(MavenSession session, MavenProject project, String goal, Xpp3Dom... parameters) throws Exception { - MojoExecution execution = newMojoExecution(goal, parameters); - executeMojo(session, project, execution); - } - - public void executeMojo(MavenProject project, String goal, Xpp3Dom... parameters) throws Exception { - MavenSession session = newMavenSession(project); - executeMojo(session, project, goal, parameters); - } - - public void executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception { - runtime.executeMojo(session, project, execution); - } - - public Mojo lookupConfiguredMojo(MavenSession session, MojoExecution execution) throws Exception { - return runtime.lookupConfiguredMojo(session, execution); - } - - public DefaultPlexusContainer getContainer() { - return runtime.getContainer(); - } - - public T lookup(Class role) throws Exception { - return runtime.lookup(role); - } - - public static Xpp3Dom newParameter(String name, String value) { - Xpp3Dom child = new Xpp3Dom(name); - child.setValue(value); - return child; - } - - public TestDependency newDependency(File artifact) { - return new TestDependency(artifact); - } + public TestDependency newDependency(File artifact) { + return new TestDependency(artifact); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/AbstractTestResources.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/AbstractTestResources.java index 2ee8fe0..02a54ae 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/AbstractTestResources.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/AbstractTestResources.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing; @@ -20,7 +20,6 @@ import java.util.Properties; import java.util.Set; import java.util.TreeSet; - import org.codehaus.plexus.util.DirectoryScanner; import org.codehaus.plexus.util.FileUtils; import org.junit.Assert; @@ -30,222 +29,223 @@ */ public abstract class AbstractTestResources { - private final String projectsDir; - - private final String workDir; - - private String name; - - AbstractTestResources() { - this("src/test/projects", "target/test-projects"); - } - - AbstractTestResources(String projectsDir, String workDir) { - this.projectsDir = projectsDir; - this.workDir = workDir; - } - - void starting(Class testClass, String methodName) { - if (methodName != null) { - methodName = methodName.replace('/', '_').replace('\\', '_'); - } - name = testClass.getSimpleName() + "_" + methodName; - } - - abstract String getRequiredAnnotationClassName(); - - /** - * Creates new clean copy of test project directory structure. The copy is named after both the test being executed and test project name, which allows the same test project can be used by multiple - * tests and by different instances of the same parametrized tests.
      - * TODO Provide alternative working directory naming for Windows, which still limits path names to ~250 charecters - */ - public File getBasedir(String project) throws IOException { - if (name == null) { - throw new IllegalStateException(getClass().getSimpleName() + " must be a test class field annotated with " + getRequiredAnnotationClassName()); - } - File basedir = new File(workDir, name + "_" + project).getCanonicalFile(); - FileUtils.deleteDirectory(basedir); - Assert.assertTrue("Test project working directory created", basedir.mkdirs()); - File src = new File(projectsDir, project).getCanonicalFile(); - Assert.assertTrue("Test project directory does not exist: " + src.getPath(), src.isDirectory()); - FileUtils.copyDirectoryStructure(src, basedir); - return basedir; - } - - /** - * Creates new clean test work directory. The directory is named after test being executed. - * - * @since 2.2 - */ - public File getBasedir() throws IOException { - if (name == null) { - throw new IllegalStateException(getClass().getSimpleName() + " must be a test class field annotated with " + getRequiredAnnotationClassName()); - } - File basedir = new File(workDir, name).getCanonicalFile(); - FileUtils.deleteDirectory(basedir); - Assert.assertTrue("Test project working directory created", basedir.mkdirs()); - return basedir; - } - - // static helpers - - public static void cp(File basedir, String from, String to) throws IOException { - // TODO ensure destination lastModified timestamp changes - FileUtils.copyFile(new File(basedir, from), new File(basedir, to)); - } - - public static void assertFileContents(File basedir, String expectedPath, String actualPath) throws IOException { - String expected = fileRead(new File(basedir, expectedPath), true); - String actual = fileRead(new File(basedir, actualPath), true); - Assert.assertEquals(expected, actual); - } - - private static String fileRead(File file, boolean normalizeEOL) throws IOException { - StringBuilder sb = new StringBuilder(); - try (BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) { - if (normalizeEOL) { - String str; - while ((str = r.readLine()) != null) { - sb.append(str).append('\n'); - } - } else { - int ch; - while ((ch = r.read()) != -1) { - sb.append((char) ch); - } - } - } - return sb.toString(); - } - - public static void assertFileContents(String expectedContents, File basedir, String path) throws IOException { - String actualContents = fileRead(new File(basedir, path), true); - Assert.assertEquals(expectedContents, actualContents); - } - - public static void assertDirectoryContents(File dir, String... expectedPaths) { - DirectoryScanner scanner = new DirectoryScanner(); - scanner.setBasedir(dir); - scanner.addDefaultExcludes(); - scanner.scan(); - - Set actual = new TreeSet(); - for (String path : scanner.getIncludedFiles()) { - actual.add(path.replace(File.separatorChar, '/')); - } - for (String path : scanner.getIncludedDirectories()) { - if (path.length() > 0) { - actual.add(path.replace(File.separatorChar, '/') + "/"); - } - } - - Set expected = new TreeSet(); - if (expectedPaths != null) { - for (String path : expectedPaths) { - expected.add(path.replace(File.separatorChar, '/')); - } - } - - // compare textual representation to make diff easier to understand - Assert.assertEquals(toString(expected), toString(actual)); - } - - private static String toString(Collection strings) { - StringBuilder sb = new StringBuilder(); - for (String string : strings) { - sb.append(string).append('\n'); - } - return sb.toString(); - } - - public static void touch(File basedir, String path) throws InterruptedException { - touch(new File(basedir, path)); - } - - public static void touch(File file) throws InterruptedException { - if (!file.isFile()) { - throw new IllegalArgumentException("Not a file " + file); - } - long lastModified = file.lastModified(); - file.setLastModified(System.currentTimeMillis()); - - // TODO do modern filesystems still have this silly lastModified resolution? - if (lastModified == file.lastModified()) { - Thread.sleep(1000L); - file.setLastModified(System.currentTimeMillis()); - } - } - - public static void rm(File basedir, String path) { - Assert.assertTrue("delete " + path, new File(basedir, path).delete()); - } - - public static void create(File basedir, String... paths) throws IOException { - if (paths == null || paths.length == 0) { - throw new IllegalArgumentException(); - } - for (String path : paths) { - File file = new File(basedir, path); - file.getParentFile().mkdirs(); - Assert.assertTrue(file.getParentFile().isDirectory()); - file.createNewFile(); - Assert.assertTrue(file.isFile() && file.canRead()); - } - } - - public static void assertFilesPresent(File basedir, String... paths) { - if (basedir == null || paths == null || paths.length <= 0) { - throw new IllegalArgumentException(); - } - if (paths.length == 1) { - Assert.assertTrue(paths[0] + " PRESENT", new File(basedir, paths[0]).isFile()); - } else { - StringBuilder expected = new StringBuilder(); - StringBuilder actual = new StringBuilder(); - for (String path : paths) { - expected.append(path).append("\n"); - if (!new File(basedir, path).isFile()) { - actual.append("NOT PRESENT "); - } - actual.append(path).append("\n"); - } - Assert.assertEquals(expected.toString(), actual.toString()); - } - } - - public static void assertFilesNotPresent(File basedir, String... paths) { - if (basedir == null || paths == null || paths.length <= 0) { - throw new IllegalArgumentException(); - } - if (paths.length == 1) { - Assert.assertFalse(paths[0] + " NOT PRESENT", new File(basedir, paths[0]).isFile()); - } else { - StringBuilder expected = new StringBuilder(); - StringBuilder actual = new StringBuilder(); - for (String path : paths) { - expected.append(path).append("\n"); - if (new File(basedir, path).isFile()) { - actual.append("PRESENT "); - } - actual.append(path).append("\n"); - } - Assert.assertEquals(expected.toString(), actual.toString()); - } - } - - /** - * @since 2.2 - */ - public static Map readProperties(File basedir, String path) throws IOException { - Properties properties = new Properties(); - try (InputStream is = new FileInputStream(new File(basedir, path))) { - properties.load(is); - } - Map result = new HashMap<>(); - for (String key : properties.stringPropertyNames()) { - result.put(key, properties.getProperty(key)); - } - return Collections.unmodifiableMap(result); - } + private final String projectsDir; + + private final String workDir; + + private String name; + + AbstractTestResources() { + this("src/test/projects", "target/test-projects"); + } + + AbstractTestResources(String projectsDir, String workDir) { + this.projectsDir = projectsDir; + this.workDir = workDir; + } + + void starting(Class testClass, String methodName) { + if (methodName != null) { + methodName = methodName.replace('/', '_').replace('\\', '_'); + } + name = testClass.getSimpleName() + "_" + methodName; + } + + abstract String getRequiredAnnotationClassName(); + + /** + * Creates new clean copy of test project directory structure. The copy is named after both the test being executed and test project name, which allows the same test project can be used by multiple + * tests and by different instances of the same parametrized tests.
      + * TODO Provide alternative working directory naming for Windows, which still limits path names to ~250 charecters + */ + public File getBasedir(String project) throws IOException { + if (name == null) { + throw new IllegalStateException(getClass().getSimpleName() + " must be a test class field annotated with " + + getRequiredAnnotationClassName()); + } + File basedir = new File(workDir, name + "_" + project).getCanonicalFile(); + FileUtils.deleteDirectory(basedir); + Assert.assertTrue("Test project working directory created", basedir.mkdirs()); + File src = new File(projectsDir, project).getCanonicalFile(); + Assert.assertTrue("Test project directory does not exist: " + src.getPath(), src.isDirectory()); + FileUtils.copyDirectoryStructure(src, basedir); + return basedir; + } + + /** + * Creates new clean test work directory. The directory is named after test being executed. + * + * @since 2.2 + */ + public File getBasedir() throws IOException { + if (name == null) { + throw new IllegalStateException(getClass().getSimpleName() + " must be a test class field annotated with " + + getRequiredAnnotationClassName()); + } + File basedir = new File(workDir, name).getCanonicalFile(); + FileUtils.deleteDirectory(basedir); + Assert.assertTrue("Test project working directory created", basedir.mkdirs()); + return basedir; + } + + // static helpers + + public static void cp(File basedir, String from, String to) throws IOException { + // TODO ensure destination lastModified timestamp changes + FileUtils.copyFile(new File(basedir, from), new File(basedir, to)); + } + + public static void assertFileContents(File basedir, String expectedPath, String actualPath) throws IOException { + String expected = fileRead(new File(basedir, expectedPath), true); + String actual = fileRead(new File(basedir, actualPath), true); + Assert.assertEquals(expected, actual); + } + + private static String fileRead(File file, boolean normalizeEOL) throws IOException { + StringBuilder sb = new StringBuilder(); + try (BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) { + if (normalizeEOL) { + String str; + while ((str = r.readLine()) != null) { + sb.append(str).append('\n'); + } + } else { + int ch; + while ((ch = r.read()) != -1) { + sb.append((char) ch); + } + } + } + return sb.toString(); + } + + public static void assertFileContents(String expectedContents, File basedir, String path) throws IOException { + String actualContents = fileRead(new File(basedir, path), true); + Assert.assertEquals(expectedContents, actualContents); + } + + public static void assertDirectoryContents(File dir, String... expectedPaths) { + DirectoryScanner scanner = new DirectoryScanner(); + scanner.setBasedir(dir); + scanner.addDefaultExcludes(); + scanner.scan(); + + Set actual = new TreeSet(); + for (String path : scanner.getIncludedFiles()) { + actual.add(path.replace(File.separatorChar, '/')); + } + for (String path : scanner.getIncludedDirectories()) { + if (path.length() > 0) { + actual.add(path.replace(File.separatorChar, '/') + "/"); + } + } + + Set expected = new TreeSet(); + if (expectedPaths != null) { + for (String path : expectedPaths) { + expected.add(path.replace(File.separatorChar, '/')); + } + } + + // compare textual representation to make diff easier to understand + Assert.assertEquals(toString(expected), toString(actual)); + } + + private static String toString(Collection strings) { + StringBuilder sb = new StringBuilder(); + for (String string : strings) { + sb.append(string).append('\n'); + } + return sb.toString(); + } + + public static void touch(File basedir, String path) throws InterruptedException { + touch(new File(basedir, path)); + } + + public static void touch(File file) throws InterruptedException { + if (!file.isFile()) { + throw new IllegalArgumentException("Not a file " + file); + } + long lastModified = file.lastModified(); + file.setLastModified(System.currentTimeMillis()); + + // TODO do modern filesystems still have this silly lastModified resolution? + if (lastModified == file.lastModified()) { + Thread.sleep(1000L); + file.setLastModified(System.currentTimeMillis()); + } + } + public static void rm(File basedir, String path) { + Assert.assertTrue("delete " + path, new File(basedir, path).delete()); + } + + public static void create(File basedir, String... paths) throws IOException { + if (paths == null || paths.length == 0) { + throw new IllegalArgumentException(); + } + for (String path : paths) { + File file = new File(basedir, path); + file.getParentFile().mkdirs(); + Assert.assertTrue(file.getParentFile().isDirectory()); + file.createNewFile(); + Assert.assertTrue(file.isFile() && file.canRead()); + } + } + + public static void assertFilesPresent(File basedir, String... paths) { + if (basedir == null || paths == null || paths.length <= 0) { + throw new IllegalArgumentException(); + } + if (paths.length == 1) { + Assert.assertTrue(paths[0] + " PRESENT", new File(basedir, paths[0]).isFile()); + } else { + StringBuilder expected = new StringBuilder(); + StringBuilder actual = new StringBuilder(); + for (String path : paths) { + expected.append(path).append("\n"); + if (!new File(basedir, path).isFile()) { + actual.append("NOT PRESENT "); + } + actual.append(path).append("\n"); + } + Assert.assertEquals(expected.toString(), actual.toString()); + } + } + + public static void assertFilesNotPresent(File basedir, String... paths) { + if (basedir == null || paths == null || paths.length <= 0) { + throw new IllegalArgumentException(); + } + if (paths.length == 1) { + Assert.assertFalse(paths[0] + " NOT PRESENT", new File(basedir, paths[0]).isFile()); + } else { + StringBuilder expected = new StringBuilder(); + StringBuilder actual = new StringBuilder(); + for (String path : paths) { + expected.append(path).append("\n"); + if (new File(basedir, path).isFile()) { + actual.append("PRESENT "); + } + actual.append(path).append("\n"); + } + Assert.assertEquals(expected.toString(), actual.toString()); + } + } + + /** + * @since 2.2 + */ + public static Map readProperties(File basedir, String path) throws IOException { + Properties properties = new Properties(); + try (InputStream is = new FileInputStream(new File(basedir, path))) { + properties.load(is); + } + Map result = new HashMap<>(); + for (String key : properties.stringPropertyNames()) { + result.put(key, properties.getProperty(key)); + } + return Collections.unmodifiableMap(result); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven30xRuntime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven30xRuntime.java index ef7b9a7..f37d04e 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven30xRuntime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven30xRuntime.java @@ -1,14 +1,14 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing; - -//some of the code was originally copied from org.apache.maven.plugin.testing.AbstractMojoTestCase and org.apache.maven.plugin.testing.MojoRule +// some of the code was originally copied from org.apache.maven.plugin.testing.AbstractMojoTestCase and +// org.apache.maven.plugin.testing.MojoRule /* * Licensed to the Apache Software Foundation (ASF) under one @@ -31,6 +31,7 @@ import static org.junit.Assert.assertNotNull; +import com.google.inject.Module; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -47,7 +48,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; - import org.apache.maven.DefaultMaven; import org.apache.maven.Maven; import org.apache.maven.artifact.Artifact; @@ -91,310 +91,330 @@ import org.codehaus.plexus.util.xml.XmlStreamReader; import org.codehaus.plexus.util.xml.Xpp3Dom; -import com.google.inject.Module; - class Maven30xRuntime implements MavenRuntime { - private static final String PATH_PLUGINXML = "META-INF/maven/plugin.xml"; - - protected final TestProperties properties = new TestProperties(); - - protected final DefaultPlexusContainer container; - protected final Map mojoDescriptors; - - public Maven30xRuntime(Module[] modules) throws Exception { - ClassWorld classWorld = new ClassWorld("plexus.core", Thread.currentThread().getContextClassLoader()); - ContainerConfiguration cc = new DefaultContainerConfiguration() // - .setClassWorld(classWorld) // - .setClassPathScanning(PlexusConstants.SCANNING_INDEX) // - .setAutoWiring(true) // - .setName("maven"); - this.container = new DefaultPlexusContainer(cc, modules); - this.mojoDescriptors = Collections.unmodifiableMap(readPluginXml(container)); - } - - private Map readPluginXml(DefaultPlexusContainer container) throws Exception { - Map mojoDescriptors = new HashMap(); - Enumeration resources = getClass().getClassLoader().getResources(PATH_PLUGINXML); - while (resources.hasMoreElements()) { - InputStream is = resources.nextElement().openStream(); - - if (is == null) { - return Collections.emptyMap(); - } - - XmlStreamReader reader = new XmlStreamReader(is); - - @SuppressWarnings("rawtypes") - Map contextData = container.getContext().getContextData(); - @SuppressWarnings("unchecked") - InterpolationFilterReader interpolationFilterReader = new InterpolationFilterReader(new BufferedReader(reader), contextData); - - PluginDescriptor pluginDescriptor = new PluginDescriptorBuilder().build(interpolationFilterReader); - - // Due this commit to prevent NPE https://github.com/apache/maven/commit/05b748ff6aa15aa63a9c9d5f9f5679f47bf9e83d - // The pluginDescriptor.plugin is set ONLY when it already went through DefaultMavenPluginManager, nothing - // else sets this. - Plugin plugin = new Plugin(); - plugin.setGroupId( pluginDescriptor.getGroupId() ); - plugin.setArtifactId( pluginDescriptor.getArtifactId() ); - plugin.setVersion( pluginDescriptor.getVersion() ); - pluginDescriptor.setPlugin( plugin ); - - Artifact artifact = container.lookup(RepositorySystem.class) // - .createArtifact(pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(), pluginDescriptor.getVersion(), ".jar"); - - artifact.setFile(getPluginArtifactFile()); - pluginDescriptor.setPluginArtifact(artifact); - pluginDescriptor.setArtifacts(Arrays.asList(artifact)); - - for (ComponentDescriptor desc : pluginDescriptor.getComponents()) { - container.addComponentDescriptor(desc); - } - - for (MojoDescriptor mojoDescriptor : pluginDescriptor.getMojos()) { - // TODO decide how to handle duplicate goals - // this is possible when one plugin extends another - // for example, Tycho 'compile' goal is an extension of standard maven 'compile' - mojoDescriptors.put(mojoDescriptor.getGoal(), mojoDescriptor); - } + private static final String PATH_PLUGINXML = "META-INF/maven/plugin.xml"; + + protected final TestProperties properties = new TestProperties(); + + protected final DefaultPlexusContainer container; + protected final Map mojoDescriptors; + + public Maven30xRuntime(Module[] modules) throws Exception { + ClassWorld classWorld = + new ClassWorld("plexus.core", Thread.currentThread().getContextClassLoader()); + ContainerConfiguration cc = new DefaultContainerConfiguration() // + .setClassWorld(classWorld) // + .setClassPathScanning(PlexusConstants.SCANNING_INDEX) // + .setAutoWiring(true) // + .setName("maven"); + this.container = new DefaultPlexusContainer(cc, modules); + this.mojoDescriptors = Collections.unmodifiableMap(readPluginXml(container)); } - return mojoDescriptors; - } - - /** - * Returns best-effort plugin artifact file. - *

      - * First, attempts to determine parent directory of META-INF directory holding the plugin descriptor. If META-INF parent directory cannot be determined, falls back to test basedir. - */ - private File getPluginArtifactFile() throws IOException { - final String pluginDescriptorLocation = PATH_PLUGINXML; - final URL resource = getClass().getResource("/" + pluginDescriptorLocation); - - File file = null; - - // attempt to resolve relative to META-INF/maven/plugin.xml first - if (resource != null) { - if ("file".equalsIgnoreCase(resource.getProtocol())) { - String path = resource.getPath(); - if (path.endsWith(pluginDescriptorLocation)) { - file = new File(path.substring(0, path.length() - pluginDescriptorLocation.length())); + + private Map readPluginXml(DefaultPlexusContainer container) throws Exception { + Map mojoDescriptors = new HashMap(); + Enumeration resources = getClass().getClassLoader().getResources(PATH_PLUGINXML); + while (resources.hasMoreElements()) { + InputStream is = resources.nextElement().openStream(); + + if (is == null) { + return Collections.emptyMap(); + } + + XmlStreamReader reader = new XmlStreamReader(is); + + @SuppressWarnings("rawtypes") + Map contextData = container.getContext().getContextData(); + @SuppressWarnings("unchecked") + InterpolationFilterReader interpolationFilterReader = + new InterpolationFilterReader(new BufferedReader(reader), contextData); + + PluginDescriptor pluginDescriptor = new PluginDescriptorBuilder().build(interpolationFilterReader); + + // Due this commit to prevent NPE + // https://github.com/apache/maven/commit/05b748ff6aa15aa63a9c9d5f9f5679f47bf9e83d + // The pluginDescriptor.plugin is set ONLY when it already went through DefaultMavenPluginManager, nothing + // else sets this. + Plugin plugin = new Plugin(); + plugin.setGroupId(pluginDescriptor.getGroupId()); + plugin.setArtifactId(pluginDescriptor.getArtifactId()); + plugin.setVersion(pluginDescriptor.getVersion()); + pluginDescriptor.setPlugin(plugin); + + Artifact artifact = container + .lookup(RepositorySystem.class) // + .createArtifact( + pluginDescriptor.getGroupId(), + pluginDescriptor.getArtifactId(), + pluginDescriptor.getVersion(), + ".jar"); + + artifact.setFile(getPluginArtifactFile()); + pluginDescriptor.setPluginArtifact(artifact); + pluginDescriptor.setArtifacts(Arrays.asList(artifact)); + + for (ComponentDescriptor desc : pluginDescriptor.getComponents()) { + container.addComponentDescriptor(desc); + } + + for (MojoDescriptor mojoDescriptor : pluginDescriptor.getMojos()) { + // TODO decide how to handle duplicate goals + // this is possible when one plugin extends another + // for example, Tycho 'compile' goal is an extension of standard maven 'compile' + mojoDescriptors.put(mojoDescriptor.getGoal(), mojoDescriptor); + } } - } else if ("jar".equalsIgnoreCase(resource.getProtocol())) { - // TODO is there a helper for this somewhere? - try { - URL jarfile = new URL(resource.getPath()); - if ("file".equalsIgnoreCase(jarfile.getProtocol())) { - String path = jarfile.getPath(); - if (path.endsWith(pluginDescriptorLocation)) { - file = new File(path.substring(0, path.length() - pluginDescriptorLocation.length() - 2)); + return mojoDescriptors; + } + + /** + * Returns best-effort plugin artifact file. + *

      + * First, attempts to determine parent directory of META-INF directory holding the plugin descriptor. If META-INF parent directory cannot be determined, falls back to test basedir. + */ + private File getPluginArtifactFile() throws IOException { + final String pluginDescriptorLocation = PATH_PLUGINXML; + final URL resource = getClass().getResource("/" + pluginDescriptorLocation); + + File file = null; + + // attempt to resolve relative to META-INF/maven/plugin.xml first + if (resource != null) { + if ("file".equalsIgnoreCase(resource.getProtocol())) { + String path = resource.getPath(); + if (path.endsWith(pluginDescriptorLocation)) { + file = new File(path.substring(0, path.length() - pluginDescriptorLocation.length())); + } + } else if ("jar".equalsIgnoreCase(resource.getProtocol())) { + // TODO is there a helper for this somewhere? + try { + URL jarfile = new URL(resource.getPath()); + if ("file".equalsIgnoreCase(jarfile.getProtocol())) { + String path = jarfile.getPath(); + if (path.endsWith(pluginDescriptorLocation)) { + file = new File(path.substring(0, path.length() - pluginDescriptorLocation.length() - 2)); + } + } + } catch (MalformedURLException e) { + // not jar:file:/ URL, too bad + } } - } - } catch (MalformedURLException e) { - // not jar:file:/ URL, too bad } - } + + // fallback to test project basedir if couldn't resolve relative to META-INF/maven/plugin.xml + if (file == null || !file.exists()) { + file = new File("").getCanonicalFile(); + } + + return file.getCanonicalFile(); } - // fallback to test project basedir if couldn't resolve relative to META-INF/maven/plugin.xml - if (file == null || !file.exists()) { - file = new File("").getCanonicalFile(); + @Override + public void shutdown() { + container.dispose(); } - return file.getCanonicalFile(); - } - - @Override - public void shutdown() { - container.dispose(); - } - - @Override - public MavenProject readMavenProject(File basedir) throws Exception { - File pom = new File(basedir, "pom.xml"); - MavenExecutionRequest request = newExecutionRequest(); - request.setBaseDirectory(basedir); - ProjectBuildingRequest configuration = getProjectBuildingRequest(request); - return container.lookup(ProjectBuilder.class).build(getPomFile(pom), configuration).getProject(); - } - - protected ProjectBuildingRequest getProjectBuildingRequest(MavenExecutionRequest request) throws ComponentLookupException { - // TODO populate repository system session... if somebody asks for it really nicely - return request.getProjectBuildingRequest(); - } - - protected File getPomFile(File pom) throws IOException { - if (!pom.exists()) { - try (BufferedWriter w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(pom), "UTF-8"))) { - w.write("\n"); - w.write("\n"); - w.write("4.0.0\n"); - w.write("test\n"); - w.write("test\n"); - w.write("1\n"); - w.write("\n"); - } + @Override + public MavenProject readMavenProject(File basedir) throws Exception { + File pom = new File(basedir, "pom.xml"); + MavenExecutionRequest request = newExecutionRequest(); + request.setBaseDirectory(basedir); + ProjectBuildingRequest configuration = getProjectBuildingRequest(request); + return container + .lookup(ProjectBuilder.class) + .build(getPomFile(pom), configuration) + .getProject(); } - return pom; - } - - @Override - public MojoExecution newMojoExecution(String goal) { - MojoDescriptor mojoDescriptor = mojoDescriptors.get(goal); - assertNotNull(String.format("The MojoDescriptor for the goal %s cannot be null.", goal), mojoDescriptor); - MojoExecution execution = new MojoExecution(mojoDescriptor); - execution.setConfiguration(new Xpp3Dom("configuration")); - return execution; - } - - // copy&paste from - // org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.finalizeMojoConfiguration(MojoExecution) - protected void finalizeMojoConfiguration(MojoExecution mojoExecution) { - MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); - - Xpp3Dom executionConfiguration = mojoExecution.getConfiguration(); - if (executionConfiguration == null) { - executionConfiguration = new Xpp3Dom("configuration"); + + protected ProjectBuildingRequest getProjectBuildingRequest(MavenExecutionRequest request) + throws ComponentLookupException { + // TODO populate repository system session... if somebody asks for it really nicely + return request.getProjectBuildingRequest(); } - Xpp3Dom defaultConfiguration = MojoDescriptorCreator.convert(mojoDescriptor); + protected File getPomFile(File pom) throws IOException { + if (!pom.exists()) { + try (BufferedWriter w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(pom), "UTF-8"))) { + w.write("\n"); + w.write("\n"); + w.write("4.0.0\n"); + w.write("test\n"); + w.write("test\n"); + w.write("1\n"); + w.write("\n"); + } + } + return pom; + } - Xpp3Dom finalConfiguration = new Xpp3Dom("configuration"); + @Override + public MojoExecution newMojoExecution(String goal) { + MojoDescriptor mojoDescriptor = mojoDescriptors.get(goal); + assertNotNull(String.format("The MojoDescriptor for the goal %s cannot be null.", goal), mojoDescriptor); + MojoExecution execution = new MojoExecution(mojoDescriptor); + execution.setConfiguration(new Xpp3Dom("configuration")); + return execution; + } - if (mojoDescriptor.getParameters() != null) { - for (Parameter parameter : mojoDescriptor.getParameters()) { - Xpp3Dom parameterConfiguration = executionConfiguration.getChild(parameter.getName()); + // copy&paste from + // org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.finalizeMojoConfiguration(MojoExecution) + protected void finalizeMojoConfiguration(MojoExecution mojoExecution) { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); - if (parameterConfiguration == null) { - parameterConfiguration = executionConfiguration.getChild(parameter.getAlias()); + Xpp3Dom executionConfiguration = mojoExecution.getConfiguration(); + if (executionConfiguration == null) { + executionConfiguration = new Xpp3Dom("configuration"); } - Xpp3Dom parameterDefaults = defaultConfiguration.getChild(parameter.getName()); + Xpp3Dom defaultConfiguration = MojoDescriptorCreator.convert(mojoDescriptor); + + Xpp3Dom finalConfiguration = new Xpp3Dom("configuration"); + + if (mojoDescriptor.getParameters() != null) { + for (Parameter parameter : mojoDescriptor.getParameters()) { + Xpp3Dom parameterConfiguration = executionConfiguration.getChild(parameter.getName()); - parameterConfiguration = Xpp3Dom.mergeXpp3Dom(parameterConfiguration, parameterDefaults, Boolean.TRUE); + if (parameterConfiguration == null) { + parameterConfiguration = executionConfiguration.getChild(parameter.getAlias()); + } - if (parameterConfiguration != null) { - parameterConfiguration = new Xpp3Dom(parameterConfiguration, parameter.getName()); + Xpp3Dom parameterDefaults = defaultConfiguration.getChild(parameter.getName()); - if (StringUtils.isEmpty(parameterConfiguration.getAttribute("implementation")) && StringUtils.isNotEmpty(parameter.getImplementation())) { - parameterConfiguration.setAttribute("implementation", parameter.getImplementation()); - } + parameterConfiguration = Xpp3Dom.mergeXpp3Dom(parameterConfiguration, parameterDefaults, Boolean.TRUE); - finalConfiguration.addChild(parameterConfiguration); + if (parameterConfiguration != null) { + parameterConfiguration = new Xpp3Dom(parameterConfiguration, parameter.getName()); + + if (StringUtils.isEmpty(parameterConfiguration.getAttribute("implementation")) + && StringUtils.isNotEmpty(parameter.getImplementation())) { + parameterConfiguration.setAttribute("implementation", parameter.getImplementation()); + } + + finalConfiguration.addChild(parameterConfiguration); + } + } } - } + + mojoExecution.setConfiguration(finalConfiguration); } - mojoExecution.setConfiguration(finalConfiguration); - } - - @Override - public MavenSession newMavenSession(File basedir) throws Exception { - MavenExecutionRequest request = newExecutionRequest(); - MavenExecutionResult result = new DefaultMavenExecutionResult(); - DefaultMaven maven = (DefaultMaven) container.lookup(Maven.class); - try { - Object repositorySession = maven.getClass().getMethod("newRepositorySession", MavenExecutionRequest.class).invoke(maven, request); - Class repositorySessionClass = repositorySession.getClass().getClassLoader().loadClass("org.sonatype.aether.RepositorySystemSession"); - Constructor constructor = MavenSession.class.getConstructor(PlexusContainer.class, repositorySessionClass, MavenExecutionRequest.class, MavenExecutionResult.class); - return constructor.newInstance(container, repositorySession, request, result); - } catch (ReflectiveOperationException | SecurityException e) { - throw new RuntimeException(e); + @Override + public MavenSession newMavenSession(File basedir) throws Exception { + MavenExecutionRequest request = newExecutionRequest(); + MavenExecutionResult result = new DefaultMavenExecutionResult(); + DefaultMaven maven = (DefaultMaven) container.lookup(Maven.class); + try { + Object repositorySession = maven.getClass() + .getMethod("newRepositorySession", MavenExecutionRequest.class) + .invoke(maven, request); + Class repositorySessionClass = repositorySession + .getClass() + .getClassLoader() + .loadClass("org.sonatype.aether.RepositorySystemSession"); + Constructor constructor = MavenSession.class.getConstructor( + PlexusContainer.class, + repositorySessionClass, + MavenExecutionRequest.class, + MavenExecutionResult.class); + return constructor.newInstance(container, repositorySession, request, result); + } catch (ReflectiveOperationException | SecurityException e) { + throw new RuntimeException(e); + } } - } - - @SuppressWarnings("deprecation") - protected MavenExecutionRequest newExecutionRequest() throws Exception { - - // system properties - Properties buildProperties = getMavenBuildProperties(); - String mavenVersion = buildProperties.getProperty("version"); - Properties systemProperties = new Properties(); - systemProperties.putAll(System.getProperties()); // TODO not thread safe - systemProperties.setProperty("maven.version", mavenVersion); - systemProperties.setProperty("maven.build.version", mavenVersion); - - // request with initial configuration - MavenExecutionRequest request = new DefaultMavenExecutionRequest(); - request.setLocalRepositoryPath(properties.getLocalRepository()); - request.setUserSettingsFile(properties.getUserSettings()); - request.setGlobalSettingsFile(properties.getGlobalSettings()); - request.setOffline(properties.getOffline()); - request.setUpdateSnapshots(properties.getUpdateSnapshots()); - request.setSystemProperties(systemProperties); - - // read settings - SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest(); - settingsRequest.setGlobalSettingsFile(request.getGlobalSettingsFile()); - settingsRequest.setUserSettingsFile(request.getUserSettingsFile()); - settingsRequest.setSystemProperties(request.getSystemProperties()); - settingsRequest.setUserProperties(request.getUserProperties()); - Settings settings = lookup(SettingsBuilder.class).build(settingsRequest).getEffectiveSettings(); - - MavenExecutionRequestPopulator populator = container.lookup(MavenExecutionRequestPopulator.class); - request = populator.populateFromSettings(request, settings); - return populator.populateDefaults(request); - } - - private Properties getMavenBuildProperties() { - Properties properties = new Properties(); - try (InputStream is = getClass().getResourceAsStream("/META-INF/maven/org.apache.maven/maven-core/pom.properties")) { - properties.load(is); - } catch (IOException e) { - // ignore + + @SuppressWarnings("deprecation") + protected MavenExecutionRequest newExecutionRequest() throws Exception { + + // system properties + Properties buildProperties = getMavenBuildProperties(); + String mavenVersion = buildProperties.getProperty("version"); + Properties systemProperties = new Properties(); + systemProperties.putAll(System.getProperties()); // TODO not thread safe + systemProperties.setProperty("maven.version", mavenVersion); + systemProperties.setProperty("maven.build.version", mavenVersion); + + // request with initial configuration + MavenExecutionRequest request = new DefaultMavenExecutionRequest(); + request.setLocalRepositoryPath(properties.getLocalRepository()); + request.setUserSettingsFile(properties.getUserSettings()); + request.setGlobalSettingsFile(properties.getGlobalSettings()); + request.setOffline(properties.getOffline()); + request.setUpdateSnapshots(properties.getUpdateSnapshots()); + request.setSystemProperties(systemProperties); + + // read settings + SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest(); + settingsRequest.setGlobalSettingsFile(request.getGlobalSettingsFile()); + settingsRequest.setUserSettingsFile(request.getUserSettingsFile()); + settingsRequest.setSystemProperties(request.getSystemProperties()); + settingsRequest.setUserProperties(request.getUserProperties()); + Settings settings = lookup(SettingsBuilder.class).build(settingsRequest).getEffectiveSettings(); + + MavenExecutionRequestPopulator populator = container.lookup(MavenExecutionRequestPopulator.class); + request = populator.populateFromSettings(request, settings); + return populator.populateDefaults(request); } - return properties; - } - @Override - public Mojo executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception { - Mojo mojo = lookupConfiguredMojo(session, execution); - mojo.execute(); - return mojo; - } + private Properties getMavenBuildProperties() { + Properties properties = new Properties(); + try (InputStream is = + getClass().getResourceAsStream("/META-INF/maven/org.apache.maven/maven-core/pom.properties")) { + properties.load(is); + } catch (IOException e) { + // ignore + } + return properties; + } - @Override - public Mojo lookupConfiguredMojo(MavenSession session, MojoExecution execution) throws Exception { - MavenProject project = session.getCurrentProject(); - MojoDescriptor mojoDescriptor = execution.getMojoDescriptor(); + @Override + public Mojo executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception { + Mojo mojo = lookupConfiguredMojo(session, execution); + mojo.execute(); + return mojo; + } - Mojo mojo = container.lookup(Mojo.class, mojoDescriptor.getRoleHint()); + @Override + public Mojo lookupConfiguredMojo(MavenSession session, MojoExecution execution) throws Exception { + MavenProject project = session.getCurrentProject(); + MojoDescriptor mojoDescriptor = execution.getMojoDescriptor(); - ExpressionEvaluator evaluator = new PluginParameterExpressionEvaluator(session, execution); + Mojo mojo = container.lookup(Mojo.class, mojoDescriptor.getRoleHint()); - Xpp3Dom configuration = null; - Plugin plugin = project.getPlugin(mojoDescriptor.getPluginDescriptor().getPluginLookupKey()); - if (plugin != null) { - configuration = (Xpp3Dom) plugin.getConfiguration(); - } - if (configuration == null) { - configuration = new Xpp3Dom("configuration"); - } - configuration = Xpp3Dom.mergeXpp3Dom(configuration, execution.getConfiguration()); - execution.setConfiguration(configuration); - finalizeMojoConfiguration(execution); + ExpressionEvaluator evaluator = new PluginParameterExpressionEvaluator(session, execution); - PlexusConfiguration pluginConfiguration = new XmlPlexusConfiguration(execution.getConfiguration()); + Xpp3Dom configuration = null; + Plugin plugin = project.getPlugin(mojoDescriptor.getPluginDescriptor().getPluginLookupKey()); + if (plugin != null) { + configuration = (Xpp3Dom) plugin.getConfiguration(); + } + if (configuration == null) { + configuration = new Xpp3Dom("configuration"); + } + configuration = Xpp3Dom.mergeXpp3Dom(configuration, execution.getConfiguration()); + execution.setConfiguration(configuration); + finalizeMojoConfiguration(execution); - String configuratorHint = "basic"; - if (mojoDescriptor.getComponentConfigurator() != null) { - configuratorHint = mojoDescriptor.getComponentConfigurator(); - } + PlexusConfiguration pluginConfiguration = new XmlPlexusConfiguration(execution.getConfiguration()); - ComponentConfigurator configurator = container.lookup(ComponentConfigurator.class, configuratorHint); + String configuratorHint = "basic"; + if (mojoDescriptor.getComponentConfigurator() != null) { + configuratorHint = mojoDescriptor.getComponentConfigurator(); + } - configurator.configureComponent(mojo, pluginConfiguration, evaluator, container.getContainerRealm()); + ComponentConfigurator configurator = container.lookup(ComponentConfigurator.class, configuratorHint); - return mojo; - } + configurator.configureComponent(mojo, pluginConfiguration, evaluator, container.getContainerRealm()); - @Override - public DefaultPlexusContainer getContainer() { - return container; - } + return mojo; + } - @Override - public T lookup(Class role) throws ComponentLookupException { - return container.lookup(role); - } + @Override + public DefaultPlexusContainer getContainer() { + return container; + } + @Override + public T lookup(Class role) throws ComponentLookupException { + return container.lookup(role); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven311Runtime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven311Runtime.java index 097ee1e..9ffd920 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven311Runtime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven311Runtime.java @@ -1,7 +1,14 @@ +/* + * Copyright (c) 2014-2024 Takari, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + */ package io.takari.maven.testing; +import com.google.inject.Module; import java.io.File; - import org.apache.maven.DefaultMaven; import org.apache.maven.Maven; import org.apache.maven.execution.DefaultMavenExecutionResult; @@ -14,42 +21,44 @@ import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.eclipse.aether.RepositorySystemSession; -import com.google.inject.Module; - class Maven311Runtime extends Maven30xRuntime { - public Maven311Runtime(Module[] modules) throws Exception { - super(modules); - } - - @Override - public MavenProject readMavenProject(File basedir) throws Exception { - File pom = new File(basedir, "pom.xml"); - MavenExecutionRequest request = newExecutionRequest(); - request.setBaseDirectory(basedir); - ProjectBuildingRequest configuration = getProjectBuildingRequest(request); - return container.lookup(ProjectBuilder.class).build(getPomFile(pom), configuration).getProject(); - } - - @Override - protected ProjectBuildingRequest getProjectBuildingRequest(MavenExecutionRequest request) throws ComponentLookupException { - ProjectBuildingRequest configuration = request.getProjectBuildingRequest(); - configuration.setRepositorySession(newRepositorySession(request)); - return configuration; - } - - @SuppressWarnings("deprecation") - @Override - public MavenSession newMavenSession(File basedir) throws Exception { - MavenExecutionRequest request = newExecutionRequest(); - RepositorySystemSession repositorySession = newRepositorySession(request); - - MavenExecutionResult result = new DefaultMavenExecutionResult(); - return new MavenSession(container, repositorySession, request, result); - } - - protected RepositorySystemSession newRepositorySession(MavenExecutionRequest request) throws ComponentLookupException { - return ((DefaultMaven) container.lookup(Maven.class)).newRepositorySession(request); - } + public Maven311Runtime(Module[] modules) throws Exception { + super(modules); + } + + @Override + public MavenProject readMavenProject(File basedir) throws Exception { + File pom = new File(basedir, "pom.xml"); + MavenExecutionRequest request = newExecutionRequest(); + request.setBaseDirectory(basedir); + ProjectBuildingRequest configuration = getProjectBuildingRequest(request); + return container + .lookup(ProjectBuilder.class) + .build(getPomFile(pom), configuration) + .getProject(); + } + + @Override + protected ProjectBuildingRequest getProjectBuildingRequest(MavenExecutionRequest request) + throws ComponentLookupException { + ProjectBuildingRequest configuration = request.getProjectBuildingRequest(); + configuration.setRepositorySession(newRepositorySession(request)); + return configuration; + } + + @SuppressWarnings("deprecation") + @Override + public MavenSession newMavenSession(File basedir) throws Exception { + MavenExecutionRequest request = newExecutionRequest(); + RepositorySystemSession repositorySession = newRepositorySession(request); + + MavenExecutionResult result = new DefaultMavenExecutionResult(); + return new MavenSession(container, repositorySession, request, result); + } + protected RepositorySystemSession newRepositorySession(MavenExecutionRequest request) + throws ComponentLookupException { + return ((DefaultMaven) container.lookup(Maven.class)).newRepositorySession(request); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven321Runtime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven321Runtime.java index 7c28836..6c2156d 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven321Runtime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven321Runtime.java @@ -1,5 +1,14 @@ +/* + * Copyright (c) 2014-2024 Takari, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + */ package io.takari.maven.testing; +import com.google.inject.AbstractModule; +import com.google.inject.Module; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MojoExecutionEvent; import org.apache.maven.execution.MojoExecutionListener; @@ -9,76 +18,77 @@ import org.apache.maven.plugin.MojoExecution; import org.apache.maven.project.MavenProject; -import com.google.inject.AbstractModule; -import com.google.inject.Module; - class Maven321Runtime extends Maven311Runtime { - private static class MojoExecutionScopeModule extends AbstractModule { - @Override - protected void configure() { - MojoExecutionScope scope = new MojoExecutionScope(); - bind(MojoExecutionScope.class).toInstance(scope); + private static class MojoExecutionScopeModule extends AbstractModule { + @Override + protected void configure() { + MojoExecutionScope scope = new MojoExecutionScope(); + bind(MojoExecutionScope.class).toInstance(scope); + + bindScope(MojoExecutionScoped.class, scope); + + // standard scope bindings + bind(MavenProject.class) + .toProvider(MojoExecutionScope.seededKeyProvider()) + .in(scope); + bind(MojoExecution.class) + .toProvider(MojoExecutionScope.seededKeyProvider()) + .in(scope); + } + } - bindScope(MojoExecutionScoped.class, scope); + public static Maven321Runtime create(Module[] modules) throws Exception { + Module[] joined = new Module[modules.length + 1]; + joined[0] = new MojoExecutionScopeModule(); + System.arraycopy(modules, 0, joined, 1, modules.length); + return new Maven321Runtime(joined); + } - // standard scope bindings - bind(MavenProject.class).toProvider(MojoExecutionScope.seededKeyProvider()).in(scope); - bind(MojoExecution.class).toProvider(MojoExecutionScope.seededKeyProvider()).in(scope); + protected Maven321Runtime(Module[] modules) throws Exception { + super(modules); } - } - - public static Maven321Runtime create(Module[] modules) throws Exception { - Module[] joined = new Module[modules.length + 1]; - joined[0] = new MojoExecutionScopeModule(); - System.arraycopy(modules, 0, joined, 1, modules.length); - return new Maven321Runtime(joined); - } - - protected Maven321Runtime(Module[] modules) throws Exception { - super(modules); - } - - @Override - public Mojo executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception { - Object sessionScope = container.lookup("org.apache.maven.SessionScope"); - try { - enter(sessionScope); - seed(sessionScope, MavenSession.class, session); - - MojoExecutionScope executionScope = container.lookup(MojoExecutionScope.class); - try { - executionScope.enter(); - - executionScope.seed(MavenProject.class, project); - executionScope.seed(MojoExecution.class, execution); - - Mojo mojo = lookupConfiguredMojo(session, execution); - mojo.execute(); - - MojoExecutionEvent event = new MojoExecutionEvent(session, project, execution, mojo); - for (MojoExecutionListener listener : container.lookupList(MojoExecutionListener.class)) { - listener.afterMojoExecutionSuccess(event); - } - return mojo; - } finally { - executionScope.exit(); - } - } finally { - exit(sessionScope); + @Override + public Mojo executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception { + Object sessionScope = container.lookup("org.apache.maven.SessionScope"); + try { + enter(sessionScope); + seed(sessionScope, MavenSession.class, session); + + MojoExecutionScope executionScope = container.lookup(MojoExecutionScope.class); + try { + executionScope.enter(); + + executionScope.seed(MavenProject.class, project); + executionScope.seed(MojoExecution.class, execution); + + Mojo mojo = lookupConfiguredMojo(session, execution); + mojo.execute(); + + MojoExecutionEvent event = new MojoExecutionEvent(session, project, execution, mojo); + for (MojoExecutionListener listener : container.lookupList(MojoExecutionListener.class)) { + listener.afterMojoExecutionSuccess(event); + } + + return mojo; + } finally { + executionScope.exit(); + } + } finally { + exit(sessionScope); + } } - } - private static void enter(Object scope) throws Exception { - scope.getClass().getMethod("enter").invoke(scope); - } + private static void enter(Object scope) throws Exception { + scope.getClass().getMethod("enter").invoke(scope); + } - private static void seed(Object scope, Class type, Object instance) throws Exception { - scope.getClass().getMethod("seed", Class.class, Object.class).invoke(scope, type, instance); - } + private static void seed(Object scope, Class type, Object instance) throws Exception { + scope.getClass().getMethod("seed", Class.class, Object.class).invoke(scope, type, instance); + } - private static void exit(Object scope) throws Exception { - scope.getClass().getMethod("exit").invoke(scope); - } + private static void exit(Object scope) throws Exception { + scope.getClass().getMethod("exit").invoke(scope); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven325Runtime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven325Runtime.java index c7585df..ecae505 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven325Runtime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven325Runtime.java @@ -1,5 +1,13 @@ +/* + * Copyright (c) 2014-2024 Takari, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + */ package io.takari.maven.testing; +import com.google.inject.Module; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MojoExecutionEvent; import org.apache.maven.execution.MojoExecutionListener; @@ -9,43 +17,40 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.session.scope.internal.SessionScope; -import com.google.inject.Module; - class Maven325Runtime extends Maven321Runtime { - public Maven325Runtime(Module[] modules) throws Exception { - super(modules); - } - - @Override - public Mojo executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception { - SessionScope sessionScope = container.lookup(SessionScope.class); - try { - sessionScope.enter(); - sessionScope.seed(MavenSession.class, session); - - MojoExecutionScope executionScope = container.lookup(MojoExecutionScope.class); - try { - executionScope.enter(); - - executionScope.seed(MavenProject.class, project); - executionScope.seed(MojoExecution.class, execution); - - Mojo mojo = lookupConfiguredMojo(session, execution); - mojo.execute(); + public Maven325Runtime(Module[] modules) throws Exception { + super(modules); + } - MojoExecutionEvent event = new MojoExecutionEvent(session, project, execution, mojo); - for (MojoExecutionListener listener : container.lookupList(MojoExecutionListener.class)) { - listener.afterMojoExecutionSuccess(event); + @Override + public Mojo executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception { + SessionScope sessionScope = container.lookup(SessionScope.class); + try { + sessionScope.enter(); + sessionScope.seed(MavenSession.class, session); + + MojoExecutionScope executionScope = container.lookup(MojoExecutionScope.class); + try { + executionScope.enter(); + + executionScope.seed(MavenProject.class, project); + executionScope.seed(MojoExecution.class, execution); + + Mojo mojo = lookupConfiguredMojo(session, execution); + mojo.execute(); + + MojoExecutionEvent event = new MojoExecutionEvent(session, project, execution, mojo); + for (MojoExecutionListener listener : container.lookupList(MojoExecutionListener.class)) { + listener.afterMojoExecutionSuccess(event); + } + + return mojo; + } finally { + executionScope.exit(); + } + } finally { + sessionScope.exit(); } - - return mojo; - } finally { - executionScope.exit(); - } - } finally { - sessionScope.exit(); } - } - } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven331Runtime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven331Runtime.java index f5eb013..d77ae52 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven331Runtime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/Maven331Runtime.java @@ -1,7 +1,14 @@ +/* + * Copyright (c) 2014-2024 Takari, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + */ package io.takari.maven.testing; +import com.google.inject.Module; import java.io.File; - import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionResult; @@ -18,54 +25,52 @@ import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.eclipse.aether.RepositorySystemSession; -import com.google.inject.Module; - class Maven331Runtime extends Maven325Runtime { - public Maven331Runtime(Module[] modules) throws Exception { - super(modules); - } + public Maven331Runtime(Module[] modules) throws Exception { + super(modules); + } - @Override - public Mojo lookupConfiguredMojo(MavenSession session, MojoExecution execution) throws Exception { - MavenProject project = session.getCurrentProject(); - MojoDescriptor mojoDescriptor = execution.getMojoDescriptor(); + @Override + public Mojo lookupConfiguredMojo(MavenSession session, MojoExecution execution) throws Exception { + MavenProject project = session.getCurrentProject(); + MojoDescriptor mojoDescriptor = execution.getMojoDescriptor(); - Mojo mojo = container.lookup(Mojo.class, mojoDescriptor.getRoleHint()); + Mojo mojo = container.lookup(Mojo.class, mojoDescriptor.getRoleHint()); - ExpressionEvaluator evaluator = new PluginParameterExpressionEvaluator(session, execution); - mojoExecutionConfigurator(execution).configure(project, execution, true); - finalizeMojoConfiguration(execution); - PlexusConfiguration mojoConfiguration = new XmlPlexusConfiguration(execution.getConfiguration()); + ExpressionEvaluator evaluator = new PluginParameterExpressionEvaluator(session, execution); + mojoExecutionConfigurator(execution).configure(project, execution, true); + finalizeMojoConfiguration(execution); + PlexusConfiguration mojoConfiguration = new XmlPlexusConfiguration(execution.getConfiguration()); - String configuratorHint = "basic"; - if (mojoDescriptor.getComponentConfigurator() != null) { - configuratorHint = mojoDescriptor.getComponentConfigurator(); - } + String configuratorHint = "basic"; + if (mojoDescriptor.getComponentConfigurator() != null) { + configuratorHint = mojoDescriptor.getComponentConfigurator(); + } - ComponentConfigurator configurator = container.lookup(ComponentConfigurator.class, configuratorHint); + ComponentConfigurator configurator = container.lookup(ComponentConfigurator.class, configuratorHint); - configurator.configureComponent(mojo, mojoConfiguration, evaluator, container.getContainerRealm()); + configurator.configureComponent(mojo, mojoConfiguration, evaluator, container.getContainerRealm()); - return mojo; - } + return mojo; + } - private MojoExecutionConfigurator mojoExecutionConfigurator(MojoExecution mojoExecution) throws Exception { - String configuratorId = mojoExecution.getMojoDescriptor().getComponentConfigurator(); - if (configuratorId == null) { - configuratorId = "default"; + private MojoExecutionConfigurator mojoExecutionConfigurator(MojoExecution mojoExecution) throws Exception { + String configuratorId = mojoExecution.getMojoDescriptor().getComponentConfigurator(); + if (configuratorId == null) { + configuratorId = "default"; + } + return container.lookup(MojoExecutionConfigurator.class, configuratorId); } - return container.lookup(MojoExecutionConfigurator.class, configuratorId); - } - @SuppressWarnings("deprecation") - @Override - public MavenSession newMavenSession(File basedir) throws Exception { - MavenExecutionRequest request = newExecutionRequest(); - request.setMultiModuleProjectDirectory(basedir); - RepositorySystemSession repositorySession = newRepositorySession(request); + @SuppressWarnings("deprecation") + @Override + public MavenSession newMavenSession(File basedir) throws Exception { + MavenExecutionRequest request = newExecutionRequest(); + request.setMultiModuleProjectDirectory(basedir); + RepositorySystemSession repositorySession = newRepositorySession(request); - MavenExecutionResult result = new DefaultMavenExecutionResult(); - return new MavenSession(container, repositorySession, request, result); - } + MavenExecutionResult result = new DefaultMavenExecutionResult(); + return new MavenSession(container, repositorySession, request, result); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/MavenRuntime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/MavenRuntime.java index 83fb3bc..f28345e 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/MavenRuntime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/MavenRuntime.java @@ -1,7 +1,13 @@ +/* + * Copyright (c) 2014-2024 Takari, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + */ package io.takari.maven.testing; import java.io.File; - import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.Mojo; import org.apache.maven.plugin.MojoExecution; @@ -11,20 +17,19 @@ interface MavenRuntime { - void shutdown(); - - MavenProject readMavenProject(File basedir) throws Exception; + void shutdown(); - MavenSession newMavenSession(File baseir) throws Exception; + MavenProject readMavenProject(File basedir) throws Exception; - MojoExecution newMojoExecution(String goal); + MavenSession newMavenSession(File baseir) throws Exception; - Mojo executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception; + MojoExecution newMojoExecution(String goal); - Mojo lookupConfiguredMojo(MavenSession session, MojoExecution execution) throws Exception; + Mojo executeMojo(MavenSession session, MavenProject project, MojoExecution execution) throws Exception; - DefaultPlexusContainer getContainer(); + Mojo lookupConfiguredMojo(MavenSession session, MojoExecution execution) throws Exception; - T lookup(Class role) throws ComponentLookupException; + DefaultPlexusContainer getContainer(); + T lookup(Class role) throws ComponentLookupException; } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestMavenRuntime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestMavenRuntime.java index f9e111e..6efb47f 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestMavenRuntime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestMavenRuntime.java @@ -1,41 +1,39 @@ -/** - * Copyright (c) 2014-2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing; +import com.google.inject.Module; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; -import com.google.inject.Module; - public class TestMavenRuntime extends AbstractTestMavenRuntime implements TestRule { - public TestMavenRuntime() { - super(); - } - - public TestMavenRuntime(Module... modules) { - super(modules); - } + public TestMavenRuntime() { + super(); + } - @Override - public Statement apply(final Statement base, final Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - createMavenRuntime(); - try { - base.evaluate(); - } finally { - shutDownMavenRuntime(); - } - } - }; - } + public TestMavenRuntime(Module... modules) { + super(modules); + } + @Override + public Statement apply(final Statement base, final Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + createMavenRuntime(); + try { + base.evaluate(); + } finally { + shutDownMavenRuntime(); + } + } + }; + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestMavenRuntime5.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestMavenRuntime5.java index 758d7c2..4473f77 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestMavenRuntime5.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestMavenRuntime5.java @@ -1,41 +1,39 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing; +import com.google.inject.Module; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; -import com.google.inject.Module; - /** * Like {@link TestMavenRuntime} but for JUnit 5. - * + * * @author Philippe Marschall */ public class TestMavenRuntime5 extends AbstractTestMavenRuntime implements BeforeEachCallback, AfterEachCallback { - public TestMavenRuntime5() { - super(); - } - - public TestMavenRuntime5(Module... modules) { - super(modules); - } + public TestMavenRuntime5() { + super(); + } - @Override - public void beforeEach(ExtensionContext context) throws Exception { - createMavenRuntime(); - } + public TestMavenRuntime5(Module... modules) { + super(modules); + } - @Override - public void afterEach(ExtensionContext context) { - shutDownMavenRuntime(); - } + @Override + public void beforeEach(ExtensionContext context) throws Exception { + createMavenRuntime(); + } + @Override + public void afterEach(ExtensionContext context) { + shutDownMavenRuntime(); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestProperties.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestProperties.java index 5bfd898..9322196 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestProperties.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestProperties.java @@ -1,12 +1,13 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing; +import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -18,124 +19,122 @@ import java.util.Properties; import java.util.StringTokenizer; import java.util.TreeMap; - import org.junit.Assert; -import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; +public class TestProperties { + public static final String PROP_CLASSPATH = "classpath"; -public class TestProperties { + /** @deprecated use {@link #PROP_USER_SETTING_FILE} */ + public static final String PROP_USER_SETTING = "userSettings"; - public static final String PROP_CLASSPATH = "classpath"; + public static final String PROP_USER_SETTING_FILE = "userSettingsFile"; - /** @deprecated use {@link #PROP_USER_SETTING_FILE} */ - public static final String PROP_USER_SETTING = "userSettings"; + public static final String PROP_GLOBAL_SETTING_FILE = "globalSettingsFile"; - public static final String PROP_USER_SETTING_FILE = "userSettingsFile"; + public static final String PROP_LOCAL_REPOSITORY = "localRepository"; - public static final String PROP_GLOBAL_SETTING_FILE = "globalSettingsFile"; + public static final String PROP_OFFLINE = "offline"; - public static final String PROP_LOCAL_REPOSITORY = "localRepository"; + public static final String PROP_UPDATESNAPSHOTS = "updateSnapshots"; - public static final String PROP_OFFLINE = "offline"; + public static final String PROP_REPOSITORY = "repository."; - public static final String PROP_UPDATESNAPSHOTS = "updateSnapshots"; + private final Map properties; - public static final String PROP_REPOSITORY = "repository."; + public TestProperties() { + try { + this.properties = loadProperties(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } - private final Map properties; + protected Map loadProperties() throws IOException { + Properties p = new Properties(); + try (InputStream os = getClass().getClassLoader().getResourceAsStream("test.properties")) { + Assert.assertNotNull( + "test.properties must be present on test classpath, see https://github.com/takari/takari-plugin-testing-project/blob/master/testproperties.md for me details", + os); + p.load(os); + } + Map properties = new HashMap<>(); + for (String key : p.stringPropertyNames()) { + properties.put(key, p.getProperty(key)); + } + return Collections.unmodifiableMap(properties); + } - public TestProperties() { - try { - this.properties = loadProperties(); - } catch (IOException e) { - throw new RuntimeException(e); + public String get(String key) { + return properties.get(key); } - } - protected Map loadProperties() throws IOException { - Properties p = new Properties(); - try (InputStream os = getClass().getClassLoader().getResourceAsStream("test.properties")) { - Assert.assertNotNull("test.properties must be present on test classpath, see https://github.com/takari/takari-plugin-testing-project/blob/master/testproperties.md for me details", os); - p.load(os); + public File getUserSettings() { + // can be null + String path = properties.get(PROP_USER_SETTING_FILE); + if (path == null) { + path = properties.get(PROP_USER_SETTING); + } + if (path == null) { + return null; + } + File file = new File(path); + Assert.assertTrue("Can read user settings.xml", file.canRead()); + return file; } - Map properties = new HashMap<>(); - for (String key : p.stringPropertyNames()) { - properties.put(key, p.getProperty(key)); + + public File getGlobalSettings() { + // can be null + String path = properties.get(PROP_GLOBAL_SETTING_FILE); + if (path == null) { + return null; + } + File file = new File(path); + Assert.assertTrue("Can read global settings.xml", file.canRead()); + return file; } - return Collections.unmodifiableMap(properties); - } - - public String get(String key) { - return properties.get(key); - } - - public File getUserSettings() { - // can be null - String path = properties.get(PROP_USER_SETTING_FILE); - if (path == null) { - path = properties.get(PROP_USER_SETTING); + + public File getLocalRepository() { + String path = properties.get(PROP_LOCAL_REPOSITORY); + Assert.assertNotNull("Local repository specified", path); + return new File(path); } - if (path == null) { - return null; + + public boolean getOffline() { + String value = properties.get(PROP_OFFLINE); + return value != null ? Boolean.parseBoolean(value) : false; } - File file = new File(path); - Assert.assertTrue("Can read user settings.xml", file.canRead()); - return file; - } - - public File getGlobalSettings() { - // can be null - String path = properties.get(PROP_GLOBAL_SETTING_FILE); - if (path == null) { - return null; + + public boolean getUpdateSnapshots() { + String value = properties.get(PROP_UPDATESNAPSHOTS); + return value != null ? Boolean.parseBoolean(value) : false; } - File file = new File(path); - Assert.assertTrue("Can read global settings.xml", file.canRead()); - return file; - } - - public File getLocalRepository() { - String path = properties.get(PROP_LOCAL_REPOSITORY); - Assert.assertNotNull("Local repository specified", path); - return new File(path); - } - - public boolean getOffline() { - String value = properties.get(PROP_OFFLINE); - return value != null ? Boolean.parseBoolean(value) : false; - } - - public boolean getUpdateSnapshots() { - String value = properties.get(PROP_UPDATESNAPSHOTS); - return value != null ? Boolean.parseBoolean(value) : false; - } - - public String getPluginVersion() { - return properties.get("project.version"); - } - - /** - * Returns location of the current project classes, i.e. target/classes directory, and all project dependencies with scope=runtime. - *

      - * Useful for testing maven core extensions, {@link MavenRuntimeBuilder#withExtensions(java.util.Collection)} - */ - public List getRuntimeClasspath() { - StringTokenizer st = new StringTokenizer(properties.get(PROP_CLASSPATH), File.pathSeparator); - List dependencies = new ArrayList<>(); - while (st.hasMoreTokens()) { - dependencies.add(new File(st.nextToken())); + + public String getPluginVersion() { + return properties.get("project.version"); } - return dependencies; - } - - public List getRepositories() { - TreeMap repositories = new TreeMap<>(); - for (Map.Entry property : properties.entrySet()) { - if (property.getKey().startsWith(PROP_REPOSITORY)) { - repositories.put(property.getKey(), property.getValue()); - } + + /** + * Returns location of the current project classes, i.e. target/classes directory, and all project dependencies with scope=runtime. + *

      + * Useful for testing maven core extensions, {@link MavenRuntimeBuilder#withExtensions(java.util.Collection)} + */ + public List getRuntimeClasspath() { + StringTokenizer st = new StringTokenizer(properties.get(PROP_CLASSPATH), File.pathSeparator); + List dependencies = new ArrayList<>(); + while (st.hasMoreTokens()) { + dependencies.add(new File(st.nextToken())); + } + return dependencies; + } + + public List getRepositories() { + TreeMap repositories = new TreeMap<>(); + for (Map.Entry property : properties.entrySet()) { + if (property.getKey().startsWith(PROP_REPOSITORY)) { + repositories.put(property.getKey(), property.getValue()); + } + } + return new ArrayList<>(repositories.values()); } - return new ArrayList<>(repositories.values()); - } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestResources.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestResources.java index 662314b..9cca9db 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestResources.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestResources.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing; @@ -17,28 +17,27 @@ */ public class TestResources extends AbstractTestResources implements TestRule { - public TestResources() { - super(); - } - - public TestResources(String projectsDir, String workDir) { - super(projectsDir, workDir); - } + public TestResources() { + super(); + } - @Override - public Statement apply(Statement base, Description d) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - starting(d.getTestClass(), d.getMethodName()); - base.evaluate(); - } - }; - } + public TestResources(String projectsDir, String workDir) { + super(projectsDir, workDir); + } - @Override - String getRequiredAnnotationClassName() { - return "org.junit.Rule"; - } + @Override + public Statement apply(Statement base, Description d) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + starting(d.getTestClass(), d.getMethodName()); + base.evaluate(); + } + }; + } + @Override + String getRequiredAnnotationClassName() { + return "org.junit.Rule"; + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestResources5.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestResources5.java index 76b8269..8f97d26 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestResources5.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/TestResources5.java @@ -1,14 +1,13 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing; import java.lang.reflect.Method; - import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; @@ -17,23 +16,22 @@ */ public class TestResources5 extends AbstractTestResources implements BeforeEachCallback { - public TestResources5() { - super(); - } + public TestResources5() { + super(); + } - public TestResources5(String projectsDir, String workDir) { - super(projectsDir, workDir); - } + public TestResources5(String projectsDir, String workDir) { + super(projectsDir, workDir); + } - @Override - public void beforeEach(ExtensionContext context) throws Exception { - String methodName = context.getTestMethod().map(Method::getName).orElse(null); - starting(context.getRequiredTestClass(), methodName); - } - - @Override - String getRequiredAnnotationClassName() { - return "org.junit.jupiter.api.extension.RegisterExtension"; - } + @Override + public void beforeEach(ExtensionContext context) throws Exception { + String methodName = context.getTestMethod().map(Method::getName).orElse(null); + starting(context.getRequiredTestClass(), methodName); + } + @Override + String getRequiredAnnotationClassName() { + return "org.junit.jupiter.api.extension.RegisterExtension"; + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/Embedded3xLauncher.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/Embedded3xLauncher.java index a41e9a2..5cc309d 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/Embedded3xLauncher.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/Embedded3xLauncher.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; @@ -13,9 +13,9 @@ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under @@ -52,7 +52,6 @@ import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; - import org.codehaus.plexus.classworlds.ClassWorldException; import org.codehaus.plexus.classworlds.launcher.ConfigurationException; import org.codehaus.plexus.classworlds.launcher.ConfigurationHandler; @@ -60,373 +59,395 @@ import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; - /** * Launches an embedded Maven 3.x instance from some Maven installation directory. - * + * * @author Benjamin Bentmann */ class Embedded3xLauncher implements MavenLauncher { - private static class ClassworldsConfiguration implements ConfigurationHandler { + private static class ClassworldsConfiguration implements ConfigurationHandler { - private String mainType; - private String mainRealm; - private LinkedHashMap> realms = new LinkedHashMap<>(); - private List curEntries; + private String mainType; + private String mainRealm; + private LinkedHashMap> realms = new LinkedHashMap<>(); + private List curEntries; - @Override - public void setAppMain(String mainType, String mainRealm) { - this.mainType = mainType; - this.mainRealm = mainRealm; - } + @Override + public void setAppMain(String mainType, String mainRealm) { + this.mainType = mainType; + this.mainRealm = mainRealm; + } - @Override - public void addRealm(String realm) throws DuplicateRealmException { - if (!realms.containsKey(realm)) { - curEntries = new ArrayList<>(); - realms.put(realm, curEntries); - } - } + @Override + public void addRealm(String realm) throws DuplicateRealmException { + if (!realms.containsKey(realm)) { + curEntries = new ArrayList<>(); + realms.put(realm, curEntries); + } + } - @Override - public void addImportFrom(String relamName, String importSpec) throws NoSuchRealmException { - throw new UnsupportedOperationException(); - } + @Override + public void addImportFrom(String relamName, String importSpec) throws NoSuchRealmException { + throw new UnsupportedOperationException(); + } - @Override - public void addLoadFile(File file) { - if (curEntries == null) { - throw new IllegalStateException(); - } - curEntries.add(file.getAbsolutePath()); - } + @Override + public void addLoadFile(File file) { + if (curEntries == null) { + throw new IllegalStateException(); + } + curEntries.add(file.getAbsolutePath()); + } - public void addEntries(String realm, List locations) { - List entries = realms.get(realm); - if (entries == null) { - throw new IllegalStateException(); - } - entries.addAll(0, locations); - } + public void addEntries(String realm, List locations) { + List entries = realms.get(realm); + if (entries == null) { + throw new IllegalStateException(); + } + entries.addAll(0, locations); + } - @Override - public void addLoadURL(URL url) { - if (curEntries == null) { - throw new IllegalStateException(); - } - curEntries.add(url.toExternalForm()); - } + @Override + public void addLoadURL(URL url) { + if (curEntries == null) { + throw new IllegalStateException(); + } + curEntries.add(url.toExternalForm()); + } - public void store(OutputStream os) throws IOException { - BufferedWriter out = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); //$NON-NLS-1$ - out.write(String.format("main is %s from %s\n", mainType, mainRealm)); - for (Map.Entry> realm : realms.entrySet()) { - out.write(String.format("[%s]\n", realm.getKey())); - for (String entry : realm.getValue()) { - out.write(String.format("load %s\n", entry)); + public void store(OutputStream os) throws IOException { + BufferedWriter out = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); // $NON-NLS-1$ + out.write(String.format("main is %s from %s\n", mainType, mainRealm)); + for (Map.Entry> realm : realms.entrySet()) { + out.write(String.format("[%s]\n", realm.getKey())); + for (String entry : realm.getValue()) { + out.write(String.format("load %s\n", entry)); + } + } + out.flush(); } - } - out.flush(); } - } + private static class Key { + + private final File mavenHome; + private final File classworldConf; + private final List bootclasspath; + private final List extensions; + private final List args; + + public Key( + File mavenHome, + File classworldConf, + List bootclasspath, + List extensions, + List args) { + this.mavenHome = mavenHome; + this.classworldConf = classworldConf; + this.bootclasspath = clone(bootclasspath); + this.extensions = clone(extensions); + this.args = clone(args); + } - private static class Key { + @Override + public int hashCode() { + int hash = 17; + hash = hash * 31 + mavenHome.hashCode(); + hash = hash * 31 + (classworldConf != null ? classworldConf.hashCode() : 0); + hash = hash * 31 + (bootclasspath != null ? bootclasspath.hashCode() : 0); + hash = hash * 31 + (extensions != null ? extensions.hashCode() : 0); + hash = hash * 31 + (args != null ? args.hashCode() : 0); + return hash; + } - private final File mavenHome; - private final File classworldConf; - private final List bootclasspath; - private final List extensions; - private final List args; + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Key)) { + return false; + } + Key other = (Key) obj; + return eq(mavenHome, other.mavenHome) + && eq(classworldConf, other.classworldConf) + && eq(bootclasspath, other.bootclasspath) + && eq(extensions, other.extensions) + && eq(args, other.args); + } - public Key(File mavenHome, File classworldConf, List bootclasspath, List extensions, List args) { - this.mavenHome = mavenHome; - this.classworldConf = classworldConf; - this.bootclasspath = clone(bootclasspath); - this.extensions = clone(extensions); - this.args = clone(args); - } + private static List clone(List origin) { + return origin != null ? new ArrayList<>(origin) : null; + } - @Override - public int hashCode() { - int hash = 17; - hash = hash * 31 + mavenHome.hashCode(); - hash = hash * 31 + (classworldConf != null ? classworldConf.hashCode() : 0); - hash = hash * 31 + (bootclasspath != null ? bootclasspath.hashCode() : 0); - hash = hash * 31 + (extensions != null ? extensions.hashCode() : 0); - hash = hash * 31 + (args != null ? args.hashCode() : 0); - return hash; + private static boolean eq(T a, T b) { + return a != null ? a.equals(b) : b == null; + } } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof Key)) { - return false; - } - Key other = (Key) obj; - return eq(mavenHome, other.mavenHome) && eq(classworldConf, other.classworldConf) && eq(bootclasspath, other.bootclasspath) && eq(extensions, other.extensions) && eq(args, other.args); - } + private static final Map CACHE = new HashMap<>(); - private static List clone(List origin) { - return origin != null ? new ArrayList<>(origin) : null; - } + private final File mavenHome; - private static boolean eq(T a, T b) { - return a != null ? a.equals(b) : b == null; - } - } + private final Object classWorld; - private static final Map CACHE = new HashMap<>(); + private final Object mavenCli; - private final File mavenHome; + private final Method doMain; - private final Object classWorld; + private final List args; - private final Object mavenCli; + private Embedded3xLauncher(File mavenHome, Object classWorld, Object mavenCli, Method doMain, List args) { + this.mavenHome = mavenHome; + this.classWorld = classWorld; + this.mavenCli = mavenCli; + this.doMain = doMain; + this.args = args; + } - private final Method doMain; + /** + * Launches an embedded Maven 3.x instance from some Maven installation directory. + */ + public static Embedded3xLauncher createFromMavenHome( + File mavenHome, File classworldConf, List extensions, List args) throws LauncherException { + if (!isValidMavenHome(mavenHome)) { + throw new LauncherException("Invalid Maven home directory " + mavenHome); + } - private final List args; + List bootclasspath = toClasspath(System.getProperty("maven.bootclasspath")); + + Properties originalProperties = copy(System.getProperties()); + System.setProperty(SYSPROP_MAVEN_HOME, mavenHome.getAbsolutePath()); + + try { + final Key key = new Key(mavenHome, classworldConf, bootclasspath, extensions, args); + Embedded3xLauncher launcher = CACHE.get(key); + if (launcher == null) { + launcher = createFromMavenHome0(mavenHome, classworldConf, bootclasspath, extensions, args); + CACHE.put(key, launcher); + } + return launcher; + } finally { + System.setProperties(originalProperties); + } + } - private Embedded3xLauncher(File mavenHome, Object classWorld, Object mavenCli, Method doMain, List args) { - this.mavenHome = mavenHome; - this.classWorld = classWorld; - this.mavenCli = mavenCli; - this.doMain = doMain; - this.args = args; - } + private static boolean isValidMavenHome(File mavenHome) { + if (mavenHome == null) { + return false; + } - /** - * Launches an embedded Maven 3.x instance from some Maven installation directory. - */ - public static Embedded3xLauncher createFromMavenHome(File mavenHome, File classworldConf, List extensions, List args) throws LauncherException { - if (!isValidMavenHome(mavenHome)) { - throw new LauncherException("Invalid Maven home directory " + mavenHome); - } + if ("WORKSPACE".equals(mavenHome.getPath()) || "EMBEDDED".equals(mavenHome.getPath())) { + return true; + } - List bootclasspath = toClasspath(System.getProperty("maven.bootclasspath")); - - Properties originalProperties = copy(System.getProperties()); - System.setProperty(SYSPROP_MAVEN_HOME, mavenHome.getAbsolutePath()); - - try { - final Key key = new Key(mavenHome, classworldConf, bootclasspath, extensions, args); - Embedded3xLauncher launcher = CACHE.get(key); - if (launcher == null) { - launcher = createFromMavenHome0(mavenHome, classworldConf, bootclasspath, extensions, args); - CACHE.put(key, launcher); - } - return launcher; - } finally { - System.setProperties(originalProperties); + return mavenHome.isDirectory(); } - } - private static boolean isValidMavenHome(File mavenHome) { - if (mavenHome == null) { - return false; + private static List toClasspath(String string) throws LauncherException { + if (string == null) { + return null; + } + StringTokenizer st = new StringTokenizer(string, File.pathSeparator); + List classpath = new ArrayList<>(); + while (st.hasMoreTokens()) { + try { + classpath.add(new File(st.nextToken()).toURI().toURL()); + } catch (MalformedURLException e) { + throw new LauncherException("Invalid launcher classpath " + string, e); + } + } + return classpath; } - if ("WORKSPACE".equals(mavenHome.getPath()) || "EMBEDDED".equals(mavenHome.getPath())) { - return true; + private static Embedded3xLauncher createFromMavenHome0( + File mavenHome, File classworldConf, List bootclasspath, List extensions, List args) + throws LauncherException { + File configFile = MavenInstallationUtils.getClassworldsConf(mavenHome, classworldConf); + + ClassLoader bootLoader = getBootLoader(mavenHome, bootclasspath); + + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(bootLoader); + try { + ClassworldsConfiguration config = new ClassworldsConfiguration(); + ConfigurationParser configParser = new ConfigurationParser(config, System.getProperties()); + try (InputStream is = new BufferedInputStream(new FileInputStream(configFile))) { + configParser.parse(is); + } + if (extensions != null && !extensions.isEmpty()) { + config.addEntries("plexus.core", extensions); + } + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + config.store(buf); + + // Launcher launcher = new org.codehaus.plexus.classworlds.launcher.Launcher() + // launcher.configure(buf) + // ClassWorld classWorld = launcher.getWorld() + // MavenCli mavenCli = launcher.getMainClass().newInstance(classWorld) + + Class launcherClass = bootLoader.loadClass("org.codehaus.plexus.classworlds.launcher.Launcher"); + Object launcher = launcherClass.newInstance(); + launcherClass + .getMethod("configure", new Class[] {InputStream.class}) + .invoke(launcher, new ByteArrayInputStream(buf.toByteArray())); + Object classWorld = launcherClass.getMethod("getWorld").invoke(launcher); + + Class cliClass = + (Class) launcherClass.getMethod("getMainClass").invoke(launcher); + Object mavenCli = cliClass.getConstructor(classWorld.getClass()).newInstance(classWorld); + + Method doMain = cliClass.getMethod( + "doMain", // + String[].class, + String.class, + PrintStream.class, + PrintStream.class); + + return new Embedded3xLauncher(mavenHome, classWorld, mavenCli, doMain, args); + } catch (ReflectiveOperationException | IOException | ClassWorldException | ConfigurationException e) { + throw new LauncherException("Invalid Maven home directory " + mavenHome, e); + } finally { + Thread.currentThread().setContextClassLoader(oldClassLoader); + } } - return mavenHome.isDirectory(); - } + private static ClassLoader getBootLoader(File mavenHome, List classpath) { + List urls = classpath; - private static List toClasspath(String string) throws LauncherException { - if (string == null) { - return null; - } - StringTokenizer st = new StringTokenizer(string, File.pathSeparator); - List classpath = new ArrayList<>(); - while (st.hasMoreTokens()) { - try { - classpath.add(new File(st.nextToken()).toURI().toURL()); - } catch (MalformedURLException e) { - throw new LauncherException("Invalid launcher classpath " + string, e); - } - } - return classpath; - } - - private static Embedded3xLauncher createFromMavenHome0(File mavenHome, File classworldConf, List bootclasspath, List extensions, List args) throws LauncherException { - File configFile = MavenInstallationUtils.getClassworldsConf(mavenHome, classworldConf); - - ClassLoader bootLoader = getBootLoader(mavenHome, bootclasspath); - - ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(bootLoader); - try { - ClassworldsConfiguration config = new ClassworldsConfiguration(); - ConfigurationParser configParser = new ConfigurationParser(config, System.getProperties()); - try (InputStream is = new BufferedInputStream(new FileInputStream(configFile))) { - configParser.parse(is); - } - if (extensions != null && !extensions.isEmpty()) { - config.addEntries("plexus.core", extensions); - } - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - config.store(buf); - - // Launcher launcher = new org.codehaus.plexus.classworlds.launcher.Launcher() - // launcher.configure(buf) - // ClassWorld classWorld = launcher.getWorld() - // MavenCli mavenCli = launcher.getMainClass().newInstance(classWorld) - - Class launcherClass = bootLoader.loadClass("org.codehaus.plexus.classworlds.launcher.Launcher"); - Object launcher = launcherClass.newInstance(); - launcherClass.getMethod("configure", new Class[] {InputStream.class}).invoke(launcher, new ByteArrayInputStream(buf.toByteArray())); - Object classWorld = launcherClass.getMethod("getWorld").invoke(launcher); - - Class cliClass = (Class) launcherClass.getMethod("getMainClass").invoke(launcher); - Object mavenCli = cliClass.getConstructor(classWorld.getClass()).newInstance(classWorld); - - Method doMain = cliClass.getMethod("doMain", // - String[].class, String.class, PrintStream.class, PrintStream.class); - - return new Embedded3xLauncher(mavenHome, classWorld, mavenCli, doMain, args); - } catch (ReflectiveOperationException | IOException | ClassWorldException | ConfigurationException e) { - throw new LauncherException("Invalid Maven home directory " + mavenHome, e); - } finally { - Thread.currentThread().setContextClassLoader(oldClassLoader); - } - } + if (urls == null) { + urls = new ArrayList(); - private static ClassLoader getBootLoader(File mavenHome, List classpath) { - List urls = classpath; + File bootDir = new File(mavenHome, "boot"); + addUrls(urls, bootDir); + } - if (urls == null) { - urls = new ArrayList(); + if (urls.isEmpty()) { + throw new IllegalArgumentException("Invalid Maven home directory " + mavenHome); + } - File bootDir = new File(mavenHome, "boot"); - addUrls(urls, bootDir); - } + URL[] ucp = urls.toArray(new URL[urls.size()]); - if (urls.isEmpty()) { - throw new IllegalArgumentException("Invalid Maven home directory " + mavenHome); + return new URLClassLoader(ucp, ClassLoader.getSystemClassLoader().getParent()); } - URL[] ucp = urls.toArray(new URL[urls.size()]); - - return new URLClassLoader(ucp, ClassLoader.getSystemClassLoader().getParent()); - } - - private static void addUrls(List urls, File directory) { - File[] jars = directory.listFiles(); - - if (jars != null) { - for (int i = 0; i < jars.length; i++) { - File jar = jars[i]; - - if (jar.getName().endsWith(".jar")) { - try { - urls.add(jar.toURI().toURL()); - } catch (MalformedURLException e) { - throw (RuntimeException) new IllegalStateException().initCause(e); - } + private static void addUrls(List urls, File directory) { + File[] jars = directory.listFiles(); + + if (jars != null) { + for (int i = 0; i < jars.length; i++) { + File jar = jars[i]; + + if (jar.getName().endsWith(".jar")) { + try { + urls.add(jar.toURI().toURL()); + } catch (MalformedURLException e) { + throw (RuntimeException) new IllegalStateException().initCause(e); + } + } + } } - } } - } - - @Override - public int run(String[] cliArgs, File multiModuleProjectDirectory, File workingDirectory, File logFile) throws IOException, LauncherException { - PrintStream out = (logFile != null) ? new PrintStream(new FileOutputStream(logFile)) : System.out; - try { - Properties originalProperties = copy(System.getProperties()); - System.setProperties(null); - System.setProperty(SYSPROP_MAVEN_HOME, mavenHome.getAbsolutePath()); - System.setProperty("user.dir", workingDirectory.getAbsolutePath()); - System.setProperty("maven.multiModuleProjectDirectory", multiModuleProjectDirectory.getAbsolutePath()); - - ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(mavenCli.getClass().getClassLoader()); - try { - Set origRealms = getRealmIds(); - - List args = new ArrayList<>(this.args); - args.addAll(Arrays.asList(cliArgs)); - - out.format("Maven Executor implementation: %s\n", getClass().getName()); - out.format("Maven home: %s\n", mavenHome); - out.format("Build work directory: %s\n", workingDirectory); - out.format("Execution parameters: %s\n\n", args); - - Object result = doMain.invoke(mavenCli, // - args.toArray(new String[args.size()]), workingDirectory.getAbsolutePath(), out, out); - - Set realms = getRealmIds(); - realms.removeAll(origRealms); - for (String realmId : realms) { - disposeRealm(realmId); - } - return ((Number) result).intValue(); - } finally { - Thread.currentThread().setContextClassLoader(originalClassLoader); - - System.setProperties(originalProperties); - } - } catch (IllegalAccessException e) { - throw new LauncherException("Failed to run Maven: " + e.getMessage(), e); - } catch (InvocationTargetException e) { - throw new LauncherException("Failed to run Maven: " + e.getMessage(), e); - } finally { - if (logFile != null) { - out.close(); - } + @Override + public int run(String[] cliArgs, File multiModuleProjectDirectory, File workingDirectory, File logFile) + throws IOException, LauncherException { + PrintStream out = (logFile != null) ? new PrintStream(new FileOutputStream(logFile)) : System.out; + try { + Properties originalProperties = copy(System.getProperties()); + System.setProperties(null); + System.setProperty(SYSPROP_MAVEN_HOME, mavenHome.getAbsolutePath()); + System.setProperty("user.dir", workingDirectory.getAbsolutePath()); + System.setProperty("maven.multiModuleProjectDirectory", multiModuleProjectDirectory.getAbsolutePath()); + + ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(mavenCli.getClass().getClassLoader()); + try { + Set origRealms = getRealmIds(); + + List args = new ArrayList<>(this.args); + args.addAll(Arrays.asList(cliArgs)); + + out.format("Maven Executor implementation: %s\n", getClass().getName()); + out.format("Maven home: %s\n", mavenHome); + out.format("Build work directory: %s\n", workingDirectory); + out.format("Execution parameters: %s\n\n", args); + + Object result = doMain.invoke( + mavenCli, // + args.toArray(new String[args.size()]), + workingDirectory.getAbsolutePath(), + out, + out); + + Set realms = getRealmIds(); + realms.removeAll(origRealms); + for (String realmId : realms) { + disposeRealm(realmId); + } + + return ((Number) result).intValue(); + } finally { + Thread.currentThread().setContextClassLoader(originalClassLoader); + + System.setProperties(originalProperties); + } + } catch (IllegalAccessException e) { + throw new LauncherException("Failed to run Maven: " + e.getMessage(), e); + } catch (InvocationTargetException e) { + throw new LauncherException("Failed to run Maven: " + e.getMessage(), e); + } finally { + if (logFile != null) { + out.close(); + } + } } - } - private static Properties copy(Properties properties) { - Properties copy = new Properties(); - for (String key : properties.stringPropertyNames()) { - copy.put(key, properties.getProperty(key)); - } - return copy; - } - - @Override - public String getMavenVersion() throws LauncherException { - try { - String version = MavenInstallationUtils.getMavenVersion(mavenCli.getClass()); - if (version != null) { - return version; - } - } catch (IOException e) { - throw new LauncherException("Failed to read Maven version", e); + private static Properties copy(Properties properties) { + Properties copy = new Properties(); + for (String key : properties.stringPropertyNames()) { + copy.put(key, properties.getProperty(key)); + } + return copy; } - throw new LauncherException("Could not determine embedded Maven version"); - } - - private Set getRealmIds() { - Set result = new HashSet<>(); + @Override + public String getMavenVersion() throws LauncherException { + try { + String version = MavenInstallationUtils.getMavenVersion(mavenCli.getClass()); + if (version != null) { + return version; + } + } catch (IOException e) { + throw new LauncherException("Failed to read Maven version", e); + } - try { - Collection realms = (Collection) classWorld.getClass().getMethod("getRealms").invoke(classWorld); - for (Object realm : realms) { - String id = (String) realm.getClass().getMethod("getId").invoke(realm); - result.add(id); - } - } catch (RuntimeException | ReflectiveOperationException e) { - // best-effort, silently ignore failures + throw new LauncherException("Could not determine embedded Maven version"); } - return result; - } + private Set getRealmIds() { + Set result = new HashSet<>(); + + try { + Collection realms = + (Collection) classWorld.getClass().getMethod("getRealms").invoke(classWorld); + for (Object realm : realms) { + String id = (String) realm.getClass().getMethod("getId").invoke(realm); + result.add(id); + } + } catch (RuntimeException | ReflectiveOperationException e) { + // best-effort, silently ignore failures + } - private void disposeRealm(String id) { - try { - classWorld.getClass().getMethod("disposeRealm", String.class).invoke(classWorld, id); - } catch (RuntimeException | ReflectiveOperationException e) { - // best-effort, silently ignore failures + return result; } - } + private void disposeRealm(String id) { + try { + classWorld.getClass().getMethod("disposeRealm", String.class).invoke(classWorld, id); + } catch (RuntimeException | ReflectiveOperationException e) { + // best-effort, silently ignore failures + } + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/ForkedLauncher.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/ForkedLauncher.java index 5e48582..715acea 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/ForkedLauncher.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/ForkedLauncher.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; @@ -13,9 +13,9 @@ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under @@ -36,7 +36,6 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteException; @@ -49,175 +48,188 @@ */ class ForkedLauncher implements MavenLauncher { - private final File mavenHome; + private final File mavenHome; - private final File classworldsJar; + private final File classworldsJar; - private final Map envVars; + private final Map envVars; - private final List extensions; + private final List extensions; - private final List args; + private final List args; - private final List jvmArgs; + private final List jvmArgs; - public ForkedLauncher(File mavenHome, File classworldsConf, List extensions, Map envVars, List args, List jvmArgs) { - this.args = args; - this.jvmArgs = jvmArgs; - if (mavenHome == null) { - throw new NullPointerException(); - } - if (classworldsConf != null) { - throw new IllegalArgumentException("Custom classworlds configuration file is not supported"); - } + public ForkedLauncher( + File mavenHome, + File classworldsConf, + List extensions, + Map envVars, + List args, + List jvmArgs) { + this.args = args; + this.jvmArgs = jvmArgs; + if (mavenHome == null) { + throw new NullPointerException(); + } + if (classworldsConf != null) { + throw new IllegalArgumentException("Custom classworlds configuration file is not supported"); + } - this.mavenHome = mavenHome; - this.envVars = envVars; - this.extensions = extensions; - - File classworldsJar = null; - File[] files = new File(mavenHome, "boot").listFiles(); - if (files != null) { - for (File file : files) { - String name = file.getName(); - if (name.startsWith("plexus-classworlds-") && name.endsWith(".jar")) { - classworldsJar = file; - break; + this.mavenHome = mavenHome; + this.envVars = envVars; + this.extensions = extensions; + + File classworldsJar = null; + File[] files = new File(mavenHome, "boot").listFiles(); + if (files != null) { + for (File file : files) { + String name = file.getName(); + if (name.startsWith("plexus-classworlds-") && name.endsWith(".jar")) { + classworldsJar = file; + break; + } + } } - } - } - if (classworldsJar == null) { - throw new IllegalArgumentException("Invalid maven home " + mavenHome); - } - this.classworldsJar = classworldsJar; - } - - public int run(String[] cliArgs, Map envVars, File multiModuleProjectDirectory, File workingDirectory, File logFile) throws IOException, LauncherException { - String javaHome; - if (envVars == null || envVars.get("JAVA_HOME") == null) { - javaHome = System.getProperty("java.home"); - } else { - javaHome = envVars.get("JAVA_HOME"); + if (classworldsJar == null) { + throw new IllegalArgumentException("Invalid maven home " + mavenHome); + } + this.classworldsJar = classworldsJar; } - File executable = new File(javaHome, Os.isFamily(Os.FAMILY_WINDOWS) ? "bin/javaw.exe" : "bin/java"); + public int run( + String[] cliArgs, + Map envVars, + File multiModuleProjectDirectory, + File workingDirectory, + File logFile) + throws IOException, LauncherException { + String javaHome; + if (envVars == null || envVars.get("JAVA_HOME") == null) { + javaHome = System.getProperty("java.home"); + } else { + javaHome = envVars.get("JAVA_HOME"); + } - CommandLine cli = new CommandLine(executable); - cli.addArgument("-classpath").addArgument(classworldsJar.getAbsolutePath()); - cli.addArgument("-Dclassworlds.conf=" + new File(mavenHome, "bin/m2.conf").getAbsolutePath()); - cli.addArgument("-Dmaven.home=" + mavenHome.getAbsolutePath()); - cli.addArgument("-Dmaven.multiModuleProjectDirectory=" + multiModuleProjectDirectory.getAbsolutePath()); + File executable = new File(javaHome, Os.isFamily(Os.FAMILY_WINDOWS) ? "bin/javaw.exe" : "bin/java"); - cli.addArguments(jvmArgs.toArray(new String[jvmArgs.size()])); + CommandLine cli = new CommandLine(executable); + cli.addArgument("-classpath").addArgument(classworldsJar.getAbsolutePath()); + cli.addArgument("-Dclassworlds.conf=" + new File(mavenHome, "bin/m2.conf").getAbsolutePath()); + cli.addArgument("-Dmaven.home=" + mavenHome.getAbsolutePath()); + cli.addArgument("-Dmaven.multiModuleProjectDirectory=" + multiModuleProjectDirectory.getAbsolutePath()); - cli.addArgument("org.codehaus.plexus.classworlds.launcher.Launcher"); + cli.addArguments(jvmArgs.toArray(new String[jvmArgs.size()])); - cli.addArguments(args.toArray(new String[args.size()])); - if (extensions != null && !extensions.isEmpty()) { - cli.addArgument("-Dmaven.ext.class.path=" + toPath(extensions)); - } + cli.addArgument("org.codehaus.plexus.classworlds.launcher.Launcher"); - cli.addArguments(cliArgs); + cli.addArguments(args.toArray(new String[args.size()])); + if (extensions != null && !extensions.isEmpty()) { + cli.addArgument("-Dmaven.ext.class.path=" + toPath(extensions)); + } - Map env = new HashMap<>(); - if (mavenHome != null) { - env.put("M2_HOME", mavenHome.getAbsolutePath()); - } - if (envVars != null) { - env.putAll(envVars); - } - if (envVars == null || envVars.get("JAVA_HOME") == null) { - env.put("JAVA_HOME", System.getProperty("java.home")); - } + cli.addArguments(cliArgs); - DefaultExecutor executor = new DefaultExecutor(); - executor.setProcessDestroyer(new ShutdownHookProcessDestroyer()); - executor.setWorkingDirectory(workingDirectory.getAbsoluteFile()); - - try (OutputStream log = new FileOutputStream(logFile)) { - PrintStream out = new PrintStream(log); - out.format("Maven Executor implementation: %s\n", getClass().getName()); - out.format("Maven home: %s\n", mavenHome); - out.format("Build work directory: %s\n", workingDirectory); - out.format("Environment: %s\n", env); - out.format("Command line: %s\n\n", cli.toString()); - out.flush(); - - PumpStreamHandler streamHandler = new PumpStreamHandler(log); - executor.setStreamHandler(streamHandler); - return executor.execute(cli, env); // this throws ExecuteException if process return code != 0 - } catch (ExecuteException e) { - throw new LauncherException("Failed to run Maven: " + e.getMessage() + "\n" + cli, e); + Map env = new HashMap<>(); + if (mavenHome != null) { + env.put("M2_HOME", mavenHome.getAbsolutePath()); + } + if (envVars != null) { + env.putAll(envVars); + } + if (envVars == null || envVars.get("JAVA_HOME") == null) { + env.put("JAVA_HOME", System.getProperty("java.home")); + } + + DefaultExecutor executor = new DefaultExecutor(); + executor.setProcessDestroyer(new ShutdownHookProcessDestroyer()); + executor.setWorkingDirectory(workingDirectory.getAbsoluteFile()); + + try (OutputStream log = new FileOutputStream(logFile)) { + PrintStream out = new PrintStream(log); + out.format("Maven Executor implementation: %s\n", getClass().getName()); + out.format("Maven home: %s\n", mavenHome); + out.format("Build work directory: %s\n", workingDirectory); + out.format("Environment: %s\n", env); + out.format("Command line: %s\n\n", cli.toString()); + out.flush(); + + PumpStreamHandler streamHandler = new PumpStreamHandler(log); + executor.setStreamHandler(streamHandler); + return executor.execute(cli, env); // this throws ExecuteException if process return code != 0 + } catch (ExecuteException e) { + throw new LauncherException("Failed to run Maven: " + e.getMessage() + "\n" + cli, e); + } } - } - - private static String toPath(List strings) { - StringBuilder sb = new StringBuilder(); - for (String string : strings) { - if (sb.length() > 0) { - sb.append(File.pathSeparatorChar); - } - sb.append(string); + + private static String toPath(List strings) { + StringBuilder sb = new StringBuilder(); + for (String string : strings) { + if (sb.length() > 0) { + sb.append(File.pathSeparatorChar); + } + sb.append(string); + } + return sb.toString(); } - return sb.toString(); - } - - @Override - public int run(String[] cliArgs, File multiModuleProjectDirectory, File workingDirectory, File logFile) throws IOException, LauncherException { - return run(cliArgs, envVars, multiModuleProjectDirectory, workingDirectory, logFile); - } - - @Override - public String getMavenVersion() throws IOException, LauncherException { - // TODO cleanup, there is no need to write log file, for example - - File logFile; - try { - logFile = File.createTempFile("maven", "log"); - } catch (IOException e) { - throw new LauncherException("Error creating temp file", e); + + @Override + public int run(String[] cliArgs, File multiModuleProjectDirectory, File workingDirectory, File logFile) + throws IOException, LauncherException { + return run(cliArgs, envVars, multiModuleProjectDirectory, workingDirectory, logFile); } - // disable EMMA runtime controller port allocation, should be harmless if EMMA is not used - Map envVars = Collections.singletonMap("MAVEN_OPTS", "-Demma.rt.control=false"); - run(new String[] {"--version"}, envVars, new File(""), new File(""), logFile); + @Override + public String getMavenVersion() throws IOException, LauncherException { + // TODO cleanup, there is no need to write log file, for example + + File logFile; + try { + logFile = File.createTempFile("maven", "log"); + } catch (IOException e) { + throw new LauncherException("Error creating temp file", e); + } - List logLines = Files.readAllLines(logFile.toPath(), Charset.defaultCharset()); - // noinspection ResultOfMethodCallIgnored - logFile.delete(); + // disable EMMA runtime controller port allocation, should be harmless if EMMA is not used + Map envVars = Collections.singletonMap("MAVEN_OPTS", "-Demma.rt.control=false"); + run(new String[] {"--version"}, envVars, new File(""), new File(""), logFile); - String version = extractMavenVersion(logLines); + List logLines = Files.readAllLines(logFile.toPath(), Charset.defaultCharset()); + // noinspection ResultOfMethodCallIgnored + logFile.delete(); - if (version == null) { - throw new LauncherException("Illegal Maven output: String 'Maven' not found in the following output:\n" + join(logLines, "\n")); - } else { - return version; - } - } + String version = extractMavenVersion(logLines); - private String join(List lines, String eol) { - StringBuilder sb = new StringBuilder(); - for (String line : lines) { - sb.append(line).append(eol); + if (version == null) { + throw new LauncherException( + "Illegal Maven output: String 'Maven' not found in the following output:\n" + join(logLines, "\n")); + } else { + return version; + } } - return sb.toString(); - } - static String extractMavenVersion(List logLines) { - String version = null; + private String join(List lines, String eol) { + StringBuilder sb = new StringBuilder(); + for (String line : lines) { + sb.append(line).append(eol); + } + return sb.toString(); + } - final Pattern mavenVersion = Pattern.compile("(?i).*Maven.*? ([0-9]\\.\\S*).*"); + static String extractMavenVersion(List logLines) { + String version = null; - for (Iterator it = logLines.iterator(); version == null && it.hasNext();) { - String line = it.next(); + final Pattern mavenVersion = Pattern.compile("(?i).*Maven.*? ([0-9]\\.\\S*).*"); - Matcher m = mavenVersion.matcher(line); - if (m.matches()) { - version = m.group(1); - } - } + for (Iterator it = logLines.iterator(); version == null && it.hasNext(); ) { + String line = it.next(); - return version; - } + Matcher m = mavenVersion.matcher(line); + if (m.matches()) { + version = m.group(1); + } + } + return version; + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/LauncherException.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/LauncherException.java index c81566e..8b2fae7 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/LauncherException.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/LauncherException.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; @@ -13,9 +13,9 @@ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under @@ -28,12 +28,11 @@ @SuppressWarnings("serial") class LauncherException extends Exception { - public LauncherException(String message) { - super(message); - } - - public LauncherException(String message, Throwable cause) { - super(message, cause); - } + public LauncherException(String message) { + super(message); + } + public LauncherException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenExecution.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenExecution.java index 1c14b4a..05d1709 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenExecution.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenExecution.java @@ -1,93 +1,95 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; +import io.takari.maven.testing.TestProperties; import java.io.File; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; -import io.takari.maven.testing.TestProperties; - public class MavenExecution { - private final MavenLauncher launcher; - - private final TestProperties properties; - - private final File multiModuleProjectDirectory; + private final MavenLauncher launcher; - private final File basedir; + private final TestProperties properties; - private final List cliOptions = new ArrayList<>(); + private final File multiModuleProjectDirectory; - MavenExecution(MavenLauncher launcher, TestProperties properties, File multiModuleProjectDirectory, String moduleRelpath) { - this.launcher = launcher; - this.properties = properties; - this.multiModuleProjectDirectory = multiModuleProjectDirectory; - this.basedir = moduleRelpath != null ? new File(multiModuleProjectDirectory, moduleRelpath) : multiModuleProjectDirectory; - } + private final File basedir; - public MavenExecutionResult execute(String... goals) throws Exception { - File logFile = new File(basedir, "log.txt"); + private final List cliOptions = new ArrayList<>(); - List args = new ArrayList<>(); - - File userSettings = properties.getUserSettings(); - if (userSettings != null && userSettings.isFile() && !isOption(cliOptions, "-s", true)) { - args.add("-s"); - args.add(userSettings.getAbsolutePath()); - } - if (!isOption(cliOptions, "-Dmaven.repo.local=", false)) { - args.add("-Dmaven.repo.local=" + properties.getLocalRepository().getAbsolutePath()); + MavenExecution( + MavenLauncher launcher, TestProperties properties, File multiModuleProjectDirectory, String moduleRelpath) { + this.launcher = launcher; + this.properties = properties; + this.multiModuleProjectDirectory = multiModuleProjectDirectory; + this.basedir = moduleRelpath != null + ? new File(multiModuleProjectDirectory, moduleRelpath) + : multiModuleProjectDirectory; } - args.add("-Dit-plugin.version=" + properties.getPluginVersion()); // TODO deprecated and remove - args.add("-Dit-project.version=" + properties.getPluginVersion()); - args.addAll(cliOptions); - for (String goal : goals) { - args.add(goal); + public MavenExecutionResult execute(String... goals) throws Exception { + File logFile = new File(basedir, "log.txt"); + + List args = new ArrayList<>(); + + File userSettings = properties.getUserSettings(); + if (userSettings != null && userSettings.isFile() && !isOption(cliOptions, "-s", true)) { + args.add("-s"); + args.add(userSettings.getAbsolutePath()); + } + if (!isOption(cliOptions, "-Dmaven.repo.local=", false)) { + args.add("-Dmaven.repo.local=" + properties.getLocalRepository().getAbsolutePath()); + } + args.add("-Dit-plugin.version=" + properties.getPluginVersion()); // TODO deprecated and remove + args.add("-Dit-project.version=" + properties.getPluginVersion()); + args.addAll(cliOptions); + + for (String goal : goals) { + args.add(goal); + } + + try { + launcher.run(args.toArray(new String[args.size()]), multiModuleProjectDirectory, basedir, logFile); + } catch (Exception e) { + String ciEnvar = System.getenv("CONTINUOUS_INTEGRATION"); + if (ciEnvar != null && ciEnvar.equalsIgnoreCase("true")) { + String logFileContent = new String(Files.readAllBytes(logFile.toPath())); + System.out.println(logFileContent); + } + throw e; + } + + return new MavenExecutionResult(basedir, logFile); } - try { - launcher.run(args.toArray(new String[args.size()]), multiModuleProjectDirectory, basedir, logFile); - } catch(Exception e) { - String ciEnvar = System.getenv("CONTINUOUS_INTEGRATION"); - if(ciEnvar != null && ciEnvar.equalsIgnoreCase("true")) { - String logFileContent = new String(Files.readAllBytes(logFile.toPath())); - System.out.println(logFileContent); - } - throw e; + private boolean isOption(List args, String str, boolean exact) { + for (String arg : args) { + if (exact && str.equals(arg)) { + return true; + } else if (!exact && arg.startsWith(str)) { + return true; + } + } + return false; } - return new MavenExecutionResult(basedir, logFile); - } - - private boolean isOption(List args, String str, boolean exact) { - for (String arg : args) { - if (exact && str.equals(arg)) { - return true; - } else if (!exact && arg.startsWith(str)) { - return true; - } + public MavenExecution withCliOption(String string) { + cliOptions.add(string); + return this; } - return false; - } - - public MavenExecution withCliOption(String string) { - cliOptions.add(string); - return this; - } - public MavenExecution withCliOptions(String... strings) { - for (String string : strings) { - cliOptions.add(string); + public MavenExecution withCliOptions(String... strings) { + for (String string : strings) { + cliOptions.add(string); + } + return this; } - return this; - } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenExecutionResult.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenExecutionResult.java index 87a13db..587915b 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenExecutionResult.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenExecutionResult.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; @@ -14,64 +14,63 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; - import org.junit.Assert; // wraps maven invocation results public class MavenExecutionResult { - private final File basedir; - private final List log; + private final File basedir; + private final List log; - MavenExecutionResult(File basedir, File logFile) throws IOException { - this.basedir = basedir; - List log = new ArrayList<>(); - if (logFile.canRead()) { - for (String line : Files.readAllLines(logFile.toPath(), Charset.defaultCharset())) { - log.add(line); - } + MavenExecutionResult(File basedir, File logFile) throws IOException { + this.basedir = basedir; + List log = new ArrayList<>(); + if (logFile.canRead()) { + for (String line : Files.readAllLines(logFile.toPath(), Charset.defaultCharset())) { + log.add(line); + } + } + this.log = Collections.unmodifiableList(log); } - this.log = Collections.unmodifiableList(log); - } - public MavenExecutionResult assertErrorFreeLog() throws Exception { - List errors = new ArrayList<>(); - for (String line : log) { - if (line.contains("[ERROR]")) { - errors.add(line); - } + public MavenExecutionResult assertErrorFreeLog() throws Exception { + List errors = new ArrayList<>(); + for (String line : log) { + if (line.contains("[ERROR]")) { + errors.add(line); + } + } + Assert.assertTrue(errors.toString(), errors.isEmpty()); + return this; } - Assert.assertTrue(errors.toString(), errors.isEmpty()); - return this; - } - public MavenExecutionResult assertLogText(String text) { - for (String line : log) { - if (line.contains(text)) { + public MavenExecutionResult assertLogText(String text) { + for (String line : log) { + if (line.contains(text)) { + return this; + } + } + Assert.fail("Log line not present: " + text); return this; - } } - Assert.fail("Log line not present: " + text); - return this; - } - public MavenExecutionResult assertNoLogText(String text) { - for (String line : log) { - if (line.contains(text)) { - Assert.fail("Log line present: " + text); - } + public MavenExecutionResult assertNoLogText(String text) { + for (String line : log) { + if (line.contains(text)) { + Assert.fail("Log line present: " + text); + } + } + return this; } - return this; - } - public File getBasedir() { - return basedir; - } + public File getBasedir() { + return basedir; + } - /** - * @since 2.9.2 - */ - public List getLog() { - return log; - } + /** + * @since 2.9.2 + */ + public List getLog() { + return log; + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenInstallationUtils.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenInstallationUtils.java index 2210dd8..16d2846 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenInstallationUtils.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenInstallationUtils.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; @@ -16,7 +16,6 @@ import java.util.Properties; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; - import org.codehaus.plexus.classworlds.ClassWorldException; import org.codehaus.plexus.classworlds.launcher.ConfigurationException; import org.codehaus.plexus.classworlds.launcher.ConfigurationHandler; @@ -26,123 +25,125 @@ public class MavenInstallationUtils { - public static final String MAVEN_CORE_POMPROPERTIES = "META-INF/maven/org.apache.maven/maven-core/pom.properties"; + public static final String MAVEN_CORE_POMPROPERTIES = "META-INF/maven/org.apache.maven/maven-core/pom.properties"; - public static final String SYSPROP_MAVEN_HOME = "maven.home"; + public static final String SYSPROP_MAVEN_HOME = "maven.home"; - public static final String SYSPROP_CLASSWORLDSCONF = "classworlds.conf"; + public static final String SYSPROP_CLASSWORLDSCONF = "classworlds.conf"; - public static String getMavenVersion(Class clazz) throws IOException { - try (InputStream is = clazz.getResourceAsStream("/" + MAVEN_CORE_POMPROPERTIES)) { - return getMavenVersion(is); + public static String getMavenVersion(Class clazz) throws IOException { + try (InputStream is = clazz.getResourceAsStream("/" + MAVEN_CORE_POMPROPERTIES)) { + return getMavenVersion(is); + } } - } - public static String getMavenVersion(InputStream is) throws IOException { - Properties props = new Properties(); - if (is != null) { - props.load(is); + public static String getMavenVersion(InputStream is) throws IOException { + Properties props = new Properties(); + if (is != null) { + props.load(is); + } + return props.getProperty("version"); } - return props.getProperty("version"); - } - public static String getMavenVersion(File mavenHome, File classworldsConf) { - classworldsConf = getClassworldsConf(mavenHome, classworldsConf); - - @SuppressWarnings("serial") - class MavenVersionFoundException extends RuntimeException { - public final String version; - - MavenVersionFoundException(String version) { - this.version = version; - } - } + public static String getMavenVersion(File mavenHome, File classworldsConf) { + classworldsConf = getClassworldsConf(mavenHome, classworldsConf); - class VersionConfigHandler implements ConfigurationHandler { + @SuppressWarnings("serial") + class MavenVersionFoundException extends RuntimeException { + public final String version; - @Override - public void setAppMain(String mainClassName, String mainRealmName) {} + MavenVersionFoundException(String version) { + this.version = version; + } + } - @Override - public void addRealm(String realmName) throws DuplicateRealmException {} + class VersionConfigHandler implements ConfigurationHandler { + + @Override + public void setAppMain(String mainClassName, String mainRealmName) {} + + @Override + public void addRealm(String realmName) throws DuplicateRealmException {} + + @Override + public void addImportFrom(String relamName, String importSpec) throws NoSuchRealmException {} + + @Override + public void addLoadFile(File file) { + String version = null; + try { + if (file.isFile()) { + try (ZipFile zip = new ZipFile(file)) { + ZipEntry entry = zip.getEntry(MAVEN_CORE_POMPROPERTIES); + if (entry != null) { + try (InputStream is = zip.getInputStream(entry)) { + version = getMavenVersion(is); + } + } + } + } else { + try (InputStream is = new BufferedInputStream( + new FileInputStream(new File(file, MAVEN_CORE_POMPROPERTIES)))) { + version = getMavenVersion(is); + } + } + if (version != null) { + throw new MavenVersionFoundException(version); + } + } catch (IOException e) { + // assume the file does not have maven version + } + } - @Override - public void addImportFrom(String relamName, String importSpec) throws NoSuchRealmException {} + @Override + public void addLoadURL(URL url) {} + } + ; - @Override - public void addLoadFile(File file) { - String version = null; try { - if (file.isFile()) { - try (ZipFile zip = new ZipFile(file)) { - ZipEntry entry = zip.getEntry(MAVEN_CORE_POMPROPERTIES); - if (entry != null) { - try (InputStream is = zip.getInputStream(entry)) { - version = getMavenVersion(is); - } - } - } - } else { - try (InputStream is = new BufferedInputStream(new FileInputStream(new File(file, MAVEN_CORE_POMPROPERTIES)))) { - version = getMavenVersion(is); + VersionConfigHandler configHandler = new VersionConfigHandler(); + Properties properties = new Properties(System.getProperties()); + properties.setProperty(SYSPROP_MAVEN_HOME, mavenHome.getCanonicalPath()); + ConfigurationParser configParser = new ConfigurationParser(configHandler, properties); + try (InputStream is = new BufferedInputStream(new FileInputStream(classworldsConf))) { + configParser.parse(is); } - } - if (version != null) { - throw new MavenVersionFoundException(version); - } - } catch (IOException e) { - // assume the file does not have maven version + } catch (IOException | ClassWorldException | ConfigurationException e) { + throw new IllegalArgumentException("Could not determine Maven version", e); + } catch (MavenVersionFoundException e) { + return e.version; } - } - - @Override - public void addLoadURL(URL url) {} - }; - - try { - VersionConfigHandler configHandler = new VersionConfigHandler(); - Properties properties = new Properties(System.getProperties()); - properties.setProperty(SYSPROP_MAVEN_HOME, mavenHome.getCanonicalPath()); - ConfigurationParser configParser = new ConfigurationParser(configHandler, properties); - try (InputStream is = new BufferedInputStream(new FileInputStream(classworldsConf))) { - configParser.parse(is); - } - } catch (IOException | ClassWorldException | ConfigurationException e) { - throw new IllegalArgumentException("Could not determine Maven version", e); - } catch (MavenVersionFoundException e) { - return e.version; - } - throw new IllegalArgumentException("Could not determine Maven version"); - } - - public static File getForcedClassworldsConf() { - File configFile = null; - String classworldConf = System.getProperty(SYSPROP_CLASSWORLDSCONF); - String mavenHome = System.getProperty(SYSPROP_MAVEN_HOME); - if (classworldConf != null) { - configFile = new File(classworldConf); + throw new IllegalArgumentException("Could not determine Maven version"); } - if (configFile == null) { - if (mavenHome != null) { - configFile = new File(mavenHome, "bin/m2.conf"); - } + + public static File getForcedClassworldsConf() { + File configFile = null; + String classworldConf = System.getProperty(SYSPROP_CLASSWORLDSCONF); + String mavenHome = System.getProperty(SYSPROP_MAVEN_HOME); + if (classworldConf != null) { + configFile = new File(classworldConf); + } + if (configFile == null) { + if (mavenHome != null) { + configFile = new File(mavenHome, "bin/m2.conf"); + } + } + return configFile; } - return configFile; - } - public static File getForcedMavenHome() { - String mavenHome = System.getProperty(SYSPROP_MAVEN_HOME); - if (mavenHome != null) { - return new File(mavenHome); + public static File getForcedMavenHome() { + String mavenHome = System.getProperty(SYSPROP_MAVEN_HOME); + if (mavenHome != null) { + return new File(mavenHome); + } + return null; } - return null; - } - public static File getClassworldsConf(File mavenHome, File classworldsConf) { - if (classworldsConf == null) { - classworldsConf = new File(mavenHome, "bin/m2.conf"); + public static File getClassworldsConf(File mavenHome, File classworldsConf) { + if (classworldsConf == null) { + classworldsConf = new File(mavenHome, "bin/m2.conf"); + } + return classworldsConf; } - return classworldsConf; - } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenInstallations.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenInstallations.java index 0205669..743c9a8 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenInstallations.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenInstallations.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; @@ -18,12 +18,11 @@ @Inherited public @interface MavenInstallations { - /* - * Note on installation names. In most cases it will be desirable to give custom distributions a meaningful name and use that name as part of test name. Most likely this will be useful not only for - * integration tests but in other scenarios too (Hudson and m2e immediately come to mind), so the name/version need to be embedded in the maven installation itself. For example, it can be a file - * under ${maven.home}/conf directory, similar to /etc/issue used by linux distributions. It is also possible to include distribution name/version in one of the jars, similar to how maven version is - * already included in META-INF/maven/org.apache.maven/maven-core/pom.properties. - */ - public String[] value(); - + /* + * Note on installation names. In most cases it will be desirable to give custom distributions a meaningful name and use that name as part of test name. Most likely this will be useful not only for + * integration tests but in other scenarios too (Hudson and m2e immediately come to mind), so the name/version need to be embedded in the maven installation itself. For example, it can be a file + * under ${maven.home}/conf directory, similar to /etc/issue used by linux distributions. It is also possible to include distribution name/version in one of the jars, similar to how maven version is + * already included in META-INF/maven/org.apache.maven/maven-core/pom.properties. + */ + public String[] value(); } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenLauncher.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenLauncher.java index 3c175eb..da72dc3 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenLauncher.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenLauncher.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; @@ -13,9 +13,9 @@ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under @@ -30,7 +30,8 @@ */ interface MavenLauncher { - int run(String[] cliArgs, File multiModuleProjectDirectory, File workingDirectory, File logFile) throws IOException, LauncherException; + int run(String[] cliArgs, File multiModuleProjectDirectory, File workingDirectory, File logFile) + throws IOException, LauncherException; - String getMavenVersion() throws IOException, LauncherException; + String getMavenVersion() throws IOException, LauncherException; } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenRuntime.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenRuntime.java index e6ea3d5..0ba9d21 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenRuntime.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenRuntime.java @@ -1,14 +1,15 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; import static org.eclipse.m2e.workspace.WorkspaceState2.SYSPROP_STATEFILE_LOCATION; +import io.takari.maven.testing.TestProperties; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -17,231 +18,235 @@ import java.util.List; import java.util.Map; -import io.takari.maven.testing.TestProperties; - public class MavenRuntime { - private final MavenLauncher launcher; + private final MavenLauncher launcher; - private final TestProperties properties; + private final TestProperties properties; - public static class MavenRuntimeBuilder { + public static class MavenRuntimeBuilder { - protected final TestProperties properties; + protected final TestProperties properties; - protected final File mavenHome; + protected final File mavenHome; - protected final File classworldsConf; + protected final File classworldsConf; - protected final List extensions = new ArrayList<>(); + protected final List extensions = new ArrayList<>(); - protected final List args = new ArrayList<>(); + protected final List args = new ArrayList<>(); - MavenRuntimeBuilder(File mavenHome, File classworldsConf) { - this.properties = new TestProperties(); - this.mavenHome = mavenHome; - this.classworldsConf = classworldsConf; + MavenRuntimeBuilder(File mavenHome, File classworldsConf) { + this.properties = new TestProperties(); + this.mavenHome = mavenHome; + this.classworldsConf = classworldsConf; - StringBuilder workspaceState = new StringBuilder(); - appendLocation(workspaceState, System.getProperty(SYSPROP_STATEFILE_LOCATION)); - appendLocation(workspaceState, properties.get("workspaceStateProperties")); + StringBuilder workspaceState = new StringBuilder(); + appendLocation(workspaceState, System.getProperty(SYSPROP_STATEFILE_LOCATION)); + appendLocation(workspaceState, properties.get("workspaceStateProperties")); - String workspaceResolver = properties.get("workspaceResolver"); - if (workspaceState.length() > 0 && isFile(workspaceResolver)) { - if ("3.2.1".equals(MavenInstallationUtils.getMavenVersion(mavenHome, classworldsConf))) { - throw new IllegalArgumentException("Maven 3.2.1 is not supported, see https://jira.codehaus.org/browse/MNG-5591"); + String workspaceResolver = properties.get("workspaceResolver"); + if (workspaceState.length() > 0 && isFile(workspaceResolver)) { + if ("3.2.1".equals(MavenInstallationUtils.getMavenVersion(mavenHome, classworldsConf))) { + throw new IllegalArgumentException( + "Maven 3.2.1 is not supported, see https://jira.codehaus.org/browse/MNG-5591"); + } + args.add("-D" + SYSPROP_STATEFILE_LOCATION + "=" + workspaceState.toString()); + extensions.add(workspaceResolver); + } + // TODO decide if workspace resolution must be enabled and enforced } - args.add("-D" + SYSPROP_STATEFILE_LOCATION + "=" + workspaceState.toString()); - extensions.add(workspaceResolver); - } - // TODO decide if workspace resolution must be enabled and enforced - } - private void appendLocation(StringBuilder workspaceState, String location) { - if (location != null) { - if (!isFile(location)) { - throw new IllegalArgumentException("Not a file " + location); + private void appendLocation(StringBuilder workspaceState, String location) { + if (location != null) { + if (!isFile(location)) { + throw new IllegalArgumentException("Not a file " + location); + } + if (workspaceState.length() > 0) { + workspaceState.append(File.pathSeparator); + } + workspaceState.append(location); + } } - if (workspaceState.length() > 0) { - workspaceState.append(File.pathSeparator); + + MavenRuntimeBuilder(File mavenHome, File classworldsConf, List extensions, List args) { + this.properties = new TestProperties(); + this.mavenHome = mavenHome; + this.classworldsConf = classworldsConf; + this.extensions.addAll(extensions); + this.args.addAll(args); } - workspaceState.append(location); - } - } - MavenRuntimeBuilder(File mavenHome, File classworldsConf, List extensions, List args) { - this.properties = new TestProperties(); - this.mavenHome = mavenHome; - this.classworldsConf = classworldsConf; - this.extensions.addAll(extensions); - this.args.addAll(args); - } + private static boolean isFile(String path) { + return path != null && new File(path).isFile(); + } - private static boolean isFile(String path) { - return path != null && new File(path).isFile(); - } + public MavenRuntimeBuilder withExtension(File extensionLocation) { + assertFileExists("No such file or directory: " + extensionLocation, extensionLocation); + extensions.add(extensionLocation.getAbsolutePath()); + return this; + } - public MavenRuntimeBuilder withExtension(File extensionLocation) { - assertFileExists("No such file or directory: " + extensionLocation, extensionLocation); - extensions.add(extensionLocation.getAbsolutePath()); - return this; - } + public MavenRuntimeBuilder withExtensions(Collection extensionLocations) { + for (File extensionLocation : extensionLocations) { + assertFileExists("No such file or directory: " + extensionLocation, extensionLocation); + extensions.add(extensionLocation.getAbsolutePath()); + } + return this; + } - public MavenRuntimeBuilder withExtensions(Collection extensionLocations) { - for (File extensionLocation : extensionLocations) { - assertFileExists("No such file or directory: " + extensionLocation, extensionLocation); - extensions.add(extensionLocation.getAbsolutePath()); - } - return this; - } + private void assertFileExists(String message, File file) { + if (!file.exists()) { + throw new AssertionError("No such file or directory: " + file); + } + } - private void assertFileExists(String message, File file) { - if (!file.exists()) { - throw new AssertionError("No such file or directory: " + file); - } - } + public MavenRuntimeBuilder withCliOptions(String... options) { + for (String option : options) { + args.add(option); + } + return this; + } - public MavenRuntimeBuilder withCliOptions(String... options) { - for (String option : options) { - args.add(option); - } - return this; - } + public ForkedMavenRuntimeBuilder forkedBuilder() { + return new ForkedMavenRuntimeBuilder(mavenHome, classworldsConf, extensions, args); + } - public ForkedMavenRuntimeBuilder forkedBuilder() { - return new ForkedMavenRuntimeBuilder(mavenHome, classworldsConf, extensions, args); + public MavenRuntime build() throws Exception { + Embedded3xLauncher launcher = + Embedded3xLauncher.createFromMavenHome(mavenHome, classworldsConf, extensions, args); + return new MavenRuntime(launcher, properties); + } } - public MavenRuntime build() throws Exception { - Embedded3xLauncher launcher = Embedded3xLauncher.createFromMavenHome(mavenHome, classworldsConf, extensions, args); - return new MavenRuntime(launcher, properties); - } - } + public static class ForkedMavenRuntimeBuilder extends MavenRuntimeBuilder { - public static class ForkedMavenRuntimeBuilder extends MavenRuntimeBuilder { + private Map environment; + private final List jvmArgs = new ArrayList<>(); - private Map environment; - private final List jvmArgs = new ArrayList<>(); + ForkedMavenRuntimeBuilder(File mavenHome, File classworldsConf) { + super(mavenHome, classworldsConf); + } - ForkedMavenRuntimeBuilder(File mavenHome, File classworldsConf) { - super(mavenHome, classworldsConf); - } + ForkedMavenRuntimeBuilder(File mavenHome, File classworldsConf, List extensions, List args) { + super(mavenHome, classworldsConf, extensions, args); + } - ForkedMavenRuntimeBuilder(File mavenHome, File classworldsConf, List extensions, List args) { - super(mavenHome, classworldsConf, extensions, args); - } + public ForkedMavenRuntimeBuilder withEnvironment(Map environment) { + this.environment = new HashMap<>(environment); + return this; + } - public ForkedMavenRuntimeBuilder withEnvironment(Map environment) { - this.environment = new HashMap<>(environment); - return this; - } + @Override + public ForkedMavenRuntimeBuilder withExtension(File extensionLocation) { + super.withExtension(extensionLocation); + return this; + } + + @Override + public ForkedMavenRuntimeBuilder withExtensions(Collection extensionLocations) { + super.withExtensions(extensionLocations); + return this; + } + + @Override + public ForkedMavenRuntimeBuilder withCliOptions(String... options) { + super.withCliOptions(options); + return this; + } + + /** + * Adds a JVM option, as opposed to application option that can be added via {@link #withCliOptions(String...)}. Use this method to add options you would normally pass to {@code mvn/mvn.bat} via + * {@code MAVEN_OPTS} environment variable. + * + * @param jvmOption the JVM option to add + * @return this {@link ForkedMavenRuntimeBuilder} + */ + public ForkedMavenRuntimeBuilder withJvmOption(String jvmOption) { + this.jvmArgs.add(jvmOption); + return this; + } + + /** + * Add a JVM options, as opposed to application options that can be added via {@link #withCliOptions(String...)}. Use this method to add options you would normally pass to {@code mvn/mvn.bat} via + * {@code MAVEN_OPTS} environment variable. + * + * @param jvmOptions the JVM options to add + * @return this {@link ForkedMavenRuntimeBuilder} + */ + public ForkedMavenRuntimeBuilder withJvmOptions(String... jvmOptions) { + for (String jvmArg : jvmOptions) { + this.jvmArgs.add(jvmArg); + } + return this; + } + + /** + * Add a JVM options, as opposed to application options that can be added via {@link #withCliOptions(String...)}. Use this method to add options you would normally pass to {@code mvn/mvn.bat} via + * {@code MAVEN_OPTS} environment variable. + * + * @param jvmOptions the JVM options to add + * @return this {@link ForkedMavenRuntimeBuilder} + */ + public ForkedMavenRuntimeBuilder withJvmOptions(Collection jvmOptions) { + this.jvmArgs.addAll(jvmOptions); + return this; + } - @Override - public ForkedMavenRuntimeBuilder withExtension(File extensionLocation) { - super.withExtension(extensionLocation); - return this; + @Override + public MavenRuntime build() { + ForkedLauncher launcher = + new ForkedLauncher(mavenHome, classworldsConf, extensions, environment, args, jvmArgs); + return new MavenRuntime(launcher, properties); + } } - @Override - public ForkedMavenRuntimeBuilder withExtensions(Collection extensionLocations) { - super.withExtensions(extensionLocations); - return this; + MavenRuntime(MavenLauncher launcher, TestProperties properties) { + this.launcher = launcher; + this.properties = properties; } - @Override - public ForkedMavenRuntimeBuilder withCliOptions(String... options) { - super.withCliOptions(options); - return this; + public static MavenRuntimeBuilder builder(File mavenHome, File classworldsConf) { + return new MavenRuntimeBuilder(mavenHome, classworldsConf); } - /** - * Adds a JVM option, as opposed to application option that can be added via {@link #withCliOptions(String...)}. Use this method to add options you would normally pass to {@code mvn/mvn.bat} via - * {@code MAVEN_OPTS} environment variable. - * - * @param jvmOption the JVM option to add - * @return this {@link ForkedMavenRuntimeBuilder} - */ - public ForkedMavenRuntimeBuilder withJvmOption(String jvmOption) { - this.jvmArgs.add(jvmOption); - return this; + public static ForkedMavenRuntimeBuilder forkedBuilder(File mavenHome) { + return new ForkedMavenRuntimeBuilder(mavenHome, null); } - /** - * Add a JVM options, as opposed to application options that can be added via {@link #withCliOptions(String...)}. Use this method to add options you would normally pass to {@code mvn/mvn.bat} via - * {@code MAVEN_OPTS} environment variable. - * - * @param jvmOptions the JVM options to add - * @return this {@link ForkedMavenRuntimeBuilder} - */ - public ForkedMavenRuntimeBuilder withJvmOptions(String... jvmOptions) { - for (String jvmArg : jvmOptions) { - this.jvmArgs.add(jvmArg); - } - return this; + public MavenExecution forProject(File multiModuleProjectDirectory) { + return new MavenExecution(launcher, properties, multiModuleProjectDirectory, null); } /** - * Add a JVM options, as opposed to application options that can be added via {@link #withCliOptions(String...)}. Use this method to add options you would normally pass to {@code mvn/mvn.bat} via - * {@code MAVEN_OPTS} environment variable. - * - * @param jvmOptions the JVM options to add - * @return this {@link ForkedMavenRuntimeBuilder} + * @since 2.9 */ - public ForkedMavenRuntimeBuilder withJvmOptions(Collection jvmOptions) { - this.jvmArgs.addAll(jvmOptions); - return this; + public MavenExecution forProject(File multiModuleProjectDirectory, String moduleRelpath) + throws IOException, LauncherException { + String mavenVersion = launcher.getMavenVersion(); + if (!isVersion330plus(mavenVersion)) { + throw new UnsupportedOperationException( + "Explicit multiModuleProjectDirectory requires Maven 3.3 or newer, current version is " + + mavenVersion); + } + return new MavenExecution(launcher, properties, multiModuleProjectDirectory, moduleRelpath); } - @Override - public MavenRuntime build() { - ForkedLauncher launcher = new ForkedLauncher(mavenHome, classworldsConf, extensions, environment, args, jvmArgs); - return new MavenRuntime(launcher, properties); - } - } - - MavenRuntime(MavenLauncher launcher, TestProperties properties) { - this.launcher = launcher; - this.properties = properties; - } - - public static MavenRuntimeBuilder builder(File mavenHome, File classworldsConf) { - return new MavenRuntimeBuilder(mavenHome, classworldsConf); - } - - public static ForkedMavenRuntimeBuilder forkedBuilder(File mavenHome) { - return new ForkedMavenRuntimeBuilder(mavenHome, null); - } - - public MavenExecution forProject(File multiModuleProjectDirectory) { - return new MavenExecution(launcher, properties, multiModuleProjectDirectory, null); - } - - /** - * @since 2.9 - */ - public MavenExecution forProject(File multiModuleProjectDirectory, String moduleRelpath) throws IOException, LauncherException { - String mavenVersion = launcher.getMavenVersion(); - if (!isVersion330plus(mavenVersion)) { - throw new UnsupportedOperationException("Explicit multiModuleProjectDirectory requires Maven 3.3 or newer, current version is " + mavenVersion); + private boolean isVersion330plus(String version) { + String[] split = version.split("\\."); + if (split.length < 2) { + return false; // can't parse + } + if (Integer.parseInt(split[0]) < 3) { + return false; + } + return Integer.parseInt(split[1]) >= 3; } - return new MavenExecution(launcher, properties, multiModuleProjectDirectory, moduleRelpath); - } - private boolean isVersion330plus(String version) { - String[] split = version.split("\\."); - if (split.length < 2) { - return false; // can't parse - } - if (Integer.parseInt(split[0]) < 3) { - return false; + /** + * @since 2.0 + */ + public String getMavenVersion() throws IOException, LauncherException { + return launcher.getMavenVersion(); } - return Integer.parseInt(split[1]) >= 3; - } - - /** - * @since 2.0 - */ - public String getMavenVersion() throws IOException, LauncherException { - return launcher.getMavenVersion(); - } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenVersions.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenVersions.java index fb76fdb..cb4e478 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenVersions.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/MavenVersions.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor; @@ -17,5 +17,5 @@ @Target(ElementType.TYPE) @Inherited public @interface MavenVersions { - public String[] value(); + public String[] value(); } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/ForcedMavenRuntimeBuilderParameterResolver.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/ForcedMavenRuntimeBuilderParameterResolver.java index 23c9e17..0764c7a 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/ForcedMavenRuntimeBuilderParameterResolver.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/ForcedMavenRuntimeBuilderParameterResolver.java @@ -1,53 +1,49 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; +import io.takari.maven.testing.executor.MavenInstallationUtils; +import io.takari.maven.testing.executor.MavenRuntime; +import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; import java.io.File; - import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; -import io.takari.maven.testing.executor.MavenInstallationUtils; -import io.takari.maven.testing.executor.MavenRuntime; -import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; - /** * Provides a {@link MavenRuntimeBuilder} based on {@code -Dmaven.home} * and optionally {@code -Dclassworlds.conf}. - * + * * @author Philippe Marschall */ final class ForcedMavenRuntimeBuilderParameterResolver implements ParameterResolver { - ForcedMavenRuntimeBuilderParameterResolver() { - super(); - } - - @Override - public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { - return (parameterContext.getParameter().getType() == MavenRuntimeBuilder.class) - && MavenHomeUtils.isForced(); - } - - @Override - public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) - throws ParameterResolutionException { - File forcedMavenHome = MavenInstallationUtils.getForcedMavenHome(); - File forcedClassworldsConf = MavenInstallationUtils.getForcedClassworldsConf(); + ForcedMavenRuntimeBuilderParameterResolver() { + super(); + } - if (forcedMavenHome != null) { - if (forcedMavenHome.isDirectory() || ((forcedClassworldsConf != null) && forcedClassworldsConf.isFile())) { - return MavenRuntime.builder(forcedMavenHome, forcedClassworldsConf); - } + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return (parameterContext.getParameter().getType() == MavenRuntimeBuilder.class) && MavenHomeUtils.isForced(); } - throw new ParameterResolutionException("Invalid -Dmaven.home=" + forcedMavenHome.getAbsolutePath()); - } + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) + throws ParameterResolutionException { + File forcedMavenHome = MavenInstallationUtils.getForcedMavenHome(); + File forcedClassworldsConf = MavenInstallationUtils.getForcedClassworldsConf(); + + if (forcedMavenHome != null) { + if (forcedMavenHome.isDirectory() || ((forcedClassworldsConf != null) && forcedClassworldsConf.isFile())) { + return MavenRuntime.builder(forcedMavenHome, forcedClassworldsConf); + } + } + throw new ParameterResolutionException("Invalid -Dmaven.home=" + forcedMavenHome.getAbsolutePath()); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenHomeUtils.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenHomeUtils.java index 9cdd4d6..86a7db3 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenHomeUtils.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenHomeUtils.java @@ -1,36 +1,33 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; +import io.takari.maven.testing.executor.MavenInstallationUtils; import java.io.File; - import org.junit.jupiter.api.extension.ExtensionConfigurationException; -import io.takari.maven.testing.executor.MavenInstallationUtils; - final class MavenHomeUtils { - private MavenHomeUtils() { - throw new AssertionError("not instantiable"); - } + private MavenHomeUtils() { + throw new AssertionError("not instantiable"); + } - static boolean isForced() { + static boolean isForced() { - File forcedMavenHome = MavenInstallationUtils.getForcedMavenHome(); - File forcedClassworldsConf = MavenInstallationUtils.getForcedClassworldsConf(); + File forcedMavenHome = MavenInstallationUtils.getForcedMavenHome(); + File forcedClassworldsConf = MavenInstallationUtils.getForcedClassworldsConf(); - if (forcedMavenHome != null) { - if (forcedMavenHome.isDirectory() || (forcedClassworldsConf != null && forcedClassworldsConf.isFile())) { - return true; - } - throw new ExtensionConfigurationException("Invalid -Dmaven.home=" + forcedMavenHome.getAbsolutePath()); + if (forcedMavenHome != null) { + if (forcedMavenHome.isDirectory() || (forcedClassworldsConf != null && forcedClassworldsConf.isFile())) { + return true; + } + throw new ExtensionConfigurationException("Invalid -Dmaven.home=" + forcedMavenHome.getAbsolutePath()); + } + return false; } - return false; - } - } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationDisplayNameFormatter.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationDisplayNameFormatter.java index 2efd2b5..41297b1 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationDisplayNameFormatter.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationDisplayNameFormatter.java @@ -1,22 +1,21 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; final class MavenInstallationDisplayNameFormatter { - private final String displayName; + private final String displayName; - MavenInstallationDisplayNameFormatter(String displayName) { - this.displayName = displayName; - } + MavenInstallationDisplayNameFormatter(String displayName) { + this.displayName = displayName; + } - String format(String mavenInstallation) { - return this.displayName + '[' + mavenInstallation + ']'; - } - + String format(String mavenInstallation) { + return this.displayName + '[' + mavenInstallation + ']'; + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationTestInvocationContext.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationTestInvocationContext.java index 02658f5..4d608f3 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationTestInvocationContext.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationTestInvocationContext.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; @@ -11,39 +11,37 @@ import java.io.IOException; import java.util.Collections; import java.util.List; - import org.junit.jupiter.api.extension.Extension; import org.junit.jupiter.api.extension.ExtensionConfigurationException; import org.junit.jupiter.api.extension.TestTemplateInvocationContext; final class MavenInstallationTestInvocationContext implements TestTemplateInvocationContext { - private final MavenInstallationDisplayNameFormatter formatter; - private final String installation; - - MavenInstallationTestInvocationContext(String installation, MavenInstallationDisplayNameFormatter formatter) { - this.installation = installation; - this.formatter = formatter; - } - - @Override - public String getDisplayName(int invocationIndex) { - return this.formatter.format(this.installation); - } + private final MavenInstallationDisplayNameFormatter formatter; + private final String installation; - @Override - public List getAdditionalExtensions() { - File mavenHome; - try { - mavenHome = new File(this.installation).getCanonicalFile(); - } catch (IOException e) { - throw new ExtensionConfigurationException("could not access maven installation: " + this.installation, e); + MavenInstallationTestInvocationContext(String installation, MavenInstallationDisplayNameFormatter formatter) { + this.installation = installation; + this.formatter = formatter; } - if (mavenHome.isDirectory()) { - return Collections.singletonList(new MavenRuntimeBuilderParameterResolver(mavenHome)); - } else { - throw new ExtensionConfigurationException("Invalid maven installation location " + installation); + + @Override + public String getDisplayName(int invocationIndex) { + return this.formatter.format(this.installation); } - } + @Override + public List getAdditionalExtensions() { + File mavenHome; + try { + mavenHome = new File(this.installation).getCanonicalFile(); + } catch (IOException e) { + throw new ExtensionConfigurationException("could not access maven installation: " + this.installation, e); + } + if (mavenHome.isDirectory()) { + return Collections.singletonList(new MavenRuntimeBuilderParameterResolver(mavenHome)); + } else { + throw new ExtensionConfigurationException("Invalid maven installation location " + installation); + } + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationsTestExtension.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationsTestExtension.java index fca18aa..6236447 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationsTestExtension.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenInstallationsTestExtension.java @@ -1,50 +1,51 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; +import io.takari.maven.testing.executor.MavenInstallations; +import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; import java.util.Arrays; import java.util.stream.Stream; - import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.TestTemplateInvocationContext; import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; -import io.takari.maven.testing.executor.MavenInstallations; -import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; - /** * Provides a {@link TestTemplateInvocationContext} with a {@link MavenRuntimeBuilder} * for each Maven installation configured through {@link MavenInstallations}. *

      * Not active if Maven home is forced through {@code -Dmaven.home}. - * + * * @author Philippe Marschall */ final class MavenInstallationsTestExtension implements TestTemplateInvocationContextProvider { - @Override - public boolean supportsTestTemplate(ExtensionContext context) { - if (MavenHomeUtils.isForced()) { - return false; + @Override + public boolean supportsTestTemplate(ExtensionContext context) { + if (MavenHomeUtils.isForced()) { + return false; + } + // @formatter:off + return context.getTestClass() + .map(clazz -> clazz.isAnnotationPresent(MavenInstallations.class)) + .orElse(false); + // @formatter:on } - //@formatter:off - return context.getTestClass() - .map(clazz -> clazz.isAnnotationPresent(MavenInstallations.class)) - .orElse(false); - //@formatter:on - } - - @Override - public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { - String displayName = context.getDisplayName(); - String[] installations = context.getTestClass().get().getAnnotation(MavenInstallations.class).value(); - return Arrays.stream(installations) - .map(installation -> new MavenInstallationTestInvocationContext(installation, new MavenInstallationDisplayNameFormatter(displayName))); - } + @Override + public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { + String displayName = context.getDisplayName(); + String[] installations = context.getTestClass() + .get() + .getAnnotation(MavenInstallations.class) + .value(); + return Arrays.stream(installations) + .map(installation -> new MavenInstallationTestInvocationContext( + installation, new MavenInstallationDisplayNameFormatter(displayName))); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenJUnitTestRunner.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenJUnitTestRunner.java index bbb4423..6292846 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenJUnitTestRunner.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenJUnitTestRunner.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; @@ -12,12 +12,10 @@ import io.takari.maven.testing.executor.MavenRuntime; import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; import io.takari.maven.testing.executor.MavenVersions; - import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; - import org.junit.runner.Runner; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; @@ -30,7 +28,7 @@ * Runs JUnit4 tests with one or more Maven runtimes. The test class must have public constructor with single parameter of type {@linkplain MavenRuntimeBuilder MavenRuntimeBuilder}. *

      * Test Maven runtimes are located in the following order: - * + * *

        *
      1. If {@code -Dmaven.home} (and optionally {@code -Dclassworlds.conf}) is specified, the tests will be executed with the specified Maven installation. This is what is used in Eclipse Maven JUnit * Test launch configuration to implement "Override test Maven runtime". Can also be useful to run tests with custom or snapshot Maven build specified from pom.xml.
      2. @@ -39,106 +37,111 @@ */ public class MavenJUnitTestRunner extends Suite { - private static class SingleMavenInstallationRunner extends BlockJUnit4ClassRunner { + private static class SingleMavenInstallationRunner extends BlockJUnit4ClassRunner { - private final File mavenHome; + private final File mavenHome; - private final File classworldsConf; + private final File classworldsConf; - private final String name; + private final String name; - SingleMavenInstallationRunner(Class klass, File mavenHome, File classworldsConf, String name) throws InitializationError { - super(klass); - this.mavenHome = mavenHome; - this.classworldsConf = classworldsConf; - this.name = name; - } + SingleMavenInstallationRunner(Class klass, File mavenHome, File classworldsConf, String name) + throws InitializationError { + super(klass); + this.mavenHome = mavenHome; + this.classworldsConf = classworldsConf; + this.name = name; + } - @Override - protected Object createTest() throws Exception { - MavenRuntimeBuilder builder = MavenRuntime.builder(mavenHome, classworldsConf); - return getTestClass().getJavaClass().getConstructor(MavenRuntimeBuilder.class).newInstance(builder); - } + @Override + protected Object createTest() throws Exception { + MavenRuntimeBuilder builder = MavenRuntime.builder(mavenHome, classworldsConf); + return getTestClass() + .getJavaClass() + .getConstructor(MavenRuntimeBuilder.class) + .newInstance(builder); + } - @Override - protected void validateZeroArgConstructor(List errors) { - try { - getTestClass().getJavaClass().getConstructor(MavenRuntimeBuilder.class); - } catch (NoSuchMethodException e) { - errors.add(e); - } - } + @Override + protected void validateZeroArgConstructor(List errors) { + try { + getTestClass().getJavaClass().getConstructor(MavenRuntimeBuilder.class); + } catch (NoSuchMethodException e) { + errors.add(e); + } + } - @Override - protected String getName() { - return "[" + name + "]"; - } + @Override + protected String getName() { + return "[" + name + "]"; + } - @Override - protected String testName(FrameworkMethod method) { - return method.getName() + getName(); - } + @Override + protected String testName(FrameworkMethod method) { + return method.getName() + getName(); + } - @Override - protected Statement classBlock(RunNotifier notifier) { - return childrenInvoker(notifier); + @Override + protected Statement classBlock(RunNotifier notifier) { + return childrenInvoker(notifier); + } } - } - - public MavenJUnitTestRunner(Class clazz) throws Throwable { - super(clazz, getRunners(clazz)); - } - - private static List getRunners(final Class clazz) throws Throwable { - File forcedMavenHome = MavenInstallationUtils.getForcedMavenHome(); - File forcedClassworldsConf = MavenInstallationUtils.getForcedClassworldsConf(); - - if (forcedMavenHome != null) { - if (forcedMavenHome.isDirectory() || (forcedClassworldsConf != null && forcedClassworldsConf.isFile())) { - String version = MavenInstallationUtils.getMavenVersion(forcedMavenHome, forcedClassworldsConf); - return Collections.singletonList(new SingleMavenInstallationRunner(clazz, forcedMavenHome, forcedClassworldsConf, version)); - } - throw new InitializationError(new Exception("Invalid -Dmaven.home=" + forcedMavenHome.getAbsolutePath())); + + public MavenJUnitTestRunner(Class clazz) throws Throwable { + super(clazz, getRunners(clazz)); } - final List errors = new ArrayList<>(); - final List runners = new ArrayList<>(); - - MavenInstallations installations = clazz.getAnnotation(MavenInstallations.class); - if (installations != null) { - for (String installation : installations.value()) { - File mavenHome = new File(installation).getCanonicalFile(); - if (mavenHome.isDirectory()) { - runners.add(new SingleMavenInstallationRunner(clazz, mavenHome, null, installation)); - } else { - errors.add(new Exception("Invalid maven installation location " + installation)); + private static List getRunners(final Class clazz) throws Throwable { + File forcedMavenHome = MavenInstallationUtils.getForcedMavenHome(); + File forcedClassworldsConf = MavenInstallationUtils.getForcedClassworldsConf(); + + if (forcedMavenHome != null) { + if (forcedMavenHome.isDirectory() || (forcedClassworldsConf != null && forcedClassworldsConf.isFile())) { + String version = MavenInstallationUtils.getMavenVersion(forcedMavenHome, forcedClassworldsConf); + return Collections.singletonList( + new SingleMavenInstallationRunner(clazz, forcedMavenHome, forcedClassworldsConf, version)); + } + throw new InitializationError(new Exception("Invalid -Dmaven.home=" + forcedMavenHome.getAbsolutePath())); } - } - } - MavenVersions versions = clazz.getAnnotation(MavenVersions.class); - if (versions != null) { - new MavenVersionResolver() { - @Override - protected void resolved(File mavenHome, String version) throws InitializationError { - runners.add(new SingleMavenInstallationRunner(clazz, mavenHome, null, version)); + final List errors = new ArrayList<>(); + final List runners = new ArrayList<>(); + + MavenInstallations installations = clazz.getAnnotation(MavenInstallations.class); + if (installations != null) { + for (String installation : installations.value()) { + File mavenHome = new File(installation).getCanonicalFile(); + if (mavenHome.isDirectory()) { + runners.add(new SingleMavenInstallationRunner(clazz, mavenHome, null, installation)); + } else { + errors.add(new Exception("Invalid maven installation location " + installation)); + } + } } - @Override - protected void error(String version, Exception cause) { - errors.add(new Exception("Could not resolve maven version " + version, cause)); + MavenVersions versions = clazz.getAnnotation(MavenVersions.class); + if (versions != null) { + new MavenVersionResolver() { + @Override + protected void resolved(File mavenHome, String version) throws InitializationError { + runners.add(new SingleMavenInstallationRunner(clazz, mavenHome, null, version)); + } + + @Override + protected void error(String version, Exception cause) { + errors.add(new Exception("Could not resolve maven version " + version, cause)); + } + }.resolve(versions.value()); } - }.resolve(versions.value()); - } - if (!errors.isEmpty()) { - throw new InitializationError(errors); - } + if (!errors.isEmpty()) { + throw new InitializationError(errors); + } - if (runners.isEmpty()) { - throw new InitializationError(new Exception("No configured test maven runtime")); - } + if (runners.isEmpty()) { + throw new InitializationError(new Exception("No configured test maven runtime")); + } - return runners; - } + return runners; + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenPluginTest.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenPluginTest.java index 5fbddf5..7a8f4e3 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenPluginTest.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenPluginTest.java @@ -1,9 +1,9 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; @@ -15,13 +15,12 @@ import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; - import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; /** * Meta-annotation for Maven plugin integration tests, registers all necessary extensions. - * + * * @author Philippe Marschall */ @Documented @@ -30,9 +29,8 @@ @TestTemplate @Inherited @ExtendWith({ - ForcedMavenRuntimeBuilderParameterResolver.class, - MavenInstallationsTestExtension.class, - MavenVersionsTestExtension.class}) -public @interface MavenPluginTest { - -} + ForcedMavenRuntimeBuilderParameterResolver.class, + MavenInstallationsTestExtension.class, + MavenVersionsTestExtension.class +}) +public @interface MavenPluginTest {} diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenRuntimeBuilderParameterResolver.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenRuntimeBuilderParameterResolver.java index 0064dff..5b400df 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenRuntimeBuilderParameterResolver.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenRuntimeBuilderParameterResolver.java @@ -1,39 +1,36 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; +import io.takari.maven.testing.executor.MavenRuntime; +import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; import java.io.File; - import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; -import io.takari.maven.testing.executor.MavenRuntime; -import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; - final class MavenRuntimeBuilderParameterResolver implements ParameterResolver { - - private final File mavenHome; - MavenRuntimeBuilderParameterResolver(File mavenHome) { - this.mavenHome = mavenHome; - } + private final File mavenHome; - @Override - public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { - return parameterContext.getParameter().getType() == MavenRuntimeBuilder.class; - } + MavenRuntimeBuilderParameterResolver(File mavenHome) { + this.mavenHome = mavenHome; + } - @Override - public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) - throws ParameterResolutionException { - return MavenRuntime.builder(this.mavenHome, null); - } + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return parameterContext.getParameter().getType() == MavenRuntimeBuilder.class; + } + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) + throws ParameterResolutionException { + return MavenRuntime.builder(this.mavenHome, null); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionDisplayNameFormatter.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionDisplayNameFormatter.java index 9cdf1bd..3c7a32b 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionDisplayNameFormatter.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionDisplayNameFormatter.java @@ -1,22 +1,21 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; final class MavenVersionDisplayNameFormatter { - private final String displayName; + private final String displayName; - MavenVersionDisplayNameFormatter(String displayName) { - this.displayName = displayName; - } + MavenVersionDisplayNameFormatter(String displayName) { + this.displayName = displayName; + } - String format(String mavenVersion) { - return this.displayName + '[' + mavenVersion + ']'; - } - + String format(String mavenVersion) { + return this.displayName + '[' + mavenVersion + ']'; + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionResolver.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionResolver.java index e0fdbaa..68bd6bf 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionResolver.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionResolver.java @@ -1,12 +1,13 @@ -/** - * Copyright (c) 2014 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; +import io.takari.maven.testing.TestProperties; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -34,13 +35,11 @@ import java.util.List; import java.util.Map; import java.util.Set; - import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; - import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; @@ -51,295 +50,307 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import io.takari.maven.testing.TestProperties; - abstract class MavenVersionResolver { - private static final XPathFactory xpathFactory = XPathFactory.newInstance(); - private static final DocumentBuilderFactory documentBuilderFactory; + private static final XPathFactory xpathFactory = XPathFactory.newInstance(); + private static final DocumentBuilderFactory documentBuilderFactory; - static { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - // settings.xml may have default xmlns, which may confuse xpath if not suppressed - factory.setNamespaceAware(false); - documentBuilderFactory = factory; - } + static { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + // settings.xml may have default xmlns, which may confuse xpath if not suppressed + factory.setNamespaceAware(false); + documentBuilderFactory = factory; + } - private static class Credentials { - public final String username; - public final String password; + private static class Credentials { + public final String username; + public final String password; - public Credentials(String username, String password) { - this.username = username; - this.password = password; + public Credentials(String username, String password) { + this.username = username; + this.password = password; + } } - } - private static class Repository { - public final URL url; - public final Credentials credentials; + private static class Repository { + public final URL url; + public final Credentials credentials; - public Repository(URL url, Credentials credentials) { - this.url = url; - this.credentials = credentials; + public Repository(URL url, Credentials credentials) { + this.url = url; + this.credentials = credentials; + } } - } - public void resolve(String[] versions) throws Exception { - List repositories = null; - TestProperties properties = new TestProperties(); - for (String version : versions) { - // refuse to test with SNAPSHOT maven version when build RELEASE plugins - if (isSnapshot(version) && !isSnapshot(properties.getPluginVersion())) { - String msg = String.format("Cannot test %s plugin release with %s maven", properties.getPluginVersion(), version); - error(version, new IllegalStateException(msg)); - } - File basdir = new File("target/maven-installation").getCanonicalFile(); - File mavenHome = new File(basdir, "apache-maven-" + version).getCanonicalFile(); - if (!mavenHome.isDirectory()) { - if (repositories == null) { - repositories = getRepositories(properties); + public void resolve(String[] versions) throws Exception { + List repositories = null; + TestProperties properties = new TestProperties(); + for (String version : versions) { + // refuse to test with SNAPSHOT maven version when build RELEASE plugins + if (isSnapshot(version) && !isSnapshot(properties.getPluginVersion())) { + String msg = String.format( + "Cannot test %s plugin release with %s maven", properties.getPluginVersion(), version); + error(version, new IllegalStateException(msg)); + } + File basdir = new File("target/maven-installation").getCanonicalFile(); + File mavenHome = new File(basdir, "apache-maven-" + version).getCanonicalFile(); + if (!mavenHome.isDirectory()) { + if (repositories == null) { + repositories = getRepositories(properties); + } + Authenticator defaultAuthenticator = getDefaultAuthenticator(); + try { + createMavenInstallation(repositories, version, properties.getLocalRepository(), basdir); + } catch (Exception e) { + error(version, e); + } finally { + Authenticator.setDefault(defaultAuthenticator); + } + } + if (mavenHome.isDirectory()) { + resolved(mavenHome, version); + } } - Authenticator defaultAuthenticator = getDefaultAuthenticator(); + } + + private static Authenticator getDefaultAuthenticator() throws ReflectiveOperationException { + Method getDefault; try { - createMavenInstallation(repositories, version, properties.getLocalRepository(), basdir); - } catch (Exception e) { - error(version, e); - } finally { - Authenticator.setDefault(defaultAuthenticator); + getDefault = Authenticator.class.getMethod("getDefault"); + } catch (NoSuchMethodException e) { + // there is no API to query current default Authenticator before JDK 9 + // assume that integration test jvm does not have any at this point + return null; } - } - if (mavenHome.isDirectory()) { - resolved(mavenHome, version); - } + return (Authenticator) getDefault.invoke(null); } - } - private static Authenticator getDefaultAuthenticator() throws ReflectiveOperationException { - Method getDefault; - try { - getDefault = Authenticator.class.getMethod("getDefault"); - } catch (NoSuchMethodException e) { - // there is no API to query current default Authenticator before JDK 9 - // assume that integration test jvm does not have any at this point - return null; + private boolean isSnapshot(String version) { + return version != null && version.endsWith("-SNAPSHOT"); } - return (Authenticator) getDefault.invoke(null); - } - private boolean isSnapshot(String version) { - return version != null && version.endsWith("-SNAPSHOT"); - } - - private void unarchive(File archive, File directory) throws IOException { - try (TarArchiveInputStream ais = new TarArchiveInputStream(new GzipCompressorInputStream(new FileInputStream(archive)))) { - TarArchiveEntry entry; - while ((entry = ais.getNextTarEntry()) != null) { - if (entry.isFile()) { - String name = entry.getName(); - File file = new File(directory, name); - file.getParentFile().mkdirs(); - try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) { - copy(ais, os); - } - int mode = entry.getMode(); - if (mode != -1 && (mode & 0100) != 0) { - try { - Path path = file.toPath(); - Set permissions = Files.getPosixFilePermissions(path); - permissions.add(PosixFilePermission.OWNER_EXECUTE); - Files.setPosixFilePermissions(path, permissions); - } catch (UnsupportedOperationException e) { - // must be windows, ignore + private void unarchive(File archive, File directory) throws IOException { + try (TarArchiveInputStream ais = + new TarArchiveInputStream(new GzipCompressorInputStream(new FileInputStream(archive)))) { + TarArchiveEntry entry; + while ((entry = ais.getNextTarEntry()) != null) { + if (entry.isFile()) { + String name = entry.getName(); + File file = new File(directory, name); + file.getParentFile().mkdirs(); + try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) { + copy(ais, os); + } + int mode = entry.getMode(); + if (mode != -1 && (mode & 0100) != 0) { + try { + Path path = file.toPath(); + Set permissions = Files.getPosixFilePermissions(path); + permissions.add(PosixFilePermission.OWNER_EXECUTE); + Files.setPosixFilePermissions(path, permissions); + } catch (UnsupportedOperationException e) { + // must be windows, ignore + } + } + } } - } } - } } - } - private List getRepositories(TestProperties properties) throws Exception { - Map credentials = getCredentials(properties); - List repositories = new ArrayList<>(); - for (String property : properties.getRepositories()) { - InputSource is = new InputSource(new StringReader("" + property + "")); - Element repository = (Element) xpathFactory.newXPath() // - .compile("/repository") // - .evaluate(is, XPathConstants.NODE); - String url = getChildValue(repository, "url"); - if (url == null) { - continue; // malformed test.properties - } - if (!url.endsWith("/")) { - url = url + "/"; - } - String id = getChildValue(repository, "id"); - repositories.add(new Repository(new URL(url), credentials.get(id))); + private List getRepositories(TestProperties properties) throws Exception { + Map credentials = getCredentials(properties); + List repositories = new ArrayList<>(); + for (String property : properties.getRepositories()) { + InputSource is = new InputSource(new StringReader("" + property + "")); + Element repository = (Element) xpathFactory + .newXPath() // + .compile("/repository") // + .evaluate(is, XPathConstants.NODE); + String url = getChildValue(repository, "url"); + if (url == null) { + continue; // malformed test.properties + } + if (!url.endsWith("/")) { + url = url + "/"; + } + String id = getChildValue(repository, "id"); + repositories.add(new Repository(new URL(url), credentials.get(id))); + } + return repositories; } - return repositories; - } - private Map getCredentials(TestProperties properties) throws IOException { - File userSettings = properties.getUserSettings(); - if (userSettings == null) { - return Collections.emptyMap(); - } - Map result = new HashMap<>(); - try { - Document document = documentBuilderFactory.newDocumentBuilder().parse(userSettings); - NodeList servers = (NodeList) xpathFactory.newXPath() // - .compile("//settings/servers/server") // - .evaluate(document, XPathConstants.NODESET); - for (int i = 0; i < servers.getLength(); i++) { - Element server = (Element) servers.item(i); - String id = getChildValue(server, "id"); - String username = getChildValue(server, "username"); - String password = getChildValue(server, "password"); - if (id != null && username != null) { - result.put(id, new Credentials(username, password)); + private Map getCredentials(TestProperties properties) throws IOException { + File userSettings = properties.getUserSettings(); + if (userSettings == null) { + return Collections.emptyMap(); + } + Map result = new HashMap<>(); + try { + Document document = documentBuilderFactory.newDocumentBuilder().parse(userSettings); + NodeList servers = (NodeList) xpathFactory + .newXPath() // + .compile("//settings/servers/server") // + .evaluate(document, XPathConstants.NODESET); + for (int i = 0; i < servers.getLength(); i++) { + Element server = (Element) servers.item(i); + String id = getChildValue(server, "id"); + String username = getChildValue(server, "username"); + String password = getChildValue(server, "password"); + if (id != null && username != null) { + result.put(id, new Credentials(username, password)); + } + } + } catch (XPathExpressionException | SAXException | ParserConfigurationException e) { + // can't happen } - } - } catch (XPathExpressionException | SAXException | ParserConfigurationException e) { - // can't happen + return result; } - return result; - } - private String getChildValue(Element server, String name) { - NodeList children = server.getElementsByTagName(name); - if (children.getLength() != 1) { - return null; - } - String value = ((Element) children.item(0)).getTextContent(); - if (value != null) { - value = value.trim(); + private String getChildValue(Element server, String name) { + NodeList children = server.getElementsByTagName(name); + if (children.getLength() != 1) { + return null; + } + String value = ((Element) children.item(0)).getTextContent(); + if (value != null) { + value = value.trim(); + } + return !value.isEmpty() ? value : null; } - return !value.isEmpty() ? value : null; - } - private String getXPathString(InputSource is, String path) throws Exception { - String value = xpathFactory.newXPath().compile(path).evaluate(is); - if (value == null) { - return null; + private String getXPathString(InputSource is, String path) throws Exception { + String value = xpathFactory.newXPath().compile(path).evaluate(is); + if (value == null) { + return null; + } + value = value.trim(); + return !value.isEmpty() ? value : null; } - value = value.trim(); - return !value.isEmpty() ? value : null; - } - private void createMavenInstallation(List repositories, String version, File localrepo, File targetdir) throws Exception { - String versionDir = "org/apache/maven/apache-maven/" + version + "/"; - String filename = "apache-maven-" + version + "-bin.tar.gz"; - File archive = new File(localrepo, versionDir + filename); - if (archive.canRead()) { - unarchive(archive, targetdir); - return; - } - Exception cause = null; - for (Repository repository : repositories) { - setHttpCredentials(repository.credentials); - String effectiveVersion; - if (isSnapshot(version)) { - try { - effectiveVersion = getQualifiedVersion(repository.url, versionDir); - } catch (FileNotFoundException e) { - continue; - } catch (IOException e) { - cause = e; - continue; + private void createMavenInstallation(List repositories, String version, File localrepo, File targetdir) + throws Exception { + String versionDir = "org/apache/maven/apache-maven/" + version + "/"; + String filename = "apache-maven-" + version + "-bin.tar.gz"; + File archive = new File(localrepo, versionDir + filename); + if (archive.canRead()) { + unarchive(archive, targetdir); + return; } - if (effectiveVersion == null) { - continue; - } - } else { - effectiveVersion = version; - } - filename = "apache-maven-" + effectiveVersion + "-bin.tar.gz"; - archive = new File(localrepo, versionDir + filename); - if (archive.canRead()) { - unarchive(archive, targetdir); - return; - } - URL resource = new URL(repository.url, versionDir + filename); - try (InputStream is = openStream(resource)) { - archive.getParentFile().mkdirs(); - File tmpfile = File.createTempFile(filename, ".tmp", archive.getParentFile()); - try { - copy(is, tmpfile); - unarchive(tmpfile, targetdir); - Files.move(tmpfile.toPath(), archive.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); - } finally { - tmpfile.delete(); + Exception cause = null; + for (Repository repository : repositories) { + setHttpCredentials(repository.credentials); + String effectiveVersion; + if (isSnapshot(version)) { + try { + effectiveVersion = getQualifiedVersion(repository.url, versionDir); + } catch (FileNotFoundException e) { + continue; + } catch (IOException e) { + cause = e; + continue; + } + if (effectiveVersion == null) { + continue; + } + } else { + effectiveVersion = version; + } + filename = "apache-maven-" + effectiveVersion + "-bin.tar.gz"; + archive = new File(localrepo, versionDir + filename); + if (archive.canRead()) { + unarchive(archive, targetdir); + return; + } + URL resource = new URL(repository.url, versionDir + filename); + try (InputStream is = openStream(resource)) { + archive.getParentFile().mkdirs(); + File tmpfile = File.createTempFile(filename, ".tmp", archive.getParentFile()); + try { + copy(is, tmpfile); + unarchive(tmpfile, targetdir); + Files.move( + tmpfile.toPath(), + archive.toPath(), + StandardCopyOption.ATOMIC_MOVE, + StandardCopyOption.REPLACE_EXISTING); + } finally { + tmpfile.delete(); + } + return; + } catch (FileNotFoundException e) { + // ignore the exception. this is expected to happen quite often and not a failure by iteself + } catch (IOException e) { + cause = e; + } } - return; - } catch (FileNotFoundException e) { - // ignore the exception. this is expected to happen quite often and not a failure by iteself - } catch (IOException e) { - cause = e; - } + Exception exception = new FileNotFoundException( + "Could not download maven version " + version + " from any configured repository"); + exception.initCause(cause); + throw exception; } - Exception exception = new FileNotFoundException("Could not download maven version " + version + " from any configured repository"); - exception.initCause(cause); - throw exception; - } - private void setHttpCredentials(final Credentials credentials) { - Authenticator authenticator = null; - if (credentials != null) { - authenticator = new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(credentials.username, credentials.password.toCharArray()); + private void setHttpCredentials(final Credentials credentials) { + Authenticator authenticator = null; + if (credentials != null) { + authenticator = new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(credentials.username, credentials.password.toCharArray()); + } + }; } - }; + Authenticator.setDefault(authenticator); } - Authenticator.setDefault(authenticator); - } - private String getQualifiedVersion(URL repository, String versionDir) throws Exception { - URL resource = new URL(repository, versionDir + "maven-metadata.xml"); - try (InputStream is = openStream(resource)) { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - copy(is, buf); - InputSource xml = new InputSource(new ByteArrayInputStream(buf.toByteArray())); - String version = getXPathString(xml, "//metadata/versioning/snapshotVersions/snapshotVersion[extension='tar.gz']/value"); - if (version == null) { - return null; - } - version = version.trim(); - return version.isEmpty() ? null : version; + private String getQualifiedVersion(URL repository, String versionDir) throws Exception { + URL resource = new URL(repository, versionDir + "maven-metadata.xml"); + try (InputStream is = openStream(resource)) { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + copy(is, buf); + InputSource xml = new InputSource(new ByteArrayInputStream(buf.toByteArray())); + String version = getXPathString( + xml, "//metadata/versioning/snapshotVersions/snapshotVersion[extension='tar.gz']/value"); + if (version == null) { + return null; + } + version = version.trim(); + return version.isEmpty() ? null : version; + } } - } - private InputStream openStream(URL resource) throws IOException { - URLConnection connection = resource.openConnection(); - if (connection instanceof HttpURLConnection) { - // for some reason, nexus version 2.11.1-01 returns partial maven-metadata.xml - // unless request User-Agent header is set to non-default value - connection.addRequestProperty("User-Agent", "takari-plugin-testing"); - int responseCode = ((HttpURLConnection) connection).getResponseCode(); - if (responseCode < 200 || responseCode > 299) { - String message = String.format("HTTP/%d %s", responseCode, ((HttpURLConnection) connection).getResponseMessage()); - throw responseCode == HttpURLConnection.HTTP_NOT_FOUND ? new FileNotFoundException(message) : new IOException(message); - } + private InputStream openStream(URL resource) throws IOException { + URLConnection connection = resource.openConnection(); + if (connection instanceof HttpURLConnection) { + // for some reason, nexus version 2.11.1-01 returns partial maven-metadata.xml + // unless request User-Agent header is set to non-default value + connection.addRequestProperty("User-Agent", "takari-plugin-testing"); + int responseCode = ((HttpURLConnection) connection).getResponseCode(); + if (responseCode < 200 || responseCode > 299) { + String message = String.format( + "HTTP/%d %s", responseCode, ((HttpURLConnection) connection).getResponseMessage()); + throw responseCode == HttpURLConnection.HTTP_NOT_FOUND + ? new FileNotFoundException(message) + : new IOException(message); + } + } + return connection.getInputStream(); } - return connection.getInputStream(); - } - private void copy(InputStream from, File to) throws IOException { - to.getParentFile().mkdirs(); - try (OutputStream out = new FileOutputStream(to)) { - copy(from, out); + private void copy(InputStream from, File to) throws IOException { + to.getParentFile().mkdirs(); + try (OutputStream out = new FileOutputStream(to)) { + copy(from, out); + } } - } - private void copy(InputStream from, OutputStream to) throws IOException { - byte[] buf = new byte[4096]; - int len; - while ((len = from.read(buf)) > 0) { - to.write(buf, 0, len); + private void copy(InputStream from, OutputStream to) throws IOException { + byte[] buf = new byte[4096]; + int len; + while ((len = from.read(buf)) > 0) { + to.write(buf, 0, len); + } } - } - protected abstract void error(String version, Exception e); + protected abstract void error(String version, Exception e); - protected abstract void resolved(File mavenHome, String version) throws InitializationError; + protected abstract void resolved(File mavenHome, String version) throws InitializationError; } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionTestInvocationContext.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionTestInvocationContext.java index 469df7a..30eb8b4 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionTestInvocationContext.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionTestInvocationContext.java @@ -1,39 +1,37 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; import java.io.File; import java.util.Collections; import java.util.List; - import org.junit.jupiter.api.extension.Extension; import org.junit.jupiter.api.extension.TestTemplateInvocationContext; final class MavenVersionTestInvocationContext implements TestTemplateInvocationContext { - private final String mavenVersion; - private final File mavenHome; - private final MavenVersionDisplayNameFormatter formatter; - - MavenVersionTestInvocationContext(String mavenVersion, File mavenHome, MavenVersionDisplayNameFormatter formatter) { - this.mavenVersion = mavenVersion; - this.mavenHome = mavenHome; - this.formatter = formatter; - } - - @Override - public String getDisplayName(int invocationIndex) { - return this.formatter.format(this.mavenVersion); - } - - @Override - public List getAdditionalExtensions() { - return Collections.singletonList(new MavenRuntimeBuilderParameterResolver(this.mavenHome)); - } - + private final String mavenVersion; + private final File mavenHome; + private final MavenVersionDisplayNameFormatter formatter; + + MavenVersionTestInvocationContext(String mavenVersion, File mavenHome, MavenVersionDisplayNameFormatter formatter) { + this.mavenVersion = mavenVersion; + this.mavenHome = mavenHome; + this.formatter = formatter; + } + + @Override + public String getDisplayName(int invocationIndex) { + return this.formatter.format(this.mavenVersion); + } + + @Override + public List getAdditionalExtensions() { + return Collections.singletonList(new MavenRuntimeBuilderParameterResolver(this.mavenHome)); + } } diff --git a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionsTestExtension.java b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionsTestExtension.java index ca21571..904445b 100644 --- a/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionsTestExtension.java +++ b/takari-plugin-testing/src/main/java/io/takari/maven/testing/executor/junit/MavenVersionsTestExtension.java @@ -1,78 +1,78 @@ -/** - * Copyright (c) 2021 Takari, Inc. +/* + * Copyright (c) 2014-2024 Takari, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html + * https://www.eclipse.org/legal/epl-v10.html */ package io.takari.maven.testing.executor.junit; +import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; +import io.takari.maven.testing.executor.MavenVersions; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; - import org.junit.jupiter.api.extension.ExtensionConfigurationException; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.TestTemplateInvocationContext; import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; import org.junit.runners.model.InitializationError; -import io.takari.maven.testing.executor.MavenRuntime.MavenRuntimeBuilder; -import io.takari.maven.testing.executor.MavenVersions; - /** * Provides a {@link TestTemplateInvocationContext} with a {@link MavenRuntimeBuilder} * for each Maven version configured through {@link MavenVersions}. *

        * Not active if Maven home is forced through {@code -Dmaven.home}. - * + * * @author Philippe Marschall */ final class MavenVersionsTestExtension implements TestTemplateInvocationContextProvider { - @Override - public boolean supportsTestTemplate(ExtensionContext context) { - if (MavenHomeUtils.isForced()) { - return false; + @Override + public boolean supportsTestTemplate(ExtensionContext context) { + if (MavenHomeUtils.isForced()) { + return false; + } + // @formatter:off + return context.getTestClass() + .map(clazz -> clazz.isAnnotationPresent(MavenVersions.class)) + .orElse(false); + // @formatter:on } - //@formatter:off - return context.getTestClass() - .map(clazz -> clazz.isAnnotationPresent(MavenVersions.class)) - .orElse(false); - //@formatter:on - } - @Override - public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { - String displayName = context.getDisplayName(); - String[] versions = context.getTestClass().get().getAnnotation(MavenVersions.class).value(); - List contexts = new ArrayList<>(); - List errors = new ArrayList<>(); + @Override + public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { + String displayName = context.getDisplayName(); + String[] versions = + context.getTestClass().get().getAnnotation(MavenVersions.class).value(); + List contexts = new ArrayList<>(); + List errors = new ArrayList<>(); - try { - new MavenVersionResolver() { - @Override - protected void resolved(File mavenHome, String version) throws InitializationError { - contexts.add(new MavenVersionTestInvocationContext(version, mavenHome, new MavenVersionDisplayNameFormatter(displayName))); - } + try { + new MavenVersionResolver() { + @Override + protected void resolved(File mavenHome, String version) throws InitializationError { + contexts.add(new MavenVersionTestInvocationContext( + version, mavenHome, new MavenVersionDisplayNameFormatter(displayName))); + } - @Override - protected void error(String version, Exception cause) { - errors.add(new Exception("Could not resolve maven version " + version, cause)); + @Override + protected void error(String version, Exception cause) { + errors.add(new Exception("Could not resolve maven version " + version, cause)); + } + }.resolve(versions); + } catch (Exception e) { + throw new ExtensionConfigurationException("Could not resolve maven versions", e); } - }.resolve(versions); - } catch (Exception e) { - throw new ExtensionConfigurationException("Could not resolve maven versions", e); - } - if (!errors.isEmpty()) { - ExtensionConfigurationException extensionConfigurationException = new ExtensionConfigurationException("Could not resolve maven versions"); - for (Throwable error : errors) { - extensionConfigurationException.addSuppressed(error); - } - throw extensionConfigurationException; + if (!errors.isEmpty()) { + ExtensionConfigurationException extensionConfigurationException = + new ExtensionConfigurationException("Could not resolve maven versions"); + for (Throwable error : errors) { + extensionConfigurationException.addSuppressed(error); + } + throw extensionConfigurationException; + } + return contexts.stream(); } - return contexts.stream(); - } - }