View Javadoc
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  package org.apache.maven.internal.impl;
20  
21  import javax.inject.Inject;
22  
23  import java.io.File;
24  import java.nio.file.Path;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.Collections;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Objects;
31  import java.util.Optional;
32  import java.util.stream.Collectors;
33  
34  import org.apache.maven.api.*;
35  import org.apache.maven.api.services.DependencyResolver;
36  import org.apache.maven.api.services.DependencyResolverResult;
37  import org.apache.maven.api.services.ProjectBuilder;
38  import org.apache.maven.api.services.ProjectBuilderRequest;
39  import org.apache.maven.api.services.SettingsBuilder;
40  import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
41  import org.apache.maven.bridge.MavenRepositorySystem;
42  import org.apache.maven.execution.DefaultMavenExecutionRequest;
43  import org.apache.maven.execution.DefaultMavenExecutionResult;
44  import org.apache.maven.execution.MavenSession;
45  import org.apache.maven.execution.scope.internal.MojoExecutionScope;
46  import org.apache.maven.repository.internal.MavenSessionBuilderSupplier;
47  import org.apache.maven.rtinfo.RuntimeInformation;
48  import org.apache.maven.session.scope.internal.SessionScope;
49  import org.apache.maven.toolchain.DefaultToolchainManagerPrivate;
50  import org.apache.maven.toolchain.building.ToolchainsBuilder;
51  import org.codehaus.plexus.PlexusContainer;
52  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
53  import org.codehaus.plexus.testing.PlexusTest;
54  import org.eclipse.aether.RepositorySystem;
55  import org.eclipse.aether.RepositorySystemSession;
56  import org.eclipse.aether.impl.MetadataGeneratorFactory;
57  import org.eclipse.aether.repository.LocalRepository;
58  import org.eclipse.aether.repository.RemoteRepository;
59  import org.junit.jupiter.api.BeforeEach;
60  import org.junit.jupiter.api.Test;
61  
62  import static org.junit.jupiter.api.Assertions.assertEquals;
63  import static org.junit.jupiter.api.Assertions.assertNotNull;
64  import static org.junit.jupiter.api.Assertions.assertNull;
65  import static org.junit.jupiter.api.Assertions.assertTrue;
66  
67  @PlexusTest
68  class TestApi {
69  
70      Session session;
71  
72      @Inject
73      RepositorySystem repositorySystem;
74  
75      @Inject
76      org.apache.maven.project.ProjectBuilder projectBuilder;
77  
78      @Inject
79      MavenRepositorySystem mavenRepositorySystem;
80  
81      @Inject
82      DefaultToolchainManagerPrivate toolchainManagerPrivate;
83  
84      @Inject
85      PlexusContainer plexusContainer;
86  
87      @Inject
88      MojoExecutionScope mojoExecutionScope;
89  
90      @Inject
91      RuntimeInformation runtimeInformation;
92  
93      @Inject
94      ArtifactHandlerManager artifactHandlerManager;
95  
96      @Inject
97      SessionScope sessionScope;
98  
99      @Inject
100     SettingsBuilder settingsBuilder;
101 
102     @Inject
103     ToolchainsBuilder toolchainsBuilder;
104 
105     @BeforeEach
106     void setup() {
107         // create session with any local repo, is redefined anyway below
108         RepositorySystemSession rss = new MavenSessionBuilderSupplier(repositorySystem)
109                 .get()
110                 .withLocalRepositoryBaseDirectories(new File("target").toPath())
111                 .build();
112         DefaultMavenExecutionRequest mer = new DefaultMavenExecutionRequest();
113         DefaultMavenExecutionResult meres = new DefaultMavenExecutionResult();
114         MavenSession ms = new MavenSession(rss, mer, meres);
115         DefaultSession session = new DefaultSession(
116                 ms,
117                 repositorySystem,
118                 Collections.emptyList(),
119                 mavenRepositorySystem,
120                 new DefaultLookup(plexusContainer),
121                 runtimeInformation);
122         DefaultLocalRepository localRepository =
123                 new DefaultLocalRepository(new LocalRepository("target/test-classes/apiv4-repo"));
124         org.apache.maven.api.RemoteRepository remoteRepository = session.getRemoteRepository(
125                 new RemoteRepository.Builder("mirror", "default", "file:target/test-classes/repo").build());
126         this.session = session.withLocalRepository(localRepository)
127                 .withRemoteRepositories(Collections.singletonList(remoteRepository));
128         InternalSession.associate(rss, this.session);
129         sessionScope.enter();
130         sessionScope.seed(InternalMavenSession.class, InternalMavenSession.from(this.session));
131     }
132 
133     private Project project(Artifact artifact) {
134         return session.getService(ProjectBuilder.class)
135                 .build(ProjectBuilderRequest.builder()
136                         .session(session)
137                         .path(session.getPathForLocalArtifact(artifact))
138                         .processPlugins(false)
139                         .build())
140                 .getProject()
141                 .get();
142     }
143 
144     @Test
145     void testCreateAndResolveArtifact() {
146         ArtifactCoordinate coord =
147                 session.createArtifactCoordinate("org.codehaus.plexus", "plexus-utils", "1.4.5", "pom");
148 
149         Map.Entry<Artifact, Path> resolved = session.resolveArtifact(coord);
150         assertNotNull(resolved);
151         assertNotNull(resolved.getKey());
152         assertNotNull(resolved.getValue());
153         Optional<Path> op = session.getArtifactPath(resolved.getKey());
154         assertTrue(op.isPresent());
155         assertEquals(resolved.getValue(), op.get());
156     }
157 
158     @Test
159     void testBuildProject() {
160         Artifact artifact = session.createArtifact("org.codehaus.plexus", "plexus-utils", "1.4.5", "pom");
161 
162         Project project = project(artifact);
163         assertNotNull(project);
164     }
165 
166     @Test
167     void testCollectArtifactDependencies() {
168         Artifact artifact =
169                 session.createArtifact("org.codehaus.plexus", "plexus-container-default", "1.0-alpha-32", "jar");
170         Node root = session.collectDependencies(artifact);
171         assertNotNull(root);
172     }
173 
174     @Test
175     void testResolveArtifactCoordinateDependencies() {
176         DependencyCoordinate coord = session.createDependencyCoordinate(
177                 session.createArtifactCoordinate("org.apache.maven.core.test", "test-extension", "1", "jar"));
178 
179         List<Path> paths = session.resolveDependencies(coord);
180 
181         assertNotNull(paths);
182         assertEquals(10, paths.size());
183         assertEquals("test-extension-1.jar", paths.get(0).getFileName().toString());
184 
185         // JUnit has an "Automatic-Module-Name", so it appears on the module path.
186         Map<PathType, List<Path>> dispatched = session.resolveDependencies(
187                 coord, PathScope.TEST_COMPILE, Arrays.asList(JavaPathType.CLASSES, JavaPathType.MODULES));
188         List<Path> classes = dispatched.get(JavaPathType.CLASSES);
189         List<Path> modules = dispatched.get(JavaPathType.MODULES);
190         List<Path> unresolved = dispatched.get(PathType.UNRESOLVED);
191         assertEquals(3, dispatched.size());
192         assertEquals(1, unresolved.size());
193         assertEquals(8, classes.size()); // "plexus.pom" and "junit.jar" are excluded.
194         assertEquals(1, modules.size());
195         assertEquals("plexus-1.0.11.pom", unresolved.get(0).getFileName().toString());
196         assertEquals("test-extension-1.jar", classes.get(0).getFileName().toString());
197         assertEquals("junit-4.13.1.jar", modules.get(0).getFileName().toString());
198         assertTrue(paths.containsAll(classes));
199         assertTrue(paths.containsAll(modules));
200 
201         // If caller wants only a classpath, JUnit shall move there.
202         dispatched = session.resolveDependencies(coord, PathScope.TEST_COMPILE, Arrays.asList(JavaPathType.CLASSES));
203         classes = dispatched.get(JavaPathType.CLASSES);
204         modules = dispatched.get(JavaPathType.MODULES);
205         unresolved = dispatched.get(PathType.UNRESOLVED);
206         assertEquals(2, dispatched.size());
207         assertEquals(1, unresolved.size());
208         assertEquals(9, classes.size());
209         assertNull(modules);
210         assertTrue(paths.containsAll(classes));
211         assertEquals("plexus-1.0.11.pom", unresolved.get(0).getFileName().toString());
212     }
213 
214     @Test
215     void testMetadataGeneratorFactory() throws ComponentLookupException {
216         List<MetadataGeneratorFactory> factories = plexusContainer.lookupList(MetadataGeneratorFactory.class);
217         assertNotNull(factories);
218         factories.forEach(f -> System.out.println(f.getClass().getName()));
219         assertEquals(3, factories.size());
220     }
221 
222     @Test
223     void testProjectDependencies() {
224         Artifact pom = session.createArtifact("org.codehaus.plexus", "plexus-container-default", "1.0-alpha-32", "pom");
225 
226         Project project = project(pom);
227         assertNotNull(project);
228 
229         Artifact artifact = session.createArtifact("org.apache.maven.core.test", "test-extension", "1", "jar");
230         Node root = session.collectDependencies(artifact);
231         assertNotNull(root);
232 
233         DependencyResolverResult result =
234                 session.getService(DependencyResolver.class).resolve(session, project, PathScope.MAIN_RUNTIME);
235         assertNotNull(result);
236         List<Dependency> deps = new ArrayList<>(result.getDependencies().keySet());
237         List<Dependency> deps2 = result.getNodes().stream()
238                 .map(Node::getDependency)
239                 .filter(Objects::nonNull)
240                 .collect(Collectors.toList());
241         assertEquals(deps, deps2);
242         for (Dependency dep : deps2) {
243             dep.getVersion();
244         }
245     }
246 }