Skip to content

Commit 7b86752

Browse files
Add range type in ignoreVersion
1 parent 0cafa40 commit 7b86752

File tree

15 files changed

+278
-71
lines changed

15 files changed

+278
-71
lines changed

Diff for: pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@
189189
<version>1.4.1</version>
190190
<scope>provided</scope>
191191
</dependency>
192+
<dependency>
193+
<groupId>org.apache.maven.resolver</groupId>
194+
<artifactId>maven-resolver-util</artifactId>
195+
<version>1.4.1</version>
196+
</dependency>
197+
192198
<dependency>
193199
<groupId>org.eclipse.sisu</groupId>
194200
<artifactId>org.eclipse.sisu.plexus</artifactId>

Diff for: versions-common/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@
8282
<groupId>javax.inject</groupId>
8383
<artifactId>javax.inject</artifactId>
8484
</dependency>
85+
86+
<dependency>
87+
<groupId>org.apache.maven.resolver</groupId>
88+
<artifactId>maven-resolver-util</artifactId>
89+
<scope>test</scope>
90+
</dependency>
8591
<dependency>
8692
<groupId>org.apache.maven.plugin-testing</groupId>
8793
<artifactId>maven-plugin-testing-harness</artifactId>

Diff for: versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java

+11-31
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,6 @@
108108
public class DefaultVersionsHelper implements VersionsHelper {
109109
private static final String CLASSPATH_PROTOCOL = "classpath";
110110

111-
private static final String TYPE_EXACT = "exact";
112-
113-
private static final String TYPE_REGEX = "regex";
114-
115111
private static final int LOOKUP_PARALLEL_THREADS = 5;
116112

117113
/**
@@ -258,8 +254,7 @@ public ArtifactVersions lookupArtifactVersions(
258254
try {
259255
Collection<IgnoreVersion> ignoredVersions = getIgnoredVersions(artifact);
260256
if (!ignoredVersions.isEmpty() && getLog().isDebugEnabled()) {
261-
getLog().debug("Found ignored versions: "
262-
+ ignoredVersions.stream().map(IgnoreVersion::toString).collect(Collectors.joining(", ")));
257+
getLog().debug("Found ignored versions: " + ignoredVersions + " for artifact" + artifact);
263258
}
264259

265260
final List<RemoteRepository> repositories;
@@ -292,21 +287,7 @@ public ArtifactVersions lookupArtifactVersions(
292287
.getVersions()
293288
.stream()
294289
.filter(v -> ignoredVersions.stream().noneMatch(i -> {
295-
if (TYPE_REGEX.equals(i.getType())
296-
&& Pattern.compile(i.getVersion())
297-
.matcher(v.toString())
298-
.matches()) {
299-
if (getLog().isDebugEnabled()) {
300-
getLog().debug("Version " + v + " for artifact "
301-
+ ArtifactUtils.versionlessKey(artifact)
302-
+ " found on ignore list: "
303-
+ i);
304-
}
305-
return true;
306-
}
307-
308-
if (TYPE_EXACT.equals(i.getType())
309-
&& i.getVersion().equals(v.toString())) {
290+
if (IgnoreVersionHelper.isVersionIgnored(v, i)) {
310291
if (getLog().isDebugEnabled()) {
311292
getLog().debug("Version " + v + " for artifact "
312293
+ ArtifactUtils.versionlessKey(artifact)
@@ -342,25 +323,24 @@ private List<IgnoreVersion> getIgnoredVersions(Artifact artifact) {
342323
final List<IgnoreVersion> ret = new ArrayList<>();
343324

344325
for (final IgnoreVersion ignoreVersion : ruleSet.getIgnoreVersions()) {
345-
if (!TYPE_EXACT.equals(ignoreVersion.getType()) && !TYPE_REGEX.equals(ignoreVersion.getType())) {
326+
if (IgnoreVersionHelper.isValidType(ignoreVersion)) {
327+
ret.add(ignoreVersion);
328+
} else {
346329
getLog().warn("The type attribute '" + ignoreVersion.getType() + "' for global ignoreVersion["
347-
+ ignoreVersion + "] is not valid." + " Please use either '" + TYPE_EXACT + "' or '"
348-
+ TYPE_REGEX
330+
+ ignoreVersion + "] is not valid. Please use one of '" + IgnoreVersionHelper.VALID_TYPES
349331
+ "'.");
350-
} else {
351-
ret.add(ignoreVersion);
352332
}
353333
}
354334

355335
final Rule rule = getBestFitRule(artifact.getGroupId(), artifact.getArtifactId());
356336

357337
if (rule != null) {
358338
for (IgnoreVersion ignoreVersion : rule.getIgnoreVersions()) {
359-
if (!TYPE_EXACT.equals(ignoreVersion.getType()) && !TYPE_REGEX.equals(ignoreVersion.getType())) {
360-
getLog().warn("The type attribute '" + ignoreVersion.getType() + "' for " + rule + " is not valid."
361-
+ " Please use either '" + TYPE_EXACT + "' or '" + TYPE_REGEX + "'.");
362-
} else {
339+
if (IgnoreVersionHelper.isValidType(ignoreVersion)) {
363340
ret.add(ignoreVersion);
341+
} else {
342+
getLog().warn("The type attribute '" + ignoreVersion.getType() + "' for " + rule + " is not valid."
343+
+ " Please use one of '" + IgnoreVersionHelper.VALID_TYPES + "'.");
364344
}
365345
}
366346
}
@@ -789,7 +769,7 @@ private static RuleSet enrichRuleSet(Collection<String> ignoredVersions, RuleSet
789769
.addAll(ignoredVersions.stream()
790770
.map(v -> {
791771
IgnoreVersion ignoreVersion = new IgnoreVersion();
792-
ignoreVersion.setType(TYPE_REGEX);
772+
ignoreVersion.setType(IgnoreVersion.TYPE_REGEX);
793773
ignoreVersion.setVersion(v);
794774
return ignoreVersion;
795775
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package org.codehaus.mojo.versions.api;
2+
3+
/*
4+
* Copyright MojoHaus and Contributors
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import java.util.Arrays;
19+
import java.util.Collections;
20+
import java.util.HashMap;
21+
import java.util.List;
22+
import java.util.Map;
23+
import java.util.function.BiFunction;
24+
import java.util.regex.Pattern;
25+
26+
import org.apache.maven.artifact.versioning.ArtifactVersion;
27+
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
28+
import org.apache.maven.artifact.versioning.VersionRange;
29+
import org.codehaus.mojo.versions.model.IgnoreVersion;
30+
import org.codehaus.mojo.versions.utils.DefaultArtifactVersionCache;
31+
import org.eclipse.aether.version.Version;
32+
33+
/**
34+
* Helper class for {@link IgnoreVersion}
35+
*/
36+
public class IgnoreVersionHelper {
37+
38+
static class IgnoreVersionException extends RuntimeException {
39+
IgnoreVersionException(Throwable cause) {
40+
super(cause);
41+
}
42+
}
43+
44+
public static final List<String> VALID_TYPES = Collections.unmodifiableList(
45+
Arrays.asList(IgnoreVersion.TYPE_EXACT, IgnoreVersion.TYPE_REGEX, IgnoreVersion.TYPE_RANGE));
46+
47+
private static final Map<String, BiFunction<Version, IgnoreVersion, Boolean>> VERSION_MATCHERS;
48+
49+
static {
50+
VERSION_MATCHERS = new HashMap<>();
51+
VERSION_MATCHERS.put(IgnoreVersion.TYPE_EXACT, IgnoreVersionHelper::isVersionIgnoredExact);
52+
VERSION_MATCHERS.put(IgnoreVersion.TYPE_REGEX, IgnoreVersionHelper::isVersionIgnoredRegex);
53+
VERSION_MATCHERS.put(IgnoreVersion.TYPE_RANGE, IgnoreVersionHelper::isVersionIgnoredRange);
54+
}
55+
56+
private IgnoreVersionHelper() {}
57+
58+
/**
59+
* Check if type for given ignoredVersion is valid.
60+
*
61+
* @param ignoreVersion an ignored version to check
62+
* @return true if type is valid
63+
*/
64+
public static boolean isValidType(IgnoreVersion ignoreVersion) {
65+
return VALID_TYPES.contains(ignoreVersion.getType());
66+
}
67+
68+
public static boolean isVersionIgnored(Version version, IgnoreVersion ignoreVersion) {
69+
return VERSION_MATCHERS.get(ignoreVersion.getType()).apply(version, ignoreVersion);
70+
}
71+
72+
private static boolean isVersionIgnoredExact(Version version, IgnoreVersion ignoreVersion) {
73+
return ignoreVersion.getVersion().equals(version.toString());
74+
}
75+
76+
private static boolean isVersionIgnoredRegex(Version version, IgnoreVersion ignoreVersion) {
77+
return Pattern.compile(ignoreVersion.getVersion())
78+
.matcher(version.toString())
79+
.matches();
80+
}
81+
82+
private static boolean isVersionIgnoredRange(Version version, IgnoreVersion ignoreVersion) {
83+
try {
84+
ArtifactVersion aVersion = DefaultArtifactVersionCache.of(version.toString());
85+
VersionRange versionRange = VersionRange.createFromVersionSpec(ignoreVersion.getVersion());
86+
if (versionRange.hasRestrictions()) {
87+
return versionRange.containsVersion(aVersion);
88+
} else {
89+
return versionRange.getRecommendedVersion().equals(aVersion);
90+
}
91+
} catch (InvalidVersionSpecificationException e) {
92+
throw new IgnoreVersionException(e);
93+
}
94+
}
95+
}

Diff for: versions-common/src/main/java/org/codehaus/mojo/versions/utils/DefaultArtifactVersionCache.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* Simple cache for {@link org.apache.maven.artifact.versioning.ArtifactVersion}
2929
*/
3030
public class DefaultArtifactVersionCache {
31-
private static final int MAX_CACHE_SIZE = 0x200;
31+
private static final int MAX_CACHE_SIZE = 512;
3232
private static final Map<String, DefaultArtifactVersion> CACHE = new LRUMap<>(MAX_CACHE_SIZE);
3333
private static final ReentrantReadWriteLock CACHE_LOCK = new ReentrantReadWriteLock();
3434

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package org.codehaus.mojo.versions.api;
2+
3+
/*
4+
* Copyright MojoHaus and Contributors
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import java.util.stream.Stream;
19+
20+
import org.codehaus.mojo.versions.model.IgnoreVersion;
21+
import org.eclipse.aether.util.version.GenericVersionScheme;
22+
import org.eclipse.aether.version.VersionScheme;
23+
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.params.ParameterizedTest;
25+
import org.junit.jupiter.params.provider.Arguments;
26+
import org.junit.jupiter.params.provider.MethodSource;
27+
28+
import static org.junit.jupiter.api.Assertions.assertEquals;
29+
import static org.junit.jupiter.api.Assertions.assertThrows;
30+
import static org.junit.jupiter.params.provider.Arguments.of;
31+
32+
class IgnoreVersionHelperTest {
33+
34+
private static final VersionScheme VERSION_SCHEME = new GenericVersionScheme();
35+
36+
static Stream<Arguments> ignoredTypeExact() {
37+
return Stream.of(of("1.0.0", "1.0.0", true), of("2.0.0", "1.0.0", false));
38+
}
39+
40+
@ParameterizedTest
41+
@MethodSource
42+
void ignoredTypeExact(String version, String ignore, boolean expected) throws Exception {
43+
44+
IgnoreVersion ignoreVersion = aIgnoreVersion(ignore, IgnoreVersion.TYPE_EXACT);
45+
46+
assertEquals(
47+
expected, IgnoreVersionHelper.isVersionIgnored(VERSION_SCHEME.parseVersion(version), ignoreVersion));
48+
}
49+
50+
public static Stream<Arguments> ignoredTypeRegex() {
51+
return Stream.of(
52+
of("1.0.0", "1\\.0\\..*", true),
53+
of("1.0.0-SNAPSHOT", ".*-SNAPSHOT", true),
54+
of("1.0.0", "2\\.0\\..*", false));
55+
}
56+
57+
@ParameterizedTest
58+
@MethodSource
59+
void ignoredTypeRegex(String version, String ignore, boolean expected) throws Exception {
60+
61+
IgnoreVersion ignoreVersion = aIgnoreVersion(ignore, IgnoreVersion.TYPE_REGEX);
62+
63+
assertEquals(
64+
expected, IgnoreVersionHelper.isVersionIgnored(VERSION_SCHEME.parseVersion(version), ignoreVersion));
65+
}
66+
67+
public static Stream<Arguments> ignoredTypeRange() {
68+
return Stream.of(
69+
of("1.0.0", "[1.0,)", true),
70+
of("1.0.0", "(,2.0.0]", true),
71+
of("2.2.0", "[1.0,3)", true),
72+
of("2.2.0", "[1.0,2.0)", false),
73+
of("2.2.0", "(,2.0.0]", false),
74+
of("1.0.0", "1.0.0", true),
75+
of("1.0.0", "1.0", true),
76+
of("1.0.1", "1.0", false),
77+
of("1.0.0", "2.0.0", false));
78+
}
79+
80+
@ParameterizedTest
81+
@MethodSource
82+
void ignoredTypeRange(String version, String ignore, boolean expected) throws Exception {
83+
84+
IgnoreVersion ignoreVersion = aIgnoreVersion(ignore, IgnoreVersion.TYPE_RANGE);
85+
86+
assertEquals(
87+
expected, IgnoreVersionHelper.isVersionIgnored(VERSION_SCHEME.parseVersion(version), ignoreVersion));
88+
}
89+
90+
@Test
91+
void invalidRangeShouldThrowException() throws Exception {
92+
IgnoreVersion ignoreVersion = aIgnoreVersion("[1,,", IgnoreVersion.TYPE_RANGE);
93+
94+
assertThrows(
95+
IgnoreVersionHelper.IgnoreVersionException.class,
96+
() -> IgnoreVersionHelper.isVersionIgnored(VERSION_SCHEME.parseVersion("1.0.0"), ignoreVersion));
97+
}
98+
99+
private IgnoreVersion aIgnoreVersion(String version, String type) {
100+
IgnoreVersion ignoreVersion = new IgnoreVersion();
101+
ignoreVersion.setVersion(version);
102+
ignoreVersion.setType(type);
103+
return ignoreVersion;
104+
}
105+
}

Diff for: versions-enforcer/src/main/java/org/codehaus/mojo/versions/enforcer/MaxDependencyUpdates.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ public class MaxDependencyUpdates extends AbstractEnforcerRule {
240240
* <p>Allows specifying the {@linkplain RuleSet} object describing rules
241241
* on artifact versions to ignore when considering updates.</p>
242242
*
243-
* @see <a href="https://www.mojohaus.org/versions-maven-plugin/version-rules.html#Using_the_ruleSet_element_in_the_POM">
243+
* @see <a href="https://www.mojohaus.org/versions/versions-maven-plugin/version-rules.html#Using_the_ruleSet_element_in_the_POM">
244244
* Using the ruleSet element in the POM</a>
245245
*
246246
* @since 2.14.0

Diff for: versions-maven-plugin/src/it/it-display-dependency-updates-issue-684-pom-based-rules/pom.xml

+18
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@
1212
<artifactId>dummy-api</artifactId>
1313
<version>1.1</version>
1414
</dependency>
15+
<dependency>
16+
<groupId>localhost</groupId>
17+
<artifactId>dummy-impl</artifactId>
18+
<version>1.0</version>
19+
</dependency>
1520
</dependencies>
21+
1622
<build>
1723
<pluginManagement>
1824
<plugins>
@@ -27,6 +33,18 @@
2733
<version>3.0</version>
2834
</ignoreVersion>
2935
</ignoreVersions>
36+
<rules>
37+
<rule>
38+
<groupId>localhost</groupId>
39+
<artifactId>dummy-impl</artifactId>
40+
<ignoreVersions>
41+
<ignoreVersion>
42+
<type>range</type>
43+
<version>[2.0,)</version>
44+
</ignoreVersion>
45+
</ignoreVersions>
46+
</rule>
47+
</rules>
3048
</ruleSet>
3149
</configuration>
3250
</plugin>
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
output = new File(basedir, "output1.txt").text
22
assert ! ( output =~ /\Qlocalhost:dummy-api\E\s*\.*\s*1\.1\s+->\s+3\.0\b/ )
33
assert output =~ /\Qlocalhost:dummy-api\E\s*\.*\s*1\.1\s+->\s+2\.1\b/
4+
assert output =~ /\Qlocalhost:dummy-impl\E\s*\.*\s*1\.0\s+->\s+1\.4\b/
45

56
output = new File(basedir, "output2.txt").text
67
assert ! ( output =~ /\Qlocalhost:dummy-api\E\s*\.*\s*1\.1\s+->\s+2\.1\b/ )
78
assert output =~ /\Qlocalhost:dummy-api\E\s*\.*\s*1\.1\s+->\s+2\.0\b/
9+
assert output =~ /\Qlocalhost:dummy-impl\E\s*\.*\s*1\.0\s+->\s+1\.4\b/

0 commit comments

Comments
 (0)