diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml index 2903856..e3bafe8 100644 --- a/.github/workflows/maven-build.yml +++ b/.github/workflows/maven-build.yml @@ -20,7 +20,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - java: [11, 17] + java: [11, 17, 21] os: [ubuntu-latest] distribution: [temurin] include: @@ -39,6 +39,6 @@ jobs: java-version: ${{ matrix.java }} maven-executable: ./mvnw sonar-run-on-os: ubuntu-latest - sonar-run-on-java-version: 11 + sonar-run-on-java-version: 17 sonar-token: ${{ secrets.SONAR_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml index aef0ee4..c709b1c 100644 --- a/.github/workflows/maven-deploy.yml +++ b/.github/workflows/maven-deploy.yml @@ -2,6 +2,8 @@ name: Deploy +concurrency: ${{ github.workflow }} + on: push: branches: @@ -15,7 +17,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Configure GIT run: | diff --git a/.github/workflows/release-from-tag.yml b/.github/workflows/release-from-tag.yml index e9947ff..b50b6bf 100644 --- a/.github/workflows/release-from-tag.yml +++ b/.github/workflows/release-from-tag.yml @@ -12,7 +12,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ncipollo/release-action@v1 with: body: 'Changes: https://devops.wcm.io/conga/plugins/sling/changes-report.html' diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index c1dd12f..cb28b0e 100644 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 8c79a83..ac18401 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -5,14 +5,14 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-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/changes.xml b/changes.xml index c732976..611239d 100644 --- a/changes.xml +++ b/changes.xml @@ -23,6 +23,12 @@ xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd"> + + + Generate run modes for configurations in order as expected by AEM Analyser Plugin. + + + Switch to Java 11 as minimum version. diff --git a/conga-sling-plugin/pom.xml b/conga-sling-plugin/pom.xml index 8cd1b9a..fc27846 100644 --- a/conga-sling-plugin/pom.xml +++ b/conga-sling-plugin/pom.xml @@ -25,13 +25,13 @@ io.wcm.devops.conga.plugins io.wcm.devops.conga.plugins.sling.parent - 1.3.2 + 1.3.4 ../parent/pom.xml io.wcm.devops.conga.plugins io.wcm.devops.conga.plugins.sling - 1.3.2 + 1.3.4 jar CONGA Sling Plugin @@ -60,7 +60,7 @@ io.wcm.devops.conga io.wcm.devops.conga.generator - 1.15.0 + 1.16.2 compile diff --git a/conga-sling-plugin/src/it/example/pom.xml b/conga-sling-plugin/src/it/example/pom.xml index 75d297d..097b51d 100644 --- a/conga-sling-plugin/src/it/example/pom.xml +++ b/conga-sling-plugin/src/it/example/pom.xml @@ -26,7 +26,7 @@ io.wcm.maven io.wcm.maven.global-parent - 44 + 54 @@ -45,7 +45,7 @@ io.wcm.devops.conga conga-maven-plugin - 1.15.0 + 1.16.2 true diff --git a/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/ConfigurationHandler_ConfigAdmin184.java b/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/ConfigurationHandler_ConfigAdmin184.java index d165d91..c2a1852 100644 --- a/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/ConfigurationHandler_ConfigAdmin184.java +++ b/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/ConfigurationHandler_ConfigAdmin184.java @@ -118,24 +118,24 @@ class ConfigurationHandler_ConfigAdmin184 { type2Code = new HashMap(); // simple (exclusive String whose type code is not written) - type2Code.put(Integer.class, new Integer(TOKEN_SIMPLE_INTEGER)); - type2Code.put(Long.class, new Integer(TOKEN_SIMPLE_LONG)); - type2Code.put(Float.class, new Integer(TOKEN_SIMPLE_FLOAT)); - type2Code.put(Double.class, new Integer(TOKEN_SIMPLE_DOUBLE)); - type2Code.put(Byte.class, new Integer(TOKEN_SIMPLE_BYTE)); - type2Code.put(Short.class, new Integer(TOKEN_SIMPLE_SHORT)); - type2Code.put(Character.class, new Integer(TOKEN_SIMPLE_CHARACTER)); - type2Code.put(Boolean.class, new Integer(TOKEN_SIMPLE_BOOLEAN)); + type2Code.put(Integer.class, Integer.valueOf(TOKEN_SIMPLE_INTEGER)); + type2Code.put(Long.class, Integer.valueOf(TOKEN_SIMPLE_LONG)); + type2Code.put(Float.class, Integer.valueOf(TOKEN_SIMPLE_FLOAT)); + type2Code.put(Double.class, Integer.valueOf(TOKEN_SIMPLE_DOUBLE)); + type2Code.put(Byte.class, Integer.valueOf(TOKEN_SIMPLE_BYTE)); + type2Code.put(Short.class, Integer.valueOf(TOKEN_SIMPLE_SHORT)); + type2Code.put(Character.class, Integer.valueOf(TOKEN_SIMPLE_CHARACTER)); + type2Code.put(Boolean.class, Integer.valueOf(TOKEN_SIMPLE_BOOLEAN)); // primitives - type2Code.put(Integer.TYPE, new Integer(TOKEN_PRIMITIVE_INT)); - type2Code.put(Long.TYPE, new Integer(TOKEN_PRIMITIVE_LONG)); - type2Code.put(Float.TYPE, new Integer(TOKEN_PRIMITIVE_FLOAT)); - type2Code.put(Double.TYPE, new Integer(TOKEN_PRIMITIVE_DOUBLE)); - type2Code.put(Byte.TYPE, new Integer(TOKEN_PRIMITIVE_BYTE)); - type2Code.put(Short.TYPE, new Integer(TOKEN_PRIMITIVE_SHORT)); - type2Code.put(Character.TYPE, new Integer(TOKEN_PRIMITIVE_CHAR)); - type2Code.put(Boolean.TYPE, new Integer(TOKEN_PRIMITIVE_BOOLEAN)); + type2Code.put(Integer.TYPE, Integer.valueOf(TOKEN_PRIMITIVE_INT)); + type2Code.put(Long.TYPE, Integer.valueOf(TOKEN_PRIMITIVE_LONG)); + type2Code.put(Float.TYPE, Integer.valueOf(TOKEN_PRIMITIVE_FLOAT)); + type2Code.put(Double.TYPE, Integer.valueOf(TOKEN_PRIMITIVE_DOUBLE)); + type2Code.put(Byte.TYPE, Integer.valueOf(TOKEN_PRIMITIVE_BYTE)); + type2Code.put(Short.TYPE, Integer.valueOf(TOKEN_PRIMITIVE_SHORT)); + type2Code.put(Character.TYPE, Integer.valueOf(TOKEN_PRIMITIVE_CHAR)); + type2Code.put(Boolean.TYPE, Integer.valueOf(TOKEN_PRIMITIVE_BOOLEAN)); // reverse map to map type codes to classes, string class mapping // to be added manually, as the string type code is not written and @@ -145,7 +145,7 @@ class ConfigurationHandler_ConfigAdmin184 { Map.Entry entry = (Map.Entry)ti.next(); code2Type.put(entry.getValue(), entry.getKey()); } - code2Type.put(new Integer(TOKEN_SIMPLE_STRING), String.class); + code2Type.put(Integer.valueOf(TOKEN_SIMPLE_STRING), String.class); NAME_CHARS = new BitSet(); for (int i = '0'; i <= '9'; i++) { @@ -301,7 +301,7 @@ private Object readValue(PushbackReader pr) throws IOException { // read value kind code if type code is not a value kinde code int code; - if (code2Type.containsKey(new Integer(type))) { + if (code2Type.containsKey(Integer.valueOf(type))) { code = read(pr); } else { @@ -346,7 +346,7 @@ private Object readArray(int typeCode, PushbackReader pr) throws IOException { } if (c == TOKEN_ARR_CLOS) { - Class type = (Class)code2Type.get(new Integer(typeCode)); + Class type = (Class)code2Type.get(Integer.valueOf(typeCode)); Object array = Array.newInstance(type, list.size()); for (int i = 0; i < list.size(); i++) { Array.set(array, i, list.get(i)); @@ -414,12 +414,12 @@ private Object readSimple(int code, PushbackReader pr) throws IOException { case TOKEN_SIMPLE_FLOAT: case TOKEN_PRIMITIVE_FLOAT: int fBits = Integer.parseInt(readQuoted(pr)); - return new Float(Float.intBitsToFloat(fBits)); + return Float.valueOf(Float.intBitsToFloat(fBits)); case TOKEN_SIMPLE_DOUBLE: case TOKEN_PRIMITIVE_DOUBLE: long dBits = Long.parseLong(readQuoted(pr)); - return new Double(Double.longBitsToDouble(dBits)); + return Double.valueOf(Double.longBitsToDouble(dBits)); case TOKEN_SIMPLE_BYTE: case TOKEN_PRIMITIVE_BYTE: @@ -433,7 +433,7 @@ private Object readSimple(int code, PushbackReader pr) throws IOException { case TOKEN_PRIMITIVE_CHAR: String cString = readQuoted(pr); if (cString != null && cString.length() > 0) { - return new Character(cString.charAt(0)); + return Character.valueOf(cString.charAt(0)); } return null; @@ -668,11 +668,11 @@ private static void writeType(Writer out, Class valueType) throws IOException { private static void writeSimple(Writer out, Object value) throws IOException { if (value instanceof Double) { double dVal = ((Double)value).doubleValue(); - value = new Long(Double.doubleToRawLongBits(dVal)); + value = Long.valueOf(Double.doubleToRawLongBits(dVal)); } else if (value instanceof Float) { float fVal = ((Float)value).floatValue(); - value = new Integer(Float.floatToRawIntBits(fVal)); + value = Integer.valueOf(Float.floatToRawIntBits(fVal)); } out.write(TOKEN_VAL_OPEN); diff --git a/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/ProvisioningUtil.java b/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/ProvisioningUtil.java index 3d766d0..b9a9f09 100644 --- a/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/ProvisioningUtil.java +++ b/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/ProvisioningUtil.java @@ -26,7 +26,9 @@ import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.SortedSet; import java.util.TreeSet; @@ -41,8 +43,6 @@ import org.apache.sling.provisioning.model.Section; import org.apache.sling.provisioning.model.io.ModelReader; -import com.google.common.collect.ImmutableList; - import io.wcm.devops.conga.generator.spi.context.FileContext; import io.wcm.devops.conga.generator.util.FileUtil; @@ -145,7 +145,7 @@ public static List visitOsgiConfigurations(Model model, ConfigConsumer } // prepare repoinit OSGi configuration - String pid = StringUtils.defaultString(feature.getName(), "conga") + String pid = Objects.toString(feature.getName(), "conga") + (runModesString != null ? "-" + StringUtils.replace(runModesString, ",", "-") : ""); Configuration configuration = new Configuration(pid, REPOINIT_PID); configuration.getProperties().put("scripts", new String[] { script }); @@ -164,9 +164,9 @@ public static List visitOsgiConfigurations(Model model, ConfigConsumer * Get the relative path for a configuration */ private static String getPathForConfiguration(Configuration configuration, RunMode runMode) { - SortedSet runModesList = new TreeSet<>(); + SortedSet runModesList = new TreeSet<>(new RunModeComparator()); if (runMode.getNames() != null) { - runModesList.addAll(ImmutableList.copyOf(runMode.getNames())); + runModesList.addAll(Arrays.asList(runMode.getNames())); } // run modes directory diff --git a/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/RunModeComparator.java b/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/RunModeComparator.java new file mode 100644 index 0000000..af0d948 --- /dev/null +++ b/conga-sling-plugin/src/main/java/io/wcm/devops/conga/plugins/sling/util/RunModeComparator.java @@ -0,0 +1,53 @@ +/* + * #%L + * wcm.io + * %% + * Copyright (C) 2023 wcm.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package io.wcm.devops.conga.plugins.sling.util; + +import java.io.Serializable; +import java.util.Comparator; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.Nullable; + +/** + * Comparator sorts run modes alphabetically. + * However, service run modes (author, publish) are always put at the first position. + */ +public class RunModeComparator implements Comparator, Serializable { + private static final long serialVersionUID = 1L; + + private static final Set SERVICE_RUNMODES = Set.of("author", "publish"); + + @Override + public int compare(String runmode1, String runmode2) { + if (isServiceRunmode(runmode1) && !isServiceRunmode(runmode2)) { + return -1; + } + if (!isServiceRunmode(runmode1) && isServiceRunmode(runmode2)) { + return 1; + } + return StringUtils.compare(runmode1, runmode2); + } + + private static boolean isServiceRunmode(@Nullable String runmode) { + return runmode != null && SERVICE_RUNMODES.contains(runmode); + } + +} diff --git a/conga-sling-plugin/src/test/java/io/wcm/devops/conga/plugins/sling/postprocessor/ProvisioningOsgiConfigPostProcessorTest.java b/conga-sling-plugin/src/test/java/io/wcm/devops/conga/plugins/sling/postprocessor/ProvisioningOsgiConfigPostProcessorTest.java index f5f7551..c7ab868 100644 --- a/conga-sling-plugin/src/test/java/io/wcm/devops/conga/plugins/sling/postprocessor/ProvisioningOsgiConfigPostProcessorTest.java +++ b/conga-sling-plugin/src/test/java/io/wcm/devops/conga/plugins/sling/postprocessor/ProvisioningOsgiConfigPostProcessorTest.java @@ -83,6 +83,7 @@ void testProvisioningExample() throws Exception { assertExists("my.factory-my.pid.config"); assertExists("mode1/my.factory-my.pid2.config"); assertExists("mode2/my.pid2.config"); + assertExists("publish.prod/my.pid2.config"); // validate repoinit statements config = readConfig("org.apache.sling.jcr.repoinit.RepositoryInitializer-test.config"); diff --git a/conga-sling-plugin/src/test/java/io/wcm/devops/conga/plugins/sling/util/RunModeComparatorTest.java b/conga-sling-plugin/src/test/java/io/wcm/devops/conga/plugins/sling/util/RunModeComparatorTest.java new file mode 100644 index 0000000..abd24ae --- /dev/null +++ b/conga-sling-plugin/src/test/java/io/wcm/devops/conga/plugins/sling/util/RunModeComparatorTest.java @@ -0,0 +1,47 @@ +/* + * #%L + * wcm.io + * %% + * Copyright (C) 2023 wcm.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package io.wcm.devops.conga.plugins.sling.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +class RunModeComparatorTest { + + @Test + void testCompare() { + assertEquals(List.of("mode1", "mode2"), comparedList("mode2", "mode1")); + assertEquals(List.of("publish", "mode1", "mode2", "prod"), comparedList("mode2", "mode1", "publish", "prod")); + assertEquals(List.of("author", "publish", "mode1", "mode2", "prod"), comparedList("mode2", "mode1", "publish", "prod", "author")); + } + + private static List comparedList(String... runmodes) { + SortedSet set = new TreeSet<>(new RunModeComparator()); + set.addAll(Arrays.asList(runmodes)); + return set.stream().collect(Collectors.toList()); + } + +} diff --git a/conga-sling-plugin/src/test/resources/validProvisioning.txt b/conga-sling-plugin/src/test/resources/validProvisioning.txt index 2f51be6..9d7cb20 100644 --- a/conga-sling-plugin/src/test/resources/validProvisioning.txt +++ b/conga-sling-plugin/src/test/resources/validProvisioning.txt @@ -23,6 +23,11 @@ my.pid2 stringProperty="value4" +[configurations runModes=publish,prod] + + my.pid2 + stringProperty="value5" + [:repoinit] create path /repoinit/test1 diff --git a/mvnw b/mvnw index 5643201..8d937f4 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven Start Up Batch script +# Apache Maven Wrapper startup batch script, version 3.2.0 # # Required ENV vars: # ------------------ @@ -27,7 +27,6 @@ # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir # MAVEN_OPTS - parameters passed to the Java VM when running Maven # e.g. to debug Maven itself, use # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -54,7 +53,7 @@ fi cygwin=false; darwin=false; mingw=false -case "`uname`" in +case "$(uname)" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true @@ -62,9 +61,9 @@ case "`uname`" in # See https://developer.apple.com/library/mac/qa/qa1170/_index.html if [ -z "$JAVA_HOME" ]; then if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME else - export JAVA_HOME="/Library/Java/Home" + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME fi fi ;; @@ -72,68 +71,38 @@ esac if [ -z "$JAVA_HOME" ] ; then if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` + JAVA_HOME=$(java-config --jre-home) fi fi -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") fi # For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" fi if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; 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 + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" else - javaExecutable="`readlink -f \"$javaExecutable\"`" + javaExecutable="$(readlink -f "\"$javaExecutable\"")" fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') JAVA_HOME="$javaHome" export JAVA_HOME fi @@ -149,7 +118,7 @@ if [ -z "$JAVACMD" ] ; then JAVACMD="$JAVA_HOME/bin/java" fi else - JAVACMD="`\\unset -f command; \\command -v java`" + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" fi fi @@ -163,12 +132,9 @@ if [ -z "$JAVA_HOME" ] ; then echo "Warning: JAVA_HOME environment variable is not set." fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - # 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" @@ -184,96 +150,99 @@ find_maven_basedir() { fi # workaround for JBEAP-8937 (on Solaris 10/Sparc) if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` + wdir=$(cd "$wdir/.." || exit 1; pwd) fi # end of workaround done - echo "${basedir}" + printf '%s' "$(cd "$basedir" || exit 1; pwd)" } # concatenates all lines of a file concat_lines() { if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" fi } -BASE_DIR=`find_maven_basedir "$(pwd)"` +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") if [ -z "$BASE_DIR" ]; then exit 1; fi +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + ########################################################################################## # 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 +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi + log "Couldn't find $wrapperJarPath, downloading it ..." + if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" else - jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") fi if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" fi elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" fi - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" # For Cygwin, switch paths to Windows format before running javac if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" fi fi fi @@ -282,35 +251,58 @@ fi # End of extension ########################################################################################## -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi fi + MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") 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 $@" +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" export MAVEN_CMD_LINE_ARGS WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +# shellcheck disable=SC2086 # safe args exec "$JAVACMD" \ $MAVEN_OPTS \ $MAVEN_DEBUG_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" \ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 8a15b7f..c4586b5 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -18,13 +18,12 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script +@REM Apache Maven Wrapper startup batch script, version 3.2.0 @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 keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @@ -120,10 +119,10 @@ 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 -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B ) @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central @@ -134,11 +133,11 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% + echo Downloading from: %WRAPPER_URL% ) powershell -Command "&{"^ @@ -146,7 +145,7 @@ if exist %WRAPPER_JAR% ( "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ "}" if "%MVNW_VERBOSE%" == "true" ( echo Finished downloading %WRAPPER_JAR% @@ -154,6 +153,24 @@ if exist %WRAPPER_JAR% ( ) @REM End of extension +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + @REM Provide a "standardized" way to retrieve the CLI args that will @REM work with both Windows and non-Windows executions. set MAVEN_CMD_LINE_ARGS=%* diff --git a/parent/pom.xml b/parent/pom.xml index 1141ab4..e8038dd 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -25,13 +25,13 @@ io.wcm.devops io.wcm.devops.parent_toplevel - 1.4.0 + 1.4.2 io.wcm.devops.conga.plugins io.wcm.devops.conga.plugins.sling.parent - 1.3.2 + 1.3.4 pom CONGA Sling Plugin @@ -43,7 +43,7 @@ GitHub - https://github.com/wcm-io/conga-sling-plugin/issues/ + https://github.com/wcm-io-devops/conga-sling-plugin/issues/ diff --git a/pom.xml b/pom.xml index 6fe0ace..c34f117 100644 --- a/pom.xml +++ b/pom.xml @@ -23,13 +23,13 @@ io.wcm.devops.conga.plugins io.wcm.devops.conga.plugins.sling.parent - 1.3.2 + 1.3.4 parent/pom.xml io.wcm.devops.conga.plugins io.wcm.devops.conga.plugins.sling.root - 1.3.2 + 1.3.4 pom CONGA Sling Plugin