22
22
import javax .inject .Named ;
23
23
import javax .inject .Singleton ;
24
24
25
+ import java .util .ArrayDeque ;
26
+ import java .util .ArrayList ;
27
+ import java .util .Deque ;
28
+ import java .util .HashMap ;
29
+ import java .util .HashSet ;
25
30
import java .util .LinkedHashMap ;
26
31
import java .util .List ;
27
32
import java .util .Map ;
33
+ import java .util .Optional ;
28
34
import java .util .Set ;
35
+ import java .util .stream .Collectors ;
29
36
37
+ import org .apache .maven .RepositoryUtils ;
30
38
import org .apache .maven .artifact .Artifact ;
31
39
import org .apache .maven .artifact .DefaultArtifact ;
32
40
import org .apache .maven .artifact .handler .manager .ArtifactHandlerManager ;
33
41
import org .apache .maven .artifact .versioning .VersionRange ;
42
+ import org .apache .maven .model .DependencyManagement ;
34
43
import org .apache .maven .plugins .assembly .AssemblerConfigurationSource ;
35
44
import org .apache .maven .plugins .assembly .archive .ArchiveCreationException ;
36
45
import org .apache .maven .plugins .assembly .archive .phase .ModuleSetAssemblyPhase ;
40
49
import org .apache .maven .plugins .assembly .model .ModuleSet ;
41
50
import org .apache .maven .project .MavenProject ;
42
51
import org .codehaus .plexus .util .StringUtils ;
52
+ import org .eclipse .aether .RepositorySystem ;
53
+ import org .eclipse .aether .RepositorySystemSession ;
54
+ import org .eclipse .aether .collection .CollectRequest ;
55
+ import org .eclipse .aether .graph .DefaultDependencyNode ;
56
+ import org .eclipse .aether .graph .Dependency ;
57
+ import org .eclipse .aether .graph .DependencyFilter ;
58
+ import org .eclipse .aether .graph .DependencyNode ;
59
+ import org .eclipse .aether .graph .DependencyVisitor ;
60
+ import org .eclipse .aether .resolution .DependencyRequest ;
61
+ import org .eclipse .aether .resolution .DependencyResult ;
62
+ import org .eclipse .aether .util .filter .DependencyFilterUtils ;
43
63
import org .slf4j .Logger ;
44
64
import org .slf4j .LoggerFactory ;
45
65
46
66
import static java .util .Objects .requireNonNull ;
47
67
48
68
/**
49
69
* @author jdcasey
50
- *
51
70
*/
52
71
@ Singleton
53
72
@ Named
@@ -56,9 +75,12 @@ public class DefaultDependencyResolver implements DependencyResolver {
56
75
57
76
private final ArtifactHandlerManager artifactHandlerManager ;
58
77
78
+ private final RepositorySystem repositorySystem ;
79
+
59
80
@ Inject
60
- public DefaultDependencyResolver (ArtifactHandlerManager artifactHandlerManager ) {
81
+ public DefaultDependencyResolver (ArtifactHandlerManager artifactHandlerManager , RepositorySystem repositorySystem ) {
61
82
this .artifactHandlerManager = requireNonNull (artifactHandlerManager );
83
+ this .repositorySystem = requireNonNull (repositorySystem );
62
84
}
63
85
64
86
@ Override
@@ -75,7 +97,8 @@ public Map<DependencySet, Set<Artifact>> resolveDependencySets(
75
97
final MavenProject currentProject = configSource .getProject ();
76
98
77
99
final ResolutionManagementInfo info = new ResolutionManagementInfo ();
78
- updateDependencySetResolutionRequirements (dependencySet , info , currentProject );
100
+ updateDependencySetResolutionRequirements (
101
+ configSource .getMavenSession ().getRepositorySession (), dependencySet , info , currentProject );
79
102
updateModuleSetResolutionRequirements (moduleSet , dependencySet , info , configSource );
80
103
81
104
result .put (dependencySet , info .getArtifacts ());
@@ -96,7 +119,8 @@ public Map<DependencySet, Set<Artifact>> resolveDependencySets(
96
119
final MavenProject currentProject = configSource .getProject ();
97
120
98
121
final ResolutionManagementInfo info = new ResolutionManagementInfo ();
99
- updateDependencySetResolutionRequirements (dependencySet , info , currentProject );
122
+ updateDependencySetResolutionRequirements (
123
+ configSource .getMavenSession ().getRepositorySession (), dependencySet , info , currentProject );
100
124
101
125
result .put (dependencySet , info .getArtifacts ());
102
126
}
@@ -127,7 +151,10 @@ void updateModuleSetResolutionRequirements(
127
151
128
152
if (binaries .isIncludeDependencies ()) {
129
153
updateDependencySetResolutionRequirements (
130
- dependencySet , requirements , projects .toArray (new MavenProject [0 ]));
154
+ configSource .getMavenSession ().getRepositorySession (),
155
+ dependencySet ,
156
+ requirements ,
157
+ projects .toArray (new MavenProject [0 ]));
131
158
}
132
159
}
133
160
}
@@ -149,7 +176,10 @@ private Artifact createArtifact(String groupId, String artifactId, String versio
149
176
}
150
177
151
178
void updateDependencySetResolutionRequirements (
152
- final DependencySet set , final ResolutionManagementInfo requirements , final MavenProject ... projects )
179
+ RepositorySystemSession systemSession ,
180
+ final DependencySet set ,
181
+ final ResolutionManagementInfo requirements ,
182
+ final MavenProject ... projects )
153
183
throws DependencyResolutionException {
154
184
for (final MavenProject project : projects ) {
155
185
if (project == null ) {
@@ -158,14 +188,91 @@ void updateDependencySetResolutionRequirements(
158
188
159
189
Set <Artifact > dependencyArtifacts = null ;
160
190
if (set .isUseTransitiveDependencies ()) {
161
- dependencyArtifacts = project .getArtifacts ();
191
+ try {
192
+ // we need resolve project again according to requested scope
193
+ dependencyArtifacts = resolveTransitive (systemSession , set .getScope (), project );
194
+ } catch (org .eclipse .aether .resolution .DependencyResolutionException e ) {
195
+ throw new DependencyResolutionException (e .getMessage (), e );
196
+ }
162
197
} else {
198
+ // FIXME remove using deprecated method
163
199
dependencyArtifacts = project .getDependencyArtifacts ();
164
200
}
165
201
166
202
requirements .addArtifacts (dependencyArtifacts );
167
- LOGGER .debug ("Dependencies for project: " + project .getId () + " are:\n "
168
- + StringUtils .join (dependencyArtifacts .iterator (), "\n " ));
203
+ if (LOGGER .isDebugEnabled ()) {
204
+ LOGGER .debug (
205
+ "Dependencies for project: {} are:\n {}" ,
206
+ project .getId (),
207
+ StringUtils .join (dependencyArtifacts .iterator (), "\n " ));
208
+ }
169
209
}
170
210
}
211
+
212
+ private Set <Artifact > resolveTransitive (
213
+ RepositorySystemSession repositorySession , String scope , MavenProject project )
214
+ throws org .eclipse .aether .resolution .DependencyResolutionException {
215
+
216
+ // scope dependency filter
217
+ DependencyFilter scoopeDependencyFilter = DependencyFilterUtils .classpathFilter (scope );
218
+
219
+ // get project dependencies filtered by requested scope
220
+ List <Dependency > dependencies = project .getDependencies ().stream ()
221
+ .map (d -> RepositoryUtils .toDependency (d , repositorySession .getArtifactTypeRegistry ()))
222
+ .filter (d -> scoopeDependencyFilter .accept (new DefaultDependencyNode (d ), null ))
223
+ .collect (Collectors .toList ());
224
+
225
+ List <Dependency > managedDependencies = Optional .ofNullable (project .getDependencyManagement ())
226
+ .map (DependencyManagement ::getDependencies )
227
+ .map (list -> list .stream ()
228
+ .map (d -> RepositoryUtils .toDependency (d , repositorySession .getArtifactTypeRegistry ()))
229
+ .collect (Collectors .toList ()))
230
+ .orElse (null );
231
+
232
+ CollectRequest collectRequest = new CollectRequest ();
233
+ collectRequest .setManagedDependencies (managedDependencies );
234
+ collectRequest .setRepositories (project .getRemoteProjectRepositories ());
235
+ collectRequest .setDependencies (dependencies );
236
+ collectRequest .setRootArtifact (RepositoryUtils .toArtifact (project .getArtifact ()));
237
+
238
+ DependencyRequest request = new DependencyRequest (collectRequest , scoopeDependencyFilter );
239
+
240
+ DependencyResult dependencyResult = repositorySystem .resolveDependencies (repositorySession , request );
241
+
242
+ // cache for artifact mapping
243
+ Map <org .eclipse .aether .artifact .Artifact , Artifact > aetherToMavenArtifacts = new HashMap <>();
244
+ Deque <String > stack = new ArrayDeque <>();
245
+ stack .push (project .getArtifact ().getId ());
246
+
247
+ Set <Artifact > artifacts = new HashSet <>();
248
+
249
+ // we need rebuild artifact dependencyTrail - it is used by useTransitiveFiltering
250
+ dependencyResult .getRoot ().accept (new DependencyVisitor () {
251
+ @ Override
252
+ public boolean visitEnter (DependencyNode node ) {
253
+ if (node .getDependency () != null ) {
254
+ stack .push (aetherToMavenArtifacts
255
+ .computeIfAbsent (node .getDependency ().getArtifact (), RepositoryUtils ::toArtifact )
256
+ .getId ());
257
+ }
258
+ return true ;
259
+ }
260
+
261
+ @ Override
262
+ public boolean visitLeave (DependencyNode node ) {
263
+ if (node .getDependency () != null ) {
264
+ Artifact artifact = aetherToMavenArtifacts .computeIfAbsent (
265
+ node .getDependency ().getArtifact (), RepositoryUtils ::toArtifact );
266
+ List <String > depTrail = new ArrayList <>();
267
+ stack .descendingIterator ().forEachRemaining (depTrail ::add );
268
+ stack .pop ();
269
+ artifact .setDependencyTrail (depTrail );
270
+ artifacts .add (artifact );
271
+ }
272
+ return true ;
273
+ }
274
+ });
275
+
276
+ return artifacts ;
277
+ }
171
278
}
0 commit comments