Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion maven-wrapper-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ under the License.
</prerequisites>

<properties>
<version.mockito>4.11.0</version.mockito>
<version.mockito>5.23.0</version.mockito>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumped to use mockStatic and mockConstruction

</properties>

<dependencies>
Expand Down Expand Up @@ -75,6 +75,12 @@ under the License.
<artifactId>plexus-io</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added since MetadataXpp3Reader.read() throws XmlPullParserException from this package.

<version>3.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-api</artifactId>
Expand Down Expand Up @@ -113,6 +119,11 @@ under the License.
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to use @ParameterizedTest

<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
66 changes: 66 additions & 0 deletions maven-wrapper-plugin/src/it/projects/mavenversion_range/pom.xml
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>mavenversion_range</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>@version.exec-maven-plugin@</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,18 @@
# 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.

maven=[3.0,3.10-rc\)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

/*
* 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, 'mvnwDebug' ).exists())
assert !(new File( basedir, 'mvnwDebug.cmd' ).exists())

def wrapperProperties = new File(basedir,'.mvn/wrapper/maven-wrapper.properties')
assert wrapperProperties.exists()

Properties props = new Properties()
wrapperProperties.withInputStream {
props.load(it)
}

// Assert that distribution URL was updated to the highest version automatically resolved
// in the specified range: [3.0,3.10-rc)
assert props.distributionUrl.endsWith("/org/apache/maven/apache-maven/3.9.16/apache-maven-3.9.16-bin.zip")

def log = new File(basedir, 'build.log').text
assert log.contains('Apache Maven 3.9.16')
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,32 @@
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.maven.Maven;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.components.io.fileselectors.FileSelector;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
Expand All @@ -49,6 +58,7 @@
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;

import static java.util.stream.Collectors.toList;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;

/**
Expand All @@ -69,9 +79,11 @@ public class WrapperMojo extends AbstractMojo {

/**
* The version of Maven to require, default value is the Runtime version of Maven.
* Can be any valid release above 2.0.9
* Can be any valid release above 2.0.9.
* Automatic version resolution is supported via {@link VersionRange} such as {@code [3.0,4.0-alpha)}.
*
* @since 3.0.0
* @see <a href="https://maven.apache.org/pom.html#Dependency_Version_Requirement_Specification">Dependency Version Requirement Specification</a>
*/
@Parameter(property = "maven")
private String mavenVersion;
Expand Down Expand Up @@ -211,15 +223,17 @@ public void execute() throws MojoExecutionException {
+ " cannot work with mvnd, please set type to '" + TYPE_ONLY_SCRIPT + "'.");
}

mavenVersion = getVersion(mavenVersion, Maven.class, "org.apache.maven/maven-core");
String repoUrl = getRepoUrl();
mavenVersion =
resolveVersionRange(getVersion(mavenVersion, Maven.class, "org.apache.maven/maven-core"), repoUrl);
String wrapperVersion = getVersion(null, this.getClass(), "org.apache.maven.plugins/maven-wrapper-plugin");

final Artifact artifact = downloadWrapperDistribution(wrapperVersion);

createDirectories(wrapperDir);
cleanup(wrapperDir);
unpack(artifact, baseDir);
replaceProperties(wrapperVersion, wrapperDir);
replaceProperties(wrapperVersion, wrapperDir, repoUrl);
}

private String determineDistributionType(final Path wrapperDir) {
Expand Down Expand Up @@ -303,11 +317,11 @@ private void unpack(Artifact artifact, Path targetFolder) {
*
* @param wrapperVersion the wrapper version
* @param targetFolder the folder containing the wrapper.properties
* @param repoUrl the repository url
* @throws MojoExecutionException if writing fails
*/
private void replaceProperties(String wrapperVersion, Path targetFolder) throws MojoExecutionException {
String repoUrl = getRepoUrl();

private void replaceProperties(String wrapperVersion, Path targetFolder, String repoUrl)
throws MojoExecutionException {
String finalDistributionUrl;
if (distributionUrl != null && !distributionUrl.trim().isEmpty()) {
// Use custom distribution URL if provided
Expand Down Expand Up @@ -376,6 +390,39 @@ private String getVersion(String defaultVersion, Class<?> clazz, String path) {
return version;
}

/**
* Resolves the actual Maven version to download, resolving the range
* provided in {@link WrapperMojo#mavenVersion}
*
* @param version the provided Maven version range
* @param repoUrl the repository url
*
* @return the highest available version according to the provided range
* @throws MojoExecutionException if the provided version range is invalid
*
* @see <a href="https://maven.apache.org/pom.html#Dependency_Version_Requirement_Specification">Dependency Version Requirement Specification</a>
*/
String resolveVersionRange(String version, String repoUrl) throws MojoExecutionException {
try {
VersionRange range = VersionRange.createFromVersionSpec(version);
if (range.getRecommendedVersion() != null) {
return version;
}

URI uri = URI.create(repoUrl + "/org/apache/maven/apache-maven/maven-metadata.xml");
Metadata metadata = new MetadataXpp3Reader().read(uri.toURL().openStream());
List<ArtifactVersion> versions = metadata.getVersioning().getVersions().stream()
.map(DefaultArtifactVersion::new)
.collect(toList());

return range.matchVersion(versions).toString();
} catch (IOException | XmlPullParserException e) {
return version;
} catch (InvalidVersionSpecificationException e) {
throw new MojoExecutionException("Invalid version specification: " + version, e);
}
}

/**
* Determine the repository URL to download Wrapper and Maven from.
*/
Expand Down
8 changes: 6 additions & 2 deletions maven-wrapper-plugin/src/site/markdown/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@ You can still use `-Dtype={type}` to change the distribution type for an existin
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.
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`.
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))
or a version range (see [Dependency Version Requirement Specification](https://maven.apache.org/pom.html#Dependency_Version_Requirement_Specification)).
In the latter case, mind that round brackets must be escaped with a backslash, as in `-Dmaven=[3.0,4.0\)`,
or the whole argument must be quoted: `-Dmaven="[3.0,4.0)"`.

Another option is to adjust the `distributionUrl` in `.mvn/wrapper/maven-wrapper.properties` with the specific version.

Debugging
---------
Expand Down
Loading