Skip to content

Commit

Permalink
[MWRAPPER-141] Use distribution type of existing Maven Wrapper by def…
Browse files Browse the repository at this point in the history
…ault (#141)

Uses `distributionType` from `.mvn/wrapper/maven-wrapper.properties` by default, when present.

---

https://issues.apache.org/jira/browse/MWRAPPER-141
  • Loading branch information
breun authored May 21, 2024
1 parent 22147ea commit 038d300
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version='1.0' encoding='UTF-8'?>

<!--
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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.apache.maven.plugins.it.wrapper</groupId>
<artifactId>extension</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<properties>
<cmd></cmd>
</properties>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<executable>mvnw${cmd}</executable>
<arguments>
<argument>-v</argument>
</arguments>
<environmentVariables>
<MVNW_VERBOSE>true</MVNW_VERBOSE>
</environmentVariables>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>

<profiles>
<profile>
<id>windows</id>
<activation>
<os><family>windows</family></os>
</activation>
<properties>
<cmd>.cmd</cmd>
</properties>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -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")
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -84,7 +83,10 @@ public class WrapperMojo extends AbstractMojo {
private String mvndVersion;

/**
* The Maven Wrapper distribution type.
* <p>
* Options are:
*
* <dl>
* <dt>script</dt>
* <dd>only mvnw scripts</dd>
Expand All @@ -95,11 +97,16 @@ public class WrapperMojo extends AbstractMojo {
* <dt>only-script (default)</dt>
* <dd>the new lite implementation of mvnw/mvnw.cmd scripts downloads the maven directly and skips maven-wrapper.jar - since 3.2.0</dd>
* </dl>
* 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.
* <p>
* 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;

/**
Expand Down Expand Up @@ -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
Expand All @@ -168,27 +185,53 @@ public class WrapperMojo extends AbstractMojo {
private Map<String, UnArchiver> 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);
}
Expand Down Expand Up @@ -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) {
Expand Down
14 changes: 9 additions & 5 deletions maven-wrapper-plugin/src/site/markdown/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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
---------
Expand Down

0 comments on commit 038d300

Please sign in to comment.