2222import javax .inject .Named ;
2323import javax .inject .Singleton ;
2424
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 ;
2530import java .util .LinkedHashMap ;
2631import java .util .List ;
2732import java .util .Map ;
33+ import java .util .Optional ;
2834import java .util .Set ;
35+ import java .util .stream .Collectors ;
2936
37+ import org .apache .maven .RepositoryUtils ;
3038import org .apache .maven .artifact .Artifact ;
3139import org .apache .maven .artifact .DefaultArtifact ;
3240import org .apache .maven .artifact .handler .manager .ArtifactHandlerManager ;
3341import org .apache .maven .artifact .versioning .VersionRange ;
42+ import org .apache .maven .model .DependencyManagement ;
3443import org .apache .maven .plugins .assembly .AssemblerConfigurationSource ;
3544import org .apache .maven .plugins .assembly .archive .ArchiveCreationException ;
3645import org .apache .maven .plugins .assembly .archive .phase .ModuleSetAssemblyPhase ;
4049import org .apache .maven .plugins .assembly .model .ModuleSet ;
4150import org .apache .maven .project .MavenProject ;
4251import 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 ;
4363import org .slf4j .Logger ;
4464import org .slf4j .LoggerFactory ;
4565
4666import static java .util .Objects .requireNonNull ;
4767
4868/**
4969 * @author jdcasey
50- *
5170 */
5271@ Singleton
5372@ Named
@@ -56,9 +75,12 @@ public class DefaultDependencyResolver implements DependencyResolver {
5675
5776 private final ArtifactHandlerManager artifactHandlerManager ;
5877
78+ private final RepositorySystem repositorySystem ;
79+
5980 @ Inject
60- public DefaultDependencyResolver (ArtifactHandlerManager artifactHandlerManager ) {
81+ public DefaultDependencyResolver (ArtifactHandlerManager artifactHandlerManager , RepositorySystem repositorySystem ) {
6182 this .artifactHandlerManager = requireNonNull (artifactHandlerManager );
83+ this .repositorySystem = requireNonNull (repositorySystem );
6284 }
6385
6486 @ Override
@@ -75,7 +97,8 @@ public Map<DependencySet, Set<Artifact>> resolveDependencySets(
7597 final MavenProject currentProject = configSource .getProject ();
7698
7799 final ResolutionManagementInfo info = new ResolutionManagementInfo ();
78- updateDependencySetResolutionRequirements (dependencySet , info , currentProject );
100+ updateDependencySetResolutionRequirements (
101+ configSource .getMavenSession ().getRepositorySession (), dependencySet , info , currentProject );
79102 updateModuleSetResolutionRequirements (moduleSet , dependencySet , info , configSource );
80103
81104 result .put (dependencySet , info .getArtifacts ());
@@ -96,7 +119,8 @@ public Map<DependencySet, Set<Artifact>> resolveDependencySets(
96119 final MavenProject currentProject = configSource .getProject ();
97120
98121 final ResolutionManagementInfo info = new ResolutionManagementInfo ();
99- updateDependencySetResolutionRequirements (dependencySet , info , currentProject );
122+ updateDependencySetResolutionRequirements (
123+ configSource .getMavenSession ().getRepositorySession (), dependencySet , info , currentProject );
100124
101125 result .put (dependencySet , info .getArtifacts ());
102126 }
@@ -127,7 +151,10 @@ void updateModuleSetResolutionRequirements(
127151
128152 if (binaries .isIncludeDependencies ()) {
129153 updateDependencySetResolutionRequirements (
130- dependencySet , requirements , projects .toArray (new MavenProject [0 ]));
154+ configSource .getMavenSession ().getRepositorySession (),
155+ dependencySet ,
156+ requirements ,
157+ projects .toArray (new MavenProject [0 ]));
131158 }
132159 }
133160 }
@@ -149,7 +176,10 @@ private Artifact createArtifact(String groupId, String artifactId, String versio
149176 }
150177
151178 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 )
153183 throws DependencyResolutionException {
154184 for (final MavenProject project : projects ) {
155185 if (project == null ) {
@@ -158,14 +188,91 @@ void updateDependencySetResolutionRequirements(
158188
159189 Set <Artifact > dependencyArtifacts = null ;
160190 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+ }
162197 } else {
198+ // FIXME remove using deprecated method
163199 dependencyArtifacts = project .getDependencyArtifacts ();
164200 }
165201
166202 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+ }
169209 }
170210 }
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+ }
171278}
0 commit comments