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.plugins.dependency.fromDependencies;
20  
21  import javax.inject.Inject;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.nio.file.Files;
26  import java.nio.file.Path;
27  import java.nio.file.Paths;
28  import java.util.Collection;
29  import java.util.Set;
30  
31  import org.apache.maven.api.plugin.testing.InjectMojo;
32  import org.apache.maven.api.plugin.testing.MojoParameter;
33  import org.apache.maven.api.plugin.testing.MojoTest;
34  import org.apache.maven.artifact.Artifact;
35  import org.apache.maven.artifact.metadata.ArtifactMetadata;
36  import org.apache.maven.artifact.repository.ArtifactRepository;
37  import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
38  import org.apache.maven.artifact.repository.MavenArtifactRepository;
39  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
40  import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
41  import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
42  import org.apache.maven.artifact.repository.metadata.Snapshot;
43  import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
44  import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
45  import org.apache.maven.artifact.versioning.VersionRange;
46  import org.apache.maven.bridge.MavenRepositorySystem;
47  import org.apache.maven.execution.MavenSession;
48  import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory;
49  import org.apache.maven.plugins.dependency.utils.DependencyUtil;
50  import org.apache.maven.project.DefaultProjectBuildingRequest;
51  import org.apache.maven.project.MavenProject;
52  import org.apache.maven.project.ProjectBuildingRequest;
53  import org.junit.jupiter.api.BeforeEach;
54  import org.junit.jupiter.api.Test;
55  import org.junit.jupiter.api.io.TempDir;
56  
57  import static org.junit.jupiter.api.Assertions.assertEquals;
58  import static org.junit.jupiter.api.Assertions.assertTrue;
59  import static org.mockito.Mockito.when;
60  
61  @MojoTest(realRepositorySession = true)
62  class TestCopyDependenciesMojo2 {
63  
64      @TempDir
65      private File tempDir;
66  
67      private DependencyArtifactStubFactory stubFactory;
68  
69      @Inject
70      private MavenSession session;
71  
72      @Inject
73      private MavenProject project;
74  
75      @Inject
76      private MavenRepositorySystem repositorySystem;
77  
78      @BeforeEach
79      void setUp() throws Exception {
80          stubFactory = new DependencyArtifactStubFactory(tempDir, true, false);
81  
82          Set<Artifact> artifacts = stubFactory.getScopedArtifacts();
83          Set<Artifact> directArtifacts = stubFactory.getReleaseAndSnapshotArtifacts();
84          artifacts.addAll(directArtifacts);
85          project.setArtifacts(artifacts);
86  
87          project.getBuild().setDirectory(new File(tempDir, "target").getAbsolutePath());
88      }
89  
90      @Test
91      @InjectMojo(goal = "copy-dependencies")
92      @MojoParameter(name = "includeScope", value = "compile")
93      void testCopyDependenciesMojoIncludeCompileScope(CopyDependenciesMojo mojo) throws Exception {
94          mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts());
95  
96          mojo.execute();
97  
98          ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.includeScope);
99  
100         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
101         for (Artifact artifact : artifacts) {
102             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
103             File file = new File(mojo.outputDirectory, fileName);
104 
105             assertEquals(saf.include(artifact), file.exists());
106         }
107     }
108 
109     @Test
110     @InjectMojo(goal = "copy-dependencies")
111     @MojoParameter(name = "includeScope", value = "test")
112     void testCopyDependenciesMojoIncludeTestScope(CopyDependenciesMojo mojo) throws Exception {
113         mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts());
114 
115         mojo.execute();
116 
117         ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.includeScope);
118 
119         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
120         for (Artifact artifact : artifacts) {
121             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
122             File file = new File(mojo.outputDirectory, fileName);
123 
124             assertEquals(saf.include(artifact), file.exists());
125         }
126     }
127 
128     @Test
129     @InjectMojo(goal = "copy-dependencies")
130     @MojoParameter(name = "includeScope", value = "runtime")
131     void testCopyDependenciesMojoIncludeRuntimeScope(CopyDependenciesMojo mojo) throws Exception {
132         mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts());
133 
134         mojo.execute();
135 
136         ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.includeScope);
137 
138         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
139         for (Artifact artifact : artifacts) {
140             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
141             File file = new File(mojo.outputDirectory, fileName);
142 
143             assertEquals(saf.include(artifact), file.exists());
144         }
145     }
146 
147     @Test
148     @InjectMojo(goal = "copy-dependencies")
149     @MojoParameter(name = "includeScope", value = "provided")
150     void testCopyDependenciesMojoIncludeprovidedScope(CopyDependenciesMojo mojo) throws Exception {
151         mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts());
152 
153         mojo.execute();
154 
155         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
156         for (Artifact artifact : artifacts) {
157             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
158             File file = new File(mojo.outputDirectory, fileName);
159 
160             assertEquals(Artifact.SCOPE_PROVIDED.equals(artifact.getScope()), file.exists());
161         }
162     }
163 
164     @Test
165     @InjectMojo(goal = "copy-dependencies")
166     @MojoParameter(name = "includeScope", value = "system")
167     void testCopyDependenciesMojoIncludesystemScope(CopyDependenciesMojo mojo) throws Exception {
168         mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts());
169 
170         mojo.execute();
171 
172         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
173         for (Artifact artifact : artifacts) {
174             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
175             File file = new File(mojo.outputDirectory, fileName);
176 
177             assertEquals(Artifact.SCOPE_SYSTEM.equals(artifact.getScope()), file.exists());
178         }
179     }
180 
181     @Test
182     @InjectMojo(goal = "copy-dependencies")
183     @MojoParameter(name = "useSubDirectoryPerArtifact", value = "true")
184     void testSubPerArtifact(CopyDependenciesMojo mojo) throws Exception {
185 
186         mojo.execute();
187 
188         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
189         for (Artifact artifact : artifacts) {
190             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
191             File folder = DependencyUtil.getFormattedOutputDirectory(
192                     false, false, true, false, false, false, mojo.outputDirectory, artifact);
193             File file = new File(folder, fileName);
194             assertTrue(file.exists());
195         }
196     }
197 
198     @Test
199     @InjectMojo(goal = "copy-dependencies")
200     @MojoParameter(name = "useSubDirectoryPerArtifact", value = "true")
201     @MojoParameter(name = "useSubDirectoryPerType", value = "true")
202     void testSubPerArtifactAndType(CopyDependenciesMojo mojo) throws Exception {
203         mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts());
204 
205         mojo.execute();
206 
207         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
208         for (Artifact artifact : artifacts) {
209             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
210             File folder = DependencyUtil.getFormattedOutputDirectory(
211                     false, true, true, false, false, false, mojo.outputDirectory, artifact);
212             File file = new File(folder, fileName);
213             assertTrue(file.exists());
214         }
215     }
216 
217     @Test
218     @InjectMojo(goal = "copy-dependencies")
219     @MojoParameter(name = "useSubDirectoryPerArtifact", value = "true")
220     @MojoParameter(name = "useSubDirectoryPerScope", value = "true")
221     void testSubPerArtifactAndScope(CopyDependenciesMojo mojo) throws Exception {
222         mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts());
223 
224         mojo.execute();
225 
226         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
227         for (Artifact artifact : artifacts) {
228             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
229             File folder = DependencyUtil.getFormattedOutputDirectory(
230                     true, false, true, false, false, false, mojo.outputDirectory, artifact);
231             File file = new File(folder, fileName);
232             assertTrue(file.exists());
233         }
234     }
235 
236     @Test
237     @InjectMojo(goal = "copy-dependencies")
238     void testRepositoryLayout(CopyDependenciesMojo mojo) throws Exception {
239 
240         ProjectBuildingRequest pbr = new DefaultProjectBuildingRequest();
241         pbr.setRepositorySession(session.getRepositorySession());
242         when(session.getProjectBuildingRequest()).thenReturn(pbr);
243 
244         String baseVersion = "2.0-SNAPSHOT";
245         String groupId = "testGroupId";
246         String artifactId = "expanded-snapshot";
247 
248         Artifact expandedSnapshot =
249                 createExpandedVersionArtifact(baseVersion, groupId, artifactId, "compile", "jar", null);
250 
251         mojo.getProject().getArtifacts().add(expandedSnapshot);
252 
253         Artifact pomExpandedSnapshot =
254                 createExpandedVersionArtifact(baseVersion, groupId, artifactId, "compile", "pom", null);
255         mojo.getProject().getArtifacts().add(pomExpandedSnapshot);
256 
257         mojo.useRepositoryLayout = true;
258         mojo.execute();
259 
260         File outputDirectory = mojo.outputDirectory;
261         ArtifactRepository targetRepository = new MavenArtifactRepository(
262                 "local",
263                 outputDirectory.toURI().toURL().toExternalForm(),
264                 new DefaultRepositoryLayout(),
265                 new ArtifactRepositoryPolicy(),
266                 new ArtifactRepositoryPolicy());
267 
268         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
269         File baseDirectory = Paths.get(targetRepository.getBasedir()).toFile();
270         assertTrue(baseDirectory.isDirectory());
271 
272         for (Artifact artifact : artifacts) {
273             assertArtifactExists(artifact, targetRepository);
274             if (!artifact.getBaseVersion().equals(artifact.getVersion())) {
275                 Artifact baseArtifact = repositorySystem.createArtifact(
276                         artifact.getGroupId(),
277                         artifact.getArtifactId(),
278                         artifact.getBaseVersion(),
279                         artifact.getScope(),
280                         artifact.getType());
281                 assertArtifactExists(baseArtifact, targetRepository);
282             }
283         }
284     }
285 
286     private Artifact createExpandedVersionArtifact(
287             String baseVersion, String groupId, String artifactId, String scope, String type, String classifier)
288             throws IOException {
289         Artifact expandedSnapshot = this.stubFactory.createArtifact(
290                 groupId, artifactId, VersionRange.createFromVersion(baseVersion), scope, type, classifier, false);
291 
292         Snapshot snapshot = new Snapshot();
293         snapshot.setTimestamp("20130710.122148");
294         snapshot.setBuildNumber(1);
295         RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata(expandedSnapshot, snapshot);
296         String newVersion = snapshot.getTimestamp() + "-" + snapshot.getBuildNumber();
297         expandedSnapshot.setResolvedVersion(baseVersion.replace(Artifact.SNAPSHOT_VERSION, newVersion));
298         expandedSnapshot.addMetadata(metadata);
299         return expandedSnapshot;
300     }
301 
302     private void assertArtifactExists(Artifact artifact, ArtifactRepository targetRepository) {
303 
304         ArtifactRepositoryLayout layout = targetRepository.getLayout();
305         String pathOf = layout.pathOf(artifact);
306 
307         // possible change/bug in DefaultArtifactRepositoryLayout.pathOf method between Maven 3 and Maven 3.1
308         pathOf = pathOf.replace("20130710.122148-1", "SNAPSHOT");
309 
310         File file = new File(targetRepository.getBasedir(), pathOf);
311 
312         Path targetPath = Paths.get(file.getParent());
313         assertTrue(Files.isDirectory(targetPath), "Target path doesn't exist: " + targetPath);
314 
315         assertTrue(file.exists(), "File doesn't exist: " + file.getAbsolutePath());
316 
317         Collection<ArtifactMetadata> metas = artifact.getMetadataList();
318         for (ArtifactMetadata meta : metas) {
319             File metaFile = new File(
320                     targetRepository.getBasedir(), layout.pathOfLocalRepositoryMetadata(meta, targetRepository));
321             assertTrue(metaFile.exists());
322         }
323     }
324 
325     @Test
326     @InjectMojo(goal = "copy-dependencies")
327     @MojoParameter(name = "useSubDirectoryPerArtifact", value = "true")
328     @MojoParameter(name = "stripVersion", value = "true")
329     void testSubPerArtifactRemoveVersion(CopyDependenciesMojo mojo) throws Exception {
330 
331         mojo.execute();
332 
333         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
334         for (Artifact artifact : artifacts) {
335             String fileName = DependencyUtil.getFormattedFileName(artifact, true);
336             File folder = DependencyUtil.getFormattedOutputDirectory(
337                     false, false, true, false, true, false, mojo.outputDirectory, artifact);
338             File file = new File(folder, fileName);
339             assertTrue(file.exists());
340         }
341     }
342 
343     @Test
344     @InjectMojo(goal = "copy-dependencies")
345     @MojoParameter(name = "useSubDirectoryPerArtifact", value = "true")
346     @MojoParameter(name = "useSubDirectoryPerType", value = "true")
347     @MojoParameter(name = "stripVersion", value = "true")
348     void testSubPerArtifactAndTypeRemoveVersion(CopyDependenciesMojo mojo) throws Exception {
349         mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts());
350 
351         mojo.execute();
352 
353         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
354         for (Artifact artifact : artifacts) {
355             String fileName = DependencyUtil.getFormattedFileName(artifact, true);
356             File folder = DependencyUtil.getFormattedOutputDirectory(
357                     false, true, true, false, true, false, mojo.outputDirectory, artifact);
358             File file = new File(folder, fileName);
359             assertTrue(file.exists());
360         }
361     }
362 
363     @Test
364     @InjectMojo(goal = "copy-dependencies")
365     @MojoParameter(name = "useSubDirectoryPerArtifact", value = "true")
366     @MojoParameter(name = "stripType", value = "true")
367     void testSubPerArtifactRemoveType(CopyDependenciesMojo mojo) throws Exception {
368 
369         mojo.execute();
370 
371         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
372         for (Artifact artifact : artifacts) {
373             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
374             File folder = DependencyUtil.getFormattedOutputDirectory(
375                     false, false, true, false, false, true, mojo.outputDirectory, artifact);
376             File file = new File(folder, fileName);
377             assertTrue(file.exists());
378         }
379     }
380 
381     @Test
382     @InjectMojo(goal = "copy-dependencies")
383     @MojoParameter(name = "useSubDirectoryPerArtifact", value = "true")
384     @MojoParameter(name = "useSubDirectoryPerType", value = "true")
385     @MojoParameter(name = "stripType", value = "true")
386     void testSubPerArtifactAndTypeRemoveType(CopyDependenciesMojo mojo) throws Exception {
387         mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts());
388 
389         mojo.execute();
390 
391         Set<Artifact> artifacts = mojo.getProject().getArtifacts();
392         for (Artifact artifact : artifacts) {
393             String fileName = DependencyUtil.getFormattedFileName(artifact, false);
394             File folder = DependencyUtil.getFormattedOutputDirectory(
395                     false, true, true, false, false, true, mojo.outputDirectory, artifact);
396             File file = new File(folder, fileName);
397             assertTrue(file.exists());
398         }
399     }
400 }