From bf2af132b9d7ba8ac05542ae4211477bc34541ce Mon Sep 17 00:00:00 2001 From: Nils Breunese Date: Sat, 18 May 2024 03:05:08 +0200 Subject: [PATCH] [MWRAPPER-141] Use distribution type of existing Maven Wrapper by default Remove unused import --- .../.mvn/wrapper/maven-wrapper.properties | 19 ++++++ .../invoker.properties | 19 ++++++ .../upgrade_with_existing_type/pom.xml | 66 ++++++++++++++++++ .../upgrade_with_existing_type/verify.groovy | 37 ++++++++++ .../maven/plugins/wrapper/WrapperMojo.java | 67 +++++++++++++++---- .../src/site/markdown/usage.md | 14 ++-- 6 files changed, 205 insertions(+), 17 deletions(-) create mode 100644 maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/.mvn/wrapper/maven-wrapper.properties create mode 100644 maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/invoker.properties create mode 100644 maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/pom.xml create mode 100644 maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/verify.groovy diff --git a/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/.mvn/wrapper/maven-wrapper.properties b/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..3ba43029 --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://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.9.5/apache-maven-3.9.5-bin.zip +distributionType=bin +wrapperVersion=3.3.1 \ No newline at end of file diff --git a/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/invoker.properties b/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/invoker.properties new file mode 100644 index 00000000..faac648f --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/invoker.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.goals.1 = ${project.groupId}:${project.artifactId}:${project.version}:wrapper -Dmaven=3.9.6 +invoker.goals.2 = exec:exec diff --git a/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/pom.xml b/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/pom.xml new file mode 100644 index 00000000..cbec1de6 --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/pom.xml @@ -0,0 +1,66 @@ + + + + + + 4.0.0 + + org.apache.maven.plugins.it.wrapper + extension + 1.0.0-SNAPSHOT + pom + + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + mvnw${cmd} + + -v + + + true + + + + + + + + + + windows + + windows + + + .cmd + + + + \ No newline at end of file diff --git a/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/verify.groovy b/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/verify.groovy new file mode 100644 index 00000000..1eeca652 --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/upgrade_with_existing_type/verify.groovy @@ -0,0 +1,37 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +assert new File(basedir,'mvnw').exists() +assert new File(basedir,'mvnw.cmd').exists() +assert new File(basedir,'.mvn/wrapper/maven-wrapper.jar').exists() + +wrapperProperties = new File(basedir,'.mvn/wrapper/maven-wrapper.properties') +assert wrapperProperties.exists() + +Properties props = new Properties() +wrapperProperties.withInputStream { + props.load(it) +} + +// Assert that distribution type from previous Maven Wrapper is retained, without it being explicitly set via '-Dtype=' +assert props.distributionType.equals("bin") + +// Assert that distribution URL was updated to version specified via '-Dmaven=' +assert props.distributionUrl.endsWith("/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip") diff --git a/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java b/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java index 91bae308..4b0650fc 100644 --- a/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java +++ b/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java @@ -36,7 +36,6 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; @@ -84,7 +83,10 @@ public class WrapperMojo extends AbstractMojo { private String mvndVersion; /** + * The Maven Wrapper distribution type. + *

* Options are: + * *

*
script
*
only mvnw scripts
@@ -95,11 +97,16 @@ public class WrapperMojo extends AbstractMojo { *
only-script (default)
*
the new lite implementation of mvnw/mvnw.cmd scripts downloads the maven directly and skips maven-wrapper.jar - since 3.2.0
*
- * Value will be used as classifier of the downloaded file + * + * If {@code -Dtype={type}} is not explicitly provided, then {@code distributionType} from + * {@code .mvn/wrapper/maven-wrapper.properties} is used, if it exists. + * Otherwise, {@code only-script} is used as the default distribution type. + *

+ * This value will be used as the classifier of the downloaded file. * * @since 3.0.0 */ - @Parameter(defaultValue = "only-script", property = "type") + @Parameter(property = "type") private String distributionType; /** @@ -159,6 +166,16 @@ public class WrapperMojo extends AbstractMojo { private static final String WRAPPER_DISTRIBUTION_EXTENSION = "zip"; + private static final String WRAPPER_DIR = ".mvn/wrapper"; + + private static final String WRAPPER_PROPERTIES_FILENAME = "maven-wrapper.properties"; + + private static final String DISTRIBUTION_TYPE_PROPERTY_NAME = "distributionType"; + + private static final String TYPE_ONLY_SCRIPT = "only-script"; + + private static final String DEFAULT_DISTRIBUTION_TYPE = TYPE_ONLY_SCRIPT; + // COMPONENTS @Inject @@ -168,27 +185,53 @@ public class WrapperMojo extends AbstractMojo { private Map unarchivers; @Override - public void execute() throws MojoExecutionException, MojoFailureException { - if (mvndVersion != null && mvndVersion.length() > 0 && !"only-script".equals(distributionType)) { + public void execute() throws MojoExecutionException { + final Path baseDir = Paths.get(session.getRequest().getBaseDirectory()); + final Path wrapperDir = baseDir.resolve(WRAPPER_DIR); + + if (distributionType == null) { + distributionType = determineDistributionType(wrapperDir); + } + + if (mvndVersion != null && mvndVersion.length() > 0 && !TYPE_ONLY_SCRIPT.equals(distributionType)) { throw new MojoExecutionException("maven-wrapper with type=" + distributionType - + " cannot work with mvnd, please set type to 'only-script'."); + + " cannot work with mvnd, please set type to '" + TYPE_ONLY_SCRIPT + "'."); } - Path baseDir = Paths.get(session.getRequest().getBaseDirectory()); mavenVersion = getVersion(mavenVersion, Maven.class, "org.apache.maven/maven-core"); String wrapperVersion = getVersion(null, this.getClass(), "org.apache.maven.plugins/maven-wrapper-plugin"); final Artifact artifact = downloadWrapperDistribution(wrapperVersion); - final Path wrapperDir = createDirectories(baseDir.resolve(".mvn/wrapper")); + createDirectories(wrapperDir); cleanup(wrapperDir); unpack(artifact, baseDir); replaceProperties(wrapperVersion, wrapperDir); } - private Path createDirectories(Path dir) throws MojoExecutionException { + private String determineDistributionType(final Path wrapperDir) { + final String typeFromMavenWrapperProperties = distributionTypeFromExistingMavenWrapperProperties(wrapperDir); + if (typeFromMavenWrapperProperties != null) { + return typeFromMavenWrapperProperties; + } + + return DEFAULT_DISTRIBUTION_TYPE; + } + + private String distributionTypeFromExistingMavenWrapperProperties(final Path wrapperDir) { + final Path mavenWrapperProperties = wrapperDir.resolve(WRAPPER_PROPERTIES_FILENAME); + try (InputStream inputStream = Files.newInputStream(mavenWrapperProperties)) { + Properties properties = new Properties(); + properties.load(inputStream); + return properties.getProperty(DISTRIBUTION_TYPE_PROPERTY_NAME); + } catch (IOException e) { + return null; + } + } + + private void createDirectories(Path dir) throws MojoExecutionException { try { - return Files.createDirectories(dir); + Files.createDirectories(dir); } catch (IOException ioe) { throw new MojoExecutionException(ioe.getMessage(), ioe); } @@ -288,12 +331,12 @@ private void replaceProperties(String wrapperVersion, Path targetFolder) throws try (BufferedWriter out = Files.newBufferedWriter(wrapperPropertiesFile, StandardCharsets.UTF_8)) { out.append(String.format(Locale.ROOT, license)); out.append("wrapperVersion=" + wrapperVersion + System.lineSeparator()); - out.append("distributionType=" + distributionType + System.lineSeparator()); + out.append(DISTRIBUTION_TYPE_PROPERTY_NAME + "=" + distributionType + System.lineSeparator()); out.append("distributionUrl=" + distributionUrl + System.lineSeparator()); if (distributionSha256Sum != null) { out.append("distributionSha256Sum=" + distributionSha256Sum + System.lineSeparator()); } - if (!distributionType.equals("only-script")) { + if (!distributionType.equals(TYPE_ONLY_SCRIPT)) { out.append("wrapperUrl=" + wrapperUrl + System.lineSeparator()); } if (wrapperSha256Sum != null) { diff --git a/maven-wrapper-plugin/src/site/markdown/usage.md b/maven-wrapper-plugin/src/site/markdown/usage.md index 3c22bcac..4bba7167 100644 --- a/maven-wrapper-plugin/src/site/markdown/usage.md +++ b/maven-wrapper-plugin/src/site/markdown/usage.md @@ -32,9 +32,9 @@ The scripts work like this: Apache Maven Wrapper Distribution Types ----- -There are 4 types available: +There are 4 distribution types available: -- **only-script** _(default)_: the lite implementation of `mvnw`/`mvnw.cmd` scripts will download the maven directly via wget or curl on *nix, or PowerShell on Windows, +- **only-script** _(default for new installations)_: the lite implementation of `mvnw`/`mvnw.cmd` scripts will download the maven directly via wget or curl on *nix, or PowerShell on Windows, then exec/call the original `mvn`/`mvn.cmd` scripts of the downloaded maven distribution. This type does not use `maven-wrapper.jar` nor `MavenWrapperDownloader.java`, only the wrapper scripts are required. @@ -46,13 +46,17 @@ The downside is that the project will contain a binary file in the source contro - **source**: Since Maven already requires Java to run, why not compile and run a classfile to download the maven-wrapper jar? This type comes with a `.mvn/wrapper/MavenWrapperDownloader.java` which will be compiled and executed on the fly. -The type can be specified with `mvn wrapper:wrapper -Dtype=x`, where x is any of the types listed above. +The type can be specified with `mvn wrapper:wrapper -Dtype={type}`, where `{type}` is any of the types listed above. + +When `wrapper:wrapper` is run in a Maven module which contains a `.mvn/wrapper/maven-wrapper.properties` file, then the distribution type of the existing Maven Wrapper is used for the execution of the goal. +This allows updating Maven Wrapper, without unintentionally changing the distribution type for an existing project. +You can still use `-Dtype={type}` to change the distribution type for an existing installation. Maven Version ------------- By default the plugin will assume the same version as the Maven runtime (calling `mvn -v`). But you can pick a different version. -Either call `mvn wrapper:wrapper -Dmaven=x`, where x is any valid Apache Maven Release, see https://search.maven.org/artifact/org.apache.maven/apache-maven -Another option is adjust the `distributionUrl` in `.mvn/wrapper/maven-wrapper.properties` +You can call `mvn wrapper:wrapper -Dmaven=x`, where `x` is any valid Apache Maven Release (see [Maven Central](https://central.sonatype.com/artifact/org.apache.maven/apache-maven/versions)). +Another option is to adjust the `distributionUrl` in `.mvn/wrapper/maven-wrapper.properties`. Debugging ---------