Skip to content

Commit c8a22b6

Browse files
authored
[MDEP-689] Fixes ignored dependency filtering in go-offline goal (#417)
1 parent d9ad8ee commit c8a22b6

File tree

14 files changed

+819
-43
lines changed

14 files changed

+819
-43
lines changed

pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ under the License.
5959
<contributor>
6060
<name>Maarten Mulders</name>
6161
</contributor>
62+
<contributor>
63+
<name>Lisa Hardy</name>
64+
</contributor>
6265
</contributors>
6366

6467
<prerequisites>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
invoker.goals = clean ${project.groupId}:${project.artifactId}:${project.version}:go-offline
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!--
4+
Licensed to the Apache Software Foundation (ASF) under one
5+
or more contributor license agreements. See the NOTICE file
6+
distributed with this work for additional information
7+
regarding copyright ownership. The ASF licenses this file
8+
to you under the Apache License, Version 2.0 (the
9+
"License"); you may not use this file except in compliance
10+
with the License. You may obtain a copy of the License at
11+
12+
http://www.apache.org/licenses/LICENSE-2.0
13+
14+
Unless required by applicable law or agreed to in writing,
15+
software distributed under the License is distributed on an
16+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
KIND, either express or implied. See the License for the
18+
specific language governing permissions and limitations
19+
under the License.
20+
-->
21+
22+
<project xmlns="http://maven.apache.org/POM/4.0.0"
23+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
24+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
25+
<modelVersion>4.0.0</modelVersion>
26+
<groupId>org.apache.maven.plugins.dependency</groupId>
27+
<artifactId>mdep-739-go-offline-respect-classifiers</artifactId>
28+
<version>1.0.0-SNAPSHOT</version>
29+
<description>Test that dependency:go-offline applies exclude filters</description>
30+
<dependencies>
31+
<dependency> <!-- excluded by excludeGroupId -->
32+
<groupId>skip.this.groupid</groupId>
33+
<artifactId>dummy-artifact</artifactId>
34+
<version>1.0</version>
35+
</dependency>
36+
<dependency> <!-- excluded by excludeGroupId -->
37+
<groupId>skip.this.groupid.too</groupId>
38+
<artifactId>dummy-artifact</artifactId>
39+
<version>1.0</version>
40+
</dependency>
41+
<dependency> <!-- excluded by excludeArtifactId -->
42+
<groupId>org.junit.jupiter</groupId>
43+
<artifactId>skip-this-artifact</artifactId>
44+
<version>1.0</version>
45+
</dependency>
46+
<dependency> <!-- excluded by excludeArtifactId -->
47+
<groupId>org.junit.jupiter</groupId>
48+
<artifactId>skip-this-artifact-too</artifactId>
49+
<version>1.0-SNAPSHOT</version>
50+
</dependency>
51+
<dependency> <!-- excluded by excludeClassifier -->
52+
<groupId>ch.qos.logback</groupId>
53+
<artifactId>logback-access</artifactId>
54+
<version>1.4.7</version>
55+
<classifier>skipThisClassifier</classifier>
56+
</dependency>
57+
<dependency> <!-- excluded by excludeClassifier -->
58+
<groupId>ch.qos.logback</groupId>
59+
<artifactId>logback-core</artifactId>
60+
<version>1.5.6</version>
61+
<classifier>skipThisClassifierToo</classifier>
62+
</dependency>
63+
<dependency><!-- should not be excluded -->
64+
<groupId>org.slf4j</groupId>
65+
<artifactId>slf4j-api</artifactId>
66+
<version>2.0.13</version>
67+
<scope>compile</scope>
68+
</dependency>
69+
<dependency> <!-- excluded by excludeScope -->
70+
<groupId>ch.qos.logback</groupId>
71+
<artifactId>logback-classic</artifactId>
72+
<version>1.5.4</version>
73+
<scope>system</scope>
74+
<!-- it doesn't matter what jar this points to, needs a systemPath to compile -->
75+
<systemPath>${project.build.directory}/local-repo/junit/junit/4.13.2/junit-4.13.2.jar</systemPath>
76+
</dependency>
77+
<dependency><!-- should not be excluded -->
78+
<groupId>org.slf4j</groupId>
79+
<artifactId>slf4j-simple</artifactId>
80+
<version>2.0.13</version>
81+
</dependency>
82+
<dependency> <!-- excluded by excludeType -->
83+
<groupId>ch.qos.logback</groupId>
84+
<artifactId>logback-examples</artifactId>
85+
<version>1.4.7</version>
86+
<type>ear</type>
87+
</dependency>
88+
</dependencies>
89+
<build>
90+
<pluginManagement>
91+
<plugins>
92+
<plugin>
93+
<artifactId>maven-dependency-plugin</artifactId>
94+
<version>@project.version@</version>
95+
<configuration>
96+
<excludeGroupIds>skip.this.groupid,skip.this.groupid.too</excludeGroupIds>
97+
<excludeArtifactIds>skip-this-artifact,skip-this-artifact-too</excludeArtifactIds>
98+
<!-- the maven-common-artifact-filters library does not support comma delimited
99+
scope exclusions. only one at a time. the other filters support comma delimited lists-->
100+
<!-- <excludeScope>compile,system</excludeScope> -->
101+
<excludeScope>system</excludeScope>
102+
<excludeTypes>ear</excludeTypes>
103+
<excludeClassifiers>skipThisClassifier,skipThisClassifierToo</excludeClassifiers>
104+
</configuration>
105+
</plugin>
106+
</plugins>
107+
</pluginManagement>
108+
</build>
109+
</project>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
File file = new File( basedir, "build.log" )
21+
assert file.exists()
22+
23+
String buildLog = file.getText( "UTF-8" )
24+
25+
// Make sure non-exluded explicit dependencies are resolved
26+
assert buildLog.contains( 'Resolved dependency: slf4j-simple-2.0.13.jar' )
27+
assert buildLog.contains( 'Resolved dependency: slf4j-api-2.0.13.jar' )
28+
29+
// Did group excludes work?
30+
assert !buildLog.contains( 'Resolving artifact skip.this.groupid' )
31+
32+
// Did artifact excludes work?
33+
assert !buildLog.contains( 'Resolving artifact org.junit.jupiter:skip-this-artifact' )
34+
35+
// Did scope exludes work?
36+
assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-classic' )
37+
38+
// Did type excludes work?
39+
assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-examples' )
40+
41+
// Did classifier excludes work?
42+
assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-core:jar:skipThisClassifierToo' )
43+
assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-core' )
44+
45+
assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-access:jar:skipThisClassifier' )
46+
assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-access' )
47+
48+
49+
50+
return true

src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj
136136

137137
/**
138138
* Scope threshold to exclude, if no value is defined for include.
139-
* An empty string indicates no dependencies (default).<br>
139+
* An empty string indicates no dependencies (default). Unlike the other
140+
* exclusion parameters, this property does not support a comma-delimited
141+
* list of scope exclusions. Just one scope may be excluded at a time.<br>
140142
* The scope threshold value being interpreted is the scope as
141143
* Maven filters for creating a classpath, not as specified in the pom. In summary:
142144
* <ul>

src/main/java/org/apache/maven/plugins/dependency/resolvers/AbstractResolveMojo.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@
2222

2323
import org.apache.maven.plugins.annotations.Parameter;
2424
import org.apache.maven.plugins.dependency.fromDependencies.AbstractDependencyFilterMojo;
25+
import org.apache.maven.plugins.dependency.utils.DependencyUtil;
26+
import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter;
27+
import org.apache.maven.shared.artifact.filter.collection.ClassifierFilter;
28+
import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
29+
import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter;
30+
import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
31+
import org.apache.maven.shared.artifact.filter.collection.TypeFilter;
2532

2633
/**
2734
* @author <a href="mailto:brianf@apache.org">Brian Fox</a>
@@ -52,4 +59,38 @@ public abstract class AbstractResolveMojo extends AbstractDependencyFilterMojo {
5259
*/
5360
@Parameter(property = "excludeReactor", defaultValue = "true")
5461
protected boolean excludeReactor;
62+
63+
/**
64+
* @return {@link FilterArtifacts}
65+
*/
66+
protected FilterArtifacts getArtifactsFilter() {
67+
final FilterArtifacts filter = new FilterArtifacts();
68+
69+
if (excludeReactor) {
70+
71+
filter.addFilter(new ExcludeReactorProjectsArtifactFilter(reactorProjects, getLog()));
72+
}
73+
74+
filter.addFilter(new ScopeFilter(
75+
DependencyUtil.cleanToBeTokenizedString(this.includeScope),
76+
DependencyUtil.cleanToBeTokenizedString(this.excludeScope)));
77+
78+
filter.addFilter(new TypeFilter(
79+
DependencyUtil.cleanToBeTokenizedString(this.includeTypes),
80+
DependencyUtil.cleanToBeTokenizedString(this.excludeTypes)));
81+
82+
filter.addFilter(new ClassifierFilter(
83+
DependencyUtil.cleanToBeTokenizedString(this.includeClassifiers),
84+
DependencyUtil.cleanToBeTokenizedString(this.excludeClassifiers)));
85+
86+
filter.addFilter(new GroupIdFilter(
87+
DependencyUtil.cleanToBeTokenizedString(this.includeGroupIds),
88+
DependencyUtil.cleanToBeTokenizedString(this.excludeGroupIds)));
89+
90+
filter.addFilter(new ArtifactIdFilter(
91+
DependencyUtil.cleanToBeTokenizedString(this.includeArtifactIds),
92+
DependencyUtil.cleanToBeTokenizedString(this.excludeArtifactIds)));
93+
94+
return filter;
95+
}
5596
}

src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,17 @@
2525
import java.util.stream.Collectors;
2626

2727
import org.apache.maven.artifact.Artifact;
28+
import org.apache.maven.artifact.DefaultArtifact;
29+
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
2830
import org.apache.maven.artifact.repository.ArtifactRepository;
2931
import org.apache.maven.model.Dependency;
3032
import org.apache.maven.plugin.MojoExecutionException;
3133
import org.apache.maven.plugins.annotations.Mojo;
3234
import org.apache.maven.plugins.dependency.utils.DependencyUtil;
3335
import org.apache.maven.project.ProjectBuildingRequest;
36+
import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
3437
import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
38+
import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
3539
import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
3640
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
3741
import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate;
@@ -43,6 +47,7 @@
4347
*
4448
* @author <a href="mailto:brianf@apache.org">Brian Fox</a>
4549
* @author Maarten Mulders
50+
* @author Lisa Hardy
4651
* @since 2.0
4752
*/
4853
@Mojo(name = "go-offline", threadSafe = true)
@@ -71,7 +76,7 @@ protected void doExecute() throws MojoExecutionException {
7176
}
7277
}
7378

74-
} catch (DependencyResolverException e) {
79+
} catch (DependencyResolverException | ArtifactFilterException e) {
7580
throw new MojoExecutionException(e.getMessage(), e);
7681
}
7782
}
@@ -81,10 +86,13 @@ protected void doExecute() throws MojoExecutionException {
8186
*
8287
* @return set of resolved dependency artifacts.
8388
* @throws DependencyResolverException in case of an error while resolving the artifacts.
89+
* @throws ArtifactFilterException
8490
*/
85-
protected Set<Artifact> resolveDependencyArtifacts() throws DependencyResolverException {
91+
protected Set<Artifact> resolveDependencyArtifacts() throws DependencyResolverException, ArtifactFilterException {
8692
Collection<Dependency> dependencies = getProject().getDependencies();
8793

94+
dependencies = filterDependencies(dependencies);
95+
8896
Set<DependableCoordinate> dependableCoordinates = dependencies.stream()
8997
.map(this::createDependendableCoordinateFromDependency)
9098
.collect(Collectors.toSet());
@@ -133,8 +141,9 @@ private TransformableFilter getTransformableFilter() {
133141
*
134142
* @return set of resolved plugin artifacts.
135143
* @throws DependencyResolverException in case of an error while resolving the artifacts.
144+
* @throws ArtifactFilterException
136145
*/
137-
protected Set<Artifact> resolvePluginArtifacts() throws DependencyResolverException {
146+
protected Set<Artifact> resolvePluginArtifacts() throws DependencyResolverException, ArtifactFilterException {
138147

139148
Set<Artifact> plugins = getProject().getPluginArtifacts();
140149
Set<Artifact> reports = getProject().getReportArtifacts();
@@ -143,6 +152,9 @@ protected Set<Artifact> resolvePluginArtifacts() throws DependencyResolverExcept
143152
artifacts.addAll(reports);
144153
artifacts.addAll(plugins);
145154

155+
final FilterArtifacts filter = getArtifactsFilter();
156+
artifacts = filter.filter(artifacts);
157+
146158
Set<DependableCoordinate> dependableCoordinates = artifacts.stream()
147159
.map(this::createDependendableCoordinateFromArtifact)
148160
.collect(Collectors.toSet());
@@ -152,6 +164,16 @@ protected Set<Artifact> resolvePluginArtifacts() throws DependencyResolverExcept
152164
return resolveDependableCoordinate(buildingRequest, dependableCoordinates, "plugins");
153165
}
154166

167+
private Collection<Dependency> filterDependencies(Collection<Dependency> deps) throws ArtifactFilterException {
168+
169+
Set<Artifact> artifacts = createArtifactSetFromDependencies(deps);
170+
171+
final FilterArtifacts filter = getArtifactsFilter();
172+
artifacts = filter.filter(artifacts);
173+
174+
return createDependencySetFromArtifacts(artifacts);
175+
}
176+
155177
private DependableCoordinate createDependendableCoordinateFromArtifact(final Artifact artifact) {
156178
final DefaultDependableCoordinate result = new DefaultDependableCoordinate();
157179
result.setGroupId(artifact.getGroupId());
@@ -174,6 +196,39 @@ private DependableCoordinate createDependendableCoordinateFromDependency(final D
174196
return result;
175197
}
176198

199+
private Set<Artifact> createArtifactSetFromDependencies(Collection<Dependency> deps) {
200+
Set<Artifact> artifacts = new HashSet<>();
201+
for (Dependency dep : deps) {
202+
DefaultArtifactHandler handler = new DefaultArtifactHandler(dep.getType());
203+
artifacts.add(new DefaultArtifact(
204+
dep.getGroupId(),
205+
dep.getArtifactId(),
206+
dep.getVersion(),
207+
dep.getScope(),
208+
dep.getType(),
209+
dep.getClassifier(),
210+
handler));
211+
}
212+
return artifacts;
213+
}
214+
215+
private Collection<Dependency> createDependencySetFromArtifacts(Set<Artifact> artifacts) {
216+
Set<Dependency> dependencies = new HashSet<>();
217+
218+
for (Artifact artifact : artifacts) {
219+
Dependency d = new Dependency();
220+
d.setGroupId(artifact.getGroupId());
221+
d.setArtifactId(artifact.getArtifactId());
222+
d.setVersion(artifact.getVersion());
223+
d.setType(artifact.getType());
224+
d.setClassifier(artifact.getClassifier());
225+
d.setScope(artifact.getScope());
226+
dependencies.add(d);
227+
}
228+
229+
return dependencies;
230+
}
231+
177232
@Override
178233
protected ArtifactsFilter getMarkedArtifactFilter() {
179234
return null;

0 commit comments

Comments
 (0)