diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java index 60757fa756b4..48b5ca0cc78b 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java @@ -612,25 +612,27 @@ Collection resolveArtifacts( * Shortcut for {@code getService(DependencyResolver.class).collect(...)} * * @param artifact artifact for which to get the dependencies, including transitive ones + * @param scope the {link PathScope} to collect dependencies, must not be {@code null} * @return root node of the dependency graph for the given artifact * - * @see org.apache.maven.api.services.DependencyResolver#collect(Session, Artifact) + * @see org.apache.maven.api.services.DependencyResolver#collect(Session, Artifact, PathScope) * @throws org.apache.maven.api.services.DependencyResolverException if the dependency collection failed */ @Nonnull - Node collectDependencies(@Nonnull Artifact artifact); + Node collectDependencies(@Nonnull Artifact artifact, @Nonnull PathScope scope); /** * Shortcut for {@code getService(DependencyResolver.class).collect(...)} * * @param project project for which to get the dependencies, including transitive ones + * @param scope the {link PathScope} to collect dependencies, must not be {@code null} * @return root node of the dependency graph for the given project * - * @see org.apache.maven.api.services.DependencyResolver#collect(Session, Project) + * @see org.apache.maven.api.services.DependencyResolver#collect(Session, Project, PathScope) * @throws org.apache.maven.api.services.DependencyResolverException if the dependency collection failed */ @Nonnull - Node collectDependencies(@Nonnull Project project); + Node collectDependencies(@Nonnull Project project, @Nonnull PathScope scope); /** * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is @@ -640,13 +642,14 @@ Collection resolveArtifacts( * Shortcut for {@code getService(DependencyResolver.class).resolve(...)} * * @param dependency dependency for which to get transitive dependencies + * @param scope the {link PathScope} to collect dependencies, must not be {@code null} * @return root node of the dependency graph for the given artifact * - * @see org.apache.maven.api.services.DependencyResolver#collect(Session, DependencyCoordinates) + * @see org.apache.maven.api.services.DependencyResolver#collect(Session, DependencyCoordinates, PathScope) * @throws org.apache.maven.api.services.DependencyResolverException if the dependency collection failed */ @Nonnull - Node collectDependencies(@Nonnull DependencyCoordinates dependency); + Node collectDependencies(@Nonnull DependencyCoordinates dependency, @Nonnull PathScope scope); /** * Shortcut for {@code getService(DependencyResolver.class).flatten(...)}. diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java index 1a217a5192d3..0473cce53708 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java @@ -29,6 +29,7 @@ import org.apache.maven.api.Session; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.annotations.Nullable; /** * Collects, flattens and resolves dependencies. @@ -37,56 +38,63 @@ public interface DependencyResolver extends Service { /** - * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is - * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the - * artifact files. + * Collects the transitive dependencies of some artifacts and builds a dependency graph for the given path scope. + * Note that this operation is only concerned about determining the coordinates of the transitive dependencies and + * does not actually resolve the artifact files. * * @param session the {@link Session}, must not be {@code null} * @param root the Maven Dependency, must not be {@code null} + * @param scope the {link PathScope} to collect dependencies, must not be {@code null} * @return the collection result, never {@code null} * @throws DependencyResolverException if the dependency tree could not be built * @throws IllegalArgumentException if an argument is null or invalid * @see #collect(DependencyResolverRequest) */ @Nonnull - default DependencyResolverResult collect(@Nonnull Session session, @Nonnull DependencyCoordinates root) { - return collect(DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.COLLECT, root)); + default DependencyResolverResult collect( + @Nonnull Session session, @Nonnull DependencyCoordinates root, @Nonnull PathScope scope) { + return collect( + DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.COLLECT, root, scope)); } /** - * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is - * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the - * artifact files. + * Collects the transitive dependencies of some artifacts and builds a dependency graph for the given path scope. + * Note that this operation is only concerned about determining the coordinates of the transitive dependencies and + * does not actually resolve the artifact files. * * @param session the {@link Session}, must not be {@code null} * @param project the {@link Project}, must not be {@code null} + * @param scope the {link PathScope} to collect dependencies, must not be {@code null} * @return the collection result, never {@code null} * @throws DependencyResolverException if the dependency tree could not be built * @throws IllegalArgumentException if an argument is null or invalid * @see #collect(DependencyResolverRequest) */ @Nonnull - default DependencyResolverResult collect(@Nonnull Session session, @Nonnull Project project) { - return collect( - DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.COLLECT, project)); + default DependencyResolverResult collect( + @Nonnull Session session, @Nonnull Project project, @Nonnull PathScope scope) { + return collect(DependencyResolverRequest.build( + session, DependencyResolverRequest.RequestType.COLLECT, project, scope)); } /** - * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is - * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the - * artifact files. + * Collects the transitive dependencies of some artifacts and builds a dependency graph for the given path scope. + * Note that this operation is only concerned about determining the coordinates of the transitive dependencies and + * does not actually resolve the artifact files. * * @param session the {@link Session}, must not be {@code null} * @param artifact the {@link Artifact}, must not be {@code null} + * @param scope the {link PathScope} to collect dependencies, must not be {@code null} * @return the collection result, never {@code null} * @throws DependencyResolverException if the dependency tree could not be built * @throws IllegalArgumentException if an argument is null or invalid * @see #collect(DependencyResolverRequest) */ @Nonnull - default DependencyResolverResult collect(@Nonnull Session session, @Nonnull Artifact artifact) { - return collect( - DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.COLLECT, artifact)); + default DependencyResolverResult collect( + @Nonnull Session session, @Nonnull Artifact artifact, @Nonnull PathScope scope) { + return collect(DependencyResolverRequest.build( + session, DependencyResolverRequest.RequestType.COLLECT, artifact, scope)); } /** @@ -99,9 +107,9 @@ default DependencyResolverResult collect(@Nonnull Session session, @Nonnull Arti * @throws DependencyResolverException if the dependency tree could not be built * @throws IllegalArgumentException if an argument is null or invalid * - * @see DependencyResolver#collect(Session, Project) - * @see DependencyResolver#collect(Session, DependencyCoordinates) - * @see DependencyResolver#collect(Session, Artifact) + * @see DependencyResolver#collect(Session, Project, PathScope) + * @see DependencyResolver#collect(Session, DependencyCoordinates, PathScope) + * @see DependencyResolver#collect(Session, Artifact, PathScope) */ @Nonnull default DependencyResolverResult collect(@Nonnull DependencyResolverRequest request) { @@ -113,20 +121,17 @@ default DependencyResolverResult collect(@Nonnull DependencyResolverRequest requ /** * Flattens a list of nodes. + * Note that the {@code PathScope} argument should usually be null as the dependency tree has been + * filtered during collection for the appropriate scope. * - * @param session - * @param node - * @param scope - * @return + * @param session the {@link Session}, must not be {@code null} + * @param node the {@link Node} to flatten, must not be {@code null} + * @param scope an optional {@link PathScope} to filter out dependencies + * @return the flattened list of node * @throws DependencyResolverException */ - List flatten(Session session, Node node, PathScope scope) throws DependencyResolverException; - - @Nonnull - default DependencyResolverResult flatten(@Nonnull Session session, @Nonnull Project project) { - return flatten( - DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.FLATTEN, project)); - } + List flatten(@Nonnull Session session, @Nonnull Node node, @Nullable PathScope scope) + throws DependencyResolverException; @Nonnull default DependencyResolverResult flatten( diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java index 928f99a7422e..6b0598e6055a 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java @@ -81,7 +81,7 @@ enum RequestType { boolean getVerbose(); - @Nullable + @Nonnull PathScope getPathScope(); /** @@ -105,11 +105,17 @@ static DependencyResolverRequestBuilder builder() { @Nonnull static DependencyResolverRequest build(Session session, RequestType requestType, Artifact rootArtifact) { + return build(session, requestType, rootArtifact, PathScope.MAIN_RUNTIME); + } + + @Nonnull + static DependencyResolverRequest build( + Session session, RequestType requestType, Artifact rootArtifact, PathScope scope) { return new DependencyResolverRequestBuilder() .session(session) .requestType(requestType) .rootArtifact(rootArtifact) - .pathScope(PathScope.MAIN_RUNTIME) + .pathScope(scope) .build(); } @@ -395,7 +401,7 @@ static class DefaultDependencyResolverRequest extends BaseRequest implements Dep this.managedDependencies = unmodifiable(nonNull(managedDependencies, "managedDependencies cannot be null")); this.verbose = verbose; - this.pathScope = pathScope; + this.pathScope = nonNull(pathScope, "pathScope cannot be null"); this.pathTypeFilter = (pathTypeFilter != null) ? pathTypeFilter : (t) -> true; this.repositories = repositories; if (verbose && requestType != RequestType.COLLECT) { diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java index b92ec7b8ee08..232f4026266b 100644 --- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java +++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java @@ -720,37 +720,42 @@ public DependencyCoordinates createDependencyCoordinates(@Nonnull Dependency dep * Shortcut for getService(DependencyResolver.class).collect(...) * * @throws DependencyResolverException if the dependency collection failed - * @see DependencyResolver#collect(Session, Artifact) + * @see DependencyResolver#collect(Session, Artifact, PathScope) */ @Nonnull @Override - public Node collectDependencies(@Nonnull Artifact artifact) { - return getService(DependencyResolver.class).collect(this, artifact).getRoot(); + public Node collectDependencies(@Nonnull Artifact artifact, @Nonnull PathScope scope) { + return getService(DependencyResolver.class) + .collect(this, artifact, scope) + .getRoot(); } /** * Shortcut for getService(DependencyResolver.class).collect(...) * * @throws DependencyResolverException if the dependency collection failed - * @see DependencyResolver#collect(Session, Project) + * @see DependencyResolver#collect(Session, Project, PathScope) */ @Nonnull @Override - public Node collectDependencies(@Nonnull Project project) { - return getService(DependencyResolver.class).collect(this, project).getRoot(); + public Node collectDependencies(@Nonnull Project project, @Nonnull PathScope scope) { + return getService(DependencyResolver.class) + .collect(this, project, scope) + .getRoot(); } /** * Shortcut for getService(DependencyResolver.class).collect(...) * * @throws DependencyResolverException if the dependency collection failed - * @see DependencyResolver#collect(Session, DependencyCoordinates) + * @see DependencyResolver#collect(Session, DependencyCoordinates, PathScope) */ @Nonnull @Override - public Node collectDependencies(@Nonnull DependencyCoordinates dependency) { - Node root = - getService(DependencyResolver.class).collect(this, dependency).getRoot(); + public Node collectDependencies(@Nonnull DependencyCoordinates dependency, @Nonnull PathScope scope) { + Node root = getService(DependencyResolver.class) + .collect(this, dependency, scope) + .getRoot(); return root.getChildren().iterator().next(); } diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java index 6675d7bf9670..d91d43dab2ea 100644 --- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java +++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java @@ -39,6 +39,7 @@ import org.apache.maven.api.RemoteRepository; import org.apache.maven.api.Session; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.di.Named; import org.apache.maven.api.di.Singleton; import org.apache.maven.api.services.ArtifactResolver; @@ -56,6 +57,7 @@ import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.graph.DependencyFilter; import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.scope.ResolutionScope; import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; import org.eclipse.aether.util.graph.transformer.ConflictResolver; @@ -96,12 +98,20 @@ public DependencyResolverResult collect(@Nonnull DependencyResolverRequest reque remoteRepositories = request.getRepositories() != null ? request.getRepositories() : session.getRemoteRepositories(); } + ResolutionScope resolutionScope = null; + if (request.getPathScope() != null) { + resolutionScope = session.getSession() + .getScopeManager() + .getResolutionScope(request.getPathScope().id()) + .orElseThrow(); + } CollectRequest collectRequest = new CollectRequest() .setRootArtifact(rootArtifact != null ? session.toArtifact(rootArtifact) : null) .setRoot(root != null ? session.toDependency(root, false) : null) .setDependencies(session.toDependencies(dependencies, false)) .setManagedDependencies(session.toDependencies(managedDependencies, true)) .setRepositories(session.toRepositories(remoteRepositories)); + collectRequest.setResolutionScope(resolutionScope); RepositorySystemSession systemSession = session.getSession(); if (request.getVerbose()) { @@ -120,8 +130,10 @@ public DependencyResolverResult collect(@Nonnull DependencyResolverRequest reque } } + @Nonnull @Override - public List flatten(Session s, Node node, PathScope scope) throws DependencyResolverException { + public List flatten(@Nonnull Session s, @Nonnull Node node, @Nullable PathScope scope) + throws DependencyResolverException { InternalSession session = InternalSession.from(s); DependencyNode root = cast(AbstractNode.class, node, "node").getDependencyNode(); List dependencies = session.getRepositorySystem() @@ -131,6 +143,9 @@ public List flatten(Session s, Node node, PathScope scope) throws Dependen } private static DependencyFilter getScopeDependencyFilter(PathScope scope) { + if (scope == null) { + return null; + } Set scopes = scope.dependencyScopes().stream().map(DependencyScope::id).collect(Collectors.toSet()); return (n, p) -> { diff --git a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java index 7259384c3309..e9eba6f5ef16 100644 --- a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java +++ b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java @@ -61,10 +61,12 @@ import org.apache.maven.internal.impl.AbstractSession; import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.internal.impl.di.SessionScope; +import org.apache.maven.internal.impl.resolver.scopes.Maven4ScopeManagerConfiguration; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.impl.RemoteRepositoryManager; +import org.eclipse.aether.internal.impl.scope.ScopeManagerImpl; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.LocalRepositoryManager; @@ -328,6 +330,7 @@ static Session newSession(RepositorySystem system, Lookup lookup) { : properties.containsKey("env.MAVEN_HOME") ? Paths.get(properties.get("env.MAVEN_HOME")) : null; DefaultRepositorySystemSession rsession = new DefaultRepositorySystemSession(h -> false); + rsession.setScopeManager(new ScopeManagerImpl(Maven4ScopeManagerConfiguration.INSTANCE)); rsession.setSystemProperties(properties); rsession.setConfigProperties(properties); diff --git a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/TestApiStandalone.java b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/TestApiStandalone.java index aa8a3db3e8ed..d6a6f29f1ebc 100644 --- a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/TestApiStandalone.java +++ b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/TestApiStandalone.java @@ -24,6 +24,7 @@ import org.apache.maven.api.ArtifactCoordinates; import org.apache.maven.api.DownloadedArtifact; import org.apache.maven.api.Node; +import org.apache.maven.api.PathScope; import org.apache.maven.api.Session; import org.apache.maven.api.services.ModelBuilder; import org.apache.maven.api.services.ModelBuilderRequest; @@ -58,8 +59,8 @@ void testStandalone() { assertNotNull(res.getPath()); assertTrue(Files.exists(res.getPath())); - Node node = session.collectDependencies(session.createDependencyCoordinates(coords)); + Node node = session.collectDependencies(session.createDependencyCoordinates(coords), PathScope.MAIN_RUNTIME); assertNotNull(node); - assertEquals(8, node.getChildren().size()); + assertEquals(6, node.getChildren().size()); } } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java index 76d359f46119..945fb1fa44a3 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java @@ -642,8 +642,9 @@ private T loadV4Mojo( } } else { // collection - DependencyResolverResult res = - sessionV4.getService(DependencyResolver.class).collect(sessionV4, project); + DependencyResolverResult res = sessionV4 + .getService(DependencyResolver.class) + .collect(sessionV4, project, PathScope.MAIN_RUNTIME); if (field.getType() == DependencyResolverResult.class) { result = res; } else if (field.getType() == Node.class) { diff --git a/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java b/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java index 68f8df087f1c..7f9177177ec5 100644 --- a/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java +++ b/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java @@ -176,7 +176,7 @@ void testBuildProject() { void testCollectArtifactDependencies() { Artifact artifact = session.createArtifact("org.codehaus.plexus", "plexus-container-default", "1.0-alpha-32", "jar"); - Node root = session.collectDependencies(artifact); + Node root = session.collectDependencies(artifact, PathScope.MAIN_RUNTIME); assertNotNull(root); } @@ -236,7 +236,7 @@ void testProjectDependencies() { assertNotNull(project); Artifact artifact = session.createArtifact("org.apache.maven.core.test", "test-extension", "1", "jar"); - Node root = session.collectDependencies(artifact); + Node root = session.collectDependencies(artifact, PathScope.MAIN_RUNTIME); assertNotNull(root); DependencyResolverResult result =