1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.assembly.archive.task;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.Properties;
27 import java.util.Set;
28
29 import org.apache.maven.artifact.Artifact;
30 import org.apache.maven.artifact.handler.ArtifactHandler;
31 import org.apache.maven.execution.MavenSession;
32 import org.apache.maven.model.Model;
33 import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
34 import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
35 import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
36 import org.apache.maven.plugins.assembly.archive.DefaultAssemblyArchiverTest;
37 import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
38 import org.apache.maven.plugins.assembly.model.DependencySet;
39 import org.apache.maven.plugins.assembly.model.UnpackOptions;
40 import org.apache.maven.project.DefaultProjectBuildingRequest;
41 import org.apache.maven.project.MavenProject;
42 import org.apache.maven.project.ProjectBuilder;
43 import org.apache.maven.project.ProjectBuildingException;
44 import org.apache.maven.project.ProjectBuildingRequest;
45 import org.apache.maven.project.ProjectBuildingResult;
46 import org.codehaus.plexus.archiver.ArchivedFileSet;
47 import org.codehaus.plexus.archiver.Archiver;
48 import org.codehaus.plexus.archiver.ArchiverException;
49 import org.codehaus.plexus.archiver.FileSet;
50 import org.junit.jupiter.api.Test;
51 import org.junit.jupiter.api.extension.ExtendWith;
52 import org.junit.jupiter.api.io.TempDir;
53 import org.mockito.ArgumentCaptor;
54 import org.mockito.junit.jupiter.MockitoExtension;
55 import org.mockito.junit.jupiter.MockitoSettings;
56 import org.mockito.quality.Strictness;
57
58 import static org.hamcrest.MatcherAssert.assertThat;
59 import static org.hamcrest.Matchers.is;
60 import static org.junit.jupiter.api.Assertions.assertEquals;
61 import static org.junit.jupiter.api.Assertions.assertNotNull;
62 import static org.junit.jupiter.api.Assertions.assertSame;
63 import static org.mockito.ArgumentMatchers.any;
64 import static org.mockito.ArgumentMatchers.isNull;
65 import static org.mockito.Mockito.atLeastOnce;
66 import static org.mockito.Mockito.mock;
67 import static org.mockito.Mockito.times;
68 import static org.mockito.Mockito.verify;
69 import static org.mockito.Mockito.when;
70
71 @MockitoSettings(strictness = Strictness.WARN)
72 @ExtendWith(MockitoExtension.class)
73 public class AddDependencySetsTaskTest {
74 @TempDir
75 private File temporaryFolder;
76
77 @Test
78 public void testAddDependencySetShouldInterpolateDefaultOutputFileNameMapping() throws Exception {
79 final String outDir = "tmp/";
80 final String mainAid = "main";
81 final String mainGid = "org.maingrp";
82 final String mainVer = "9";
83 final String depAid = "dep";
84 final String depGid = "org.depgrp";
85 final String depVer = "1";
86 final String depExt = "war";
87
88 final DependencySet ds = new DependencySet();
89 ds.setOutputDirectory(outDir);
90 ds.setDirectoryMode(Integer.toString(10, 8));
91 ds.setFileMode(Integer.toString(10, 8));
92
93 final Model mainModel = new Model();
94 mainModel.setArtifactId(mainAid);
95 mainModel.setGroupId(mainGid);
96 mainModel.setVersion(mainVer);
97
98 final MavenProject mainProject = new MavenProject(mainModel);
99
100 Artifact mainArtifact = mock(Artifact.class);
101 mainProject.setArtifact(mainArtifact);
102
103 final Model depModel = new Model();
104 depModel.setArtifactId(depAid);
105 depModel.setGroupId(depGid);
106 depModel.setVersion(depVer);
107 depModel.setPackaging(depExt);
108
109 final MavenProject depProject = new MavenProject(depModel);
110
111 Artifact depArtifact = mock(Artifact.class);
112 ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
113 when(artifactHandler.getExtension()).thenReturn(depExt);
114 when(depArtifact.getArtifactHandler()).thenReturn(artifactHandler);
115 final File newFile = File.createTempFile("junit", null, temporaryFolder);
116 when(depArtifact.getFile()).thenReturn(newFile);
117 when(depArtifact.getGroupId()).thenReturn("GROUPID");
118
119 depProject.setArtifact(depArtifact);
120
121 ProjectBuildingResult pbr = mock(ProjectBuildingResult.class);
122 when(pbr.getProject()).thenReturn(depProject);
123
124 final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
125 when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
126 .thenReturn(pbr);
127
128 final MavenSession session = mock(MavenSession.class);
129 when(session.getProjectBuildingRequest()).thenReturn(new DefaultProjectBuildingRequest());
130 when(session.getUserProperties()).thenReturn(new Properties());
131 when(session.getSystemProperties()).thenReturn(new Properties());
132
133 final AssemblerConfigurationSource configSource = mock(AssemblerConfigurationSource.class);
134 when(configSource.getFinalName()).thenReturn(mainAid + "-" + mainVer);
135 when(configSource.getProject()).thenReturn(mainProject);
136 when(configSource.getMavenSession()).thenReturn(session);
137
138 final Archiver archiver = mock(Archiver.class);
139 when(archiver.getDestFile()).thenReturn(new File("junk"));
140 when(archiver.getOverrideDirectoryMode()).thenReturn(0222);
141 when(archiver.getOverrideFileMode()).thenReturn(0222);
142
143 DefaultAssemblyArchiverTest.setupInterpolators(configSource, mainProject);
144
145 final AddDependencySetsTask task = new AddDependencySetsTask(
146 Collections.singletonList(ds), Collections.singleton(depArtifact), depProject, projectBuilder);
147
148 task.addDependencySet(ds, archiver, configSource);
149
150
151 verify(configSource).getFinalName();
152 verify(configSource, atLeastOnce()).getMavenSession();
153 verify(configSource, atLeastOnce()).getProject();
154
155 verify(archiver, atLeastOnce()).getDestFile();
156 verify(archiver).addFile(newFile, outDir + depAid + "-" + depVer + "." + depExt, 10);
157 verify(archiver).getOverrideDirectoryMode();
158 verify(archiver).getOverrideFileMode();
159 verify(archiver).setDirectoryMode(10);
160 verify(archiver).setDirectoryMode(146);
161 verify(archiver).setFileMode(10);
162 verify(archiver).setFileMode(146);
163
164 verify(session).getProjectBuildingRequest();
165 verify(session, times(2)).getUserProperties();
166 verify(session, times(2)).getSystemProperties();
167
168 verify(projectBuilder).build(any(Artifact.class), any(ProjectBuildingRequest.class));
169 }
170
171 @Test
172 public void testAddDependencySetShouldNotAddDependenciesWhenProjectHasNone() throws Exception {
173 final MavenProject project = new MavenProject(new Model());
174
175 final DependencySet ds = new DependencySet();
176 ds.setOutputDirectory("/out");
177
178 final AddDependencySetsTask task =
179 new AddDependencySetsTask(Collections.singletonList(ds), null, project, null);
180
181 task.addDependencySet(ds, null, null);
182 }
183
184
185 @Test
186 public void testAddDependencySetShouldNotAddDependenciesWhenProjectIsStubbed() throws Exception {
187 final MavenProject project = new MavenProject(new Model());
188
189 final ProjectBuildingException pbe = new ProjectBuildingException("test", "Test error.", new Throwable());
190
191 final String aid = "test-dep";
192 final String version = "2.0-SNAPSHOT";
193 final String type = "jar";
194
195 final File file = new File("dep-artifact.jar");
196
197 Artifact depArtifact = mock(Artifact.class);
198 when(depArtifact.getGroupId()).thenReturn("GROUPID");
199 when(depArtifact.getArtifactId()).thenReturn(aid);
200 when(depArtifact.getBaseVersion()).thenReturn(version);
201 when(depArtifact.getFile()).thenReturn(file);
202 ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
203 when(artifactHandler.getExtension()).thenReturn(type);
204 when(depArtifact.getArtifactHandler()).thenReturn(artifactHandler);
205
206 final File destFile = new File("assembly-dep-set.zip");
207
208 final Archiver archiver = mock(Archiver.class);
209 when(archiver.getDestFile()).thenReturn(destFile);
210 when(archiver.getOverrideDirectoryMode()).thenReturn(0222);
211 when(archiver.getOverrideFileMode()).thenReturn(0222);
212
213 final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
214 when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
215 .thenThrow(pbe);
216
217 final MavenSession session = mock(MavenSession.class);
218 when(session.getProjectBuildingRequest()).thenReturn(new DefaultProjectBuildingRequest());
219 when(session.getUserProperties()).thenReturn(new Properties());
220 when(session.getSystemProperties()).thenReturn(new Properties());
221
222 final AssemblerConfigurationSource configSource = mock(AssemblerConfigurationSource.class);
223 when(configSource.getFinalName()).thenReturn("final-name");
224 when(configSource.getMavenSession()).thenReturn(session);
225 when(configSource.getProject()).thenReturn(project);
226
227 final DependencySet ds = new DependencySet();
228 ds.setOutputDirectory("/out");
229 DefaultAssemblyArchiverTest.setupInterpolators(configSource, project);
230
231 final AddDependencySetsTask task = new AddDependencySetsTask(
232 Collections.singletonList(ds), Collections.singleton(depArtifact), project, projectBuilder);
233
234 task.addDependencySet(ds, archiver, configSource);
235
236
237 verify(configSource).getFinalName();
238 verify(configSource, atLeastOnce()).getMavenSession();
239 verify(configSource, atLeastOnce()).getProject();
240
241 verify(archiver).addFile(file, "out/" + aid + "-" + version + "." + type);
242 verify(archiver, atLeastOnce()).getDestFile();
243 verify(archiver).getOverrideDirectoryMode();
244 verify(archiver).getOverrideFileMode();
245
246 verify(session).getProjectBuildingRequest();
247 verify(session, times(2)).getUserProperties();
248 verify(session, times(2)).getSystemProperties();
249
250 verify(projectBuilder).build(any(Artifact.class), any(ProjectBuildingRequest.class));
251 }
252
253 @Test
254 public void testAddDependencySetShouldAddOneDependencyFromProjectWithoutUnpacking() throws Exception {
255 verifyOneDependencyAdded("out", false);
256 }
257
258 @Test
259 public void testAddDependencySetShouldAddOneDependencyFromProjectUnpacked() throws Exception {
260 verifyOneDependencyAdded("out", true);
261 }
262
263 private void verifyOneDependencyAdded(final String outputLocation, final boolean unpack)
264 throws AssemblyFormattingException, ArchiverException, ArchiveCreationException, IOException,
265 InvalidAssemblerConfigurationException, ProjectBuildingException {
266 final MavenProject project = new MavenProject(new Model());
267
268 final DependencySet ds = new DependencySet();
269 ds.setOutputDirectory(outputLocation);
270 ds.setOutputFileNameMapping("artifact");
271 ds.setUnpack(unpack);
272 ds.setScope(Artifact.SCOPE_COMPILE);
273
274 ds.setDirectoryMode(Integer.toString(10, 8));
275 ds.setFileMode(Integer.toString(10, 8));
276
277 final MavenSession session = mock(MavenSession.class);
278 when(session.getProjectBuildingRequest()).thenReturn(new DefaultProjectBuildingRequest());
279 when(session.getUserProperties()).thenReturn(new Properties());
280 when(session.getSystemProperties()).thenReturn(new Properties());
281
282 final AssemblerConfigurationSource configSource = mock(AssemblerConfigurationSource.class);
283 when(configSource.getMavenSession()).thenReturn(session);
284 when(configSource.getFinalName()).thenReturn("final-name");
285
286 Artifact artifact = mock(Artifact.class);
287 final File artifactFile = File.createTempFile("junit", null, temporaryFolder);
288 when(artifact.getFile()).thenReturn(artifactFile);
289 when(artifact.getGroupId()).thenReturn("GROUPID");
290
291 final Archiver archiver = mock(Archiver.class);
292 when(archiver.getDestFile()).thenReturn(new File("junk"));
293 when(archiver.getOverrideDirectoryMode()).thenReturn(0222);
294 when(archiver.getOverrideFileMode()).thenReturn(0222);
295
296 if (!unpack) {
297 when(configSource.getProject()).thenReturn(project);
298 }
299
300 final MavenProject depProject = new MavenProject(new Model());
301 depProject.setGroupId("GROUPID");
302
303 ProjectBuildingResult pbr = mock(ProjectBuildingResult.class);
304 when(pbr.getProject()).thenReturn(depProject);
305
306 final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
307 when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
308 .thenReturn(pbr);
309
310 final AddDependencySetsTask task = new AddDependencySetsTask(
311 Collections.singletonList(ds), Collections.singleton(artifact), project, projectBuilder);
312 DefaultAssemblyArchiverTest.setupInterpolators(configSource, project);
313
314 task.addDependencySet(ds, archiver, configSource);
315
316
317 verify(configSource).getFinalName();
318 verify(configSource, atLeastOnce()).getMavenSession();
319
320 verify(archiver, atLeastOnce()).getDestFile();
321 verify(archiver).getOverrideDirectoryMode();
322 verify(archiver).getOverrideFileMode();
323 verify(archiver).setFileMode(10);
324 verify(archiver).setFileMode(146);
325 verify(archiver).setDirectoryMode(10);
326 verify(archiver).setDirectoryMode(146);
327
328 verify(session).getProjectBuildingRequest();
329 verify(session, atLeastOnce()).getUserProperties();
330 verify(session, atLeastOnce()).getSystemProperties();
331
332 verify(projectBuilder).build(any(Artifact.class), any(ProjectBuildingRequest.class));
333
334 if (unpack) {
335 verify(archiver).addArchivedFileSet(any(ArchivedFileSet.class), isNull());
336 } else {
337 verify(archiver).addFile(artifactFile, outputLocation + "/artifact", 10);
338 verify(configSource, atLeastOnce()).getProject();
339 }
340 }
341
342 @Test
343 public void testGetDependencyArtifactsShouldGetOneDependencyArtifact() throws Exception {
344 final MavenProject project = new MavenProject(new Model());
345
346 Artifact artifact = mock(Artifact.class);
347 project.setArtifacts(Collections.singleton(artifact));
348
349 final DependencySet dependencySet = new DependencySet();
350
351 final AddDependencySetsTask task = new AddDependencySetsTask(
352 Collections.singletonList(dependencySet), Collections.singleton(artifact), project, null);
353
354 final Set<Artifact> result = task.resolveDependencyArtifacts(dependencySet);
355
356 assertNotNull(result);
357 assertEquals(1, result.size());
358 assertSame(artifact, result.iterator().next());
359 }
360
361 @Test
362 public void testGetDependencyArtifactsShouldFilterOneDependencyArtifactViaInclude() throws Exception {
363 final MavenProject project = new MavenProject(new Model());
364
365 final Set<Artifact> artifacts = new HashSet<>();
366
367 Artifact am1 = mock(Artifact.class);
368 when(am1.getGroupId()).thenReturn("group");
369 when(am1.getArtifactId()).thenReturn("artifact");
370 artifacts.add(am1);
371
372 Artifact am2 = mock(Artifact.class);
373 when(am2.getGroupId()).thenReturn("group2");
374 when(am2.getId()).thenReturn("group2:artifact2:1.0:jar");
375 artifacts.add(am2);
376
377 final DependencySet dependencySet = new DependencySet();
378
379 dependencySet.addInclude("group:artifact");
380 dependencySet.setUseTransitiveFiltering(true);
381
382 final AddDependencySetsTask task =
383 new AddDependencySetsTask(Collections.singletonList(dependencySet), artifacts, project, null);
384
385 final Set<Artifact> result = task.resolveDependencyArtifacts(dependencySet);
386
387 assertNotNull(result);
388 assertEquals(1, result.size());
389 assertSame(am1, result.iterator().next());
390 }
391
392 @Test
393 public void testGetDependencyArtifactsShouldIgnoreTransitivePathFilteringWhenIncludeNotTransitive()
394 throws Exception {
395 final MavenProject project = new MavenProject(new Model());
396
397 final Set<Artifact> artifacts = new HashSet<>();
398
399 Artifact am1 = mock(Artifact.class);
400 when(am1.getGroupId()).thenReturn("group");
401 when(am1.getArtifactId()).thenReturn("artifact");
402 artifacts.add(am1);
403
404 Artifact am2 = mock(Artifact.class);
405 when(am2.getGroupId()).thenReturn("group2");
406 when(am2.getId()).thenReturn("group2:artifact2:1.0:jar");
407 artifacts.add(am2);
408
409 final DependencySet dependencySet = new DependencySet();
410
411 dependencySet.addInclude("group:artifact");
412 dependencySet.setUseTransitiveFiltering(false);
413
414 final AddDependencySetsTask task =
415 new AddDependencySetsTask(Collections.singletonList(dependencySet), artifacts, project, null);
416
417 final Set<Artifact> result = task.resolveDependencyArtifacts(dependencySet);
418
419 assertNotNull(result);
420 assertEquals(1, result.size());
421 assertSame(am1, result.iterator().next());
422 }
423
424
425 @Test
426 public void useDefaultExcludes() throws Exception {
427 Artifact zipArtifact = mock(Artifact.class);
428 when(zipArtifact.getGroupId()).thenReturn("some-artifact");
429 when(zipArtifact.getArtifactId()).thenReturn("of-type-zip");
430 when(zipArtifact.getId()).thenReturn("some-artifact:of-type-zip:1.0:zip");
431 when(zipArtifact.getFile()).thenReturn(newFile(temporaryFolder, "of-type-zip.zip"));
432
433 Artifact dirArtifact = mock(Artifact.class);
434 when(dirArtifact.getGroupId()).thenReturn("some-artifact");
435 when(dirArtifact.getArtifactId()).thenReturn("of-type-zip");
436 when(dirArtifact.getId()).thenReturn("some-artifact:of-type-zip:1.0:dir");
437 when(dirArtifact.getFile()).thenReturn(newFolder(temporaryFolder, "of-type-zip"));
438
439 final Set<Artifact> artifacts = new HashSet<>(Arrays.asList(zipArtifact, dirArtifact));
440
441 final DependencySet dependencySet = new DependencySet();
442 dependencySet.setUseProjectArtifact(false);
443 dependencySet.setIncludes(Collections.singletonList("some-artifact:of-type-zip"));
444 dependencySet.setOutputDirectory("MyOutputDir");
445 dependencySet.setUnpack(true);
446 UnpackOptions unpackOptions = new UnpackOptions();
447 unpackOptions.setUseDefaultExcludes(false);
448 dependencySet.setUnpackOptions(unpackOptions);
449
450 final MavenProject project = new MavenProject(new Model());
451 project.setGroupId("GROUPID");
452
453 ProjectBuildingRequest pbReq = new DefaultProjectBuildingRequest();
454 ProjectBuildingResult pbRes = mock(ProjectBuildingResult.class);
455 when(pbRes.getProject()).thenReturn(project);
456
457 final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
458 when(projectBuilder.build(any(Artifact.class), any(ProjectBuildingRequest.class)))
459 .thenReturn(pbRes);
460
461 final AddDependencySetsTask task =
462 new AddDependencySetsTask(Collections.singletonList(dependencySet), artifacts, project, projectBuilder);
463
464 final MavenSession session = mock(MavenSession.class);
465 when(session.getProjectBuildingRequest()).thenReturn(pbReq);
466
467 final AssemblerConfigurationSource configSource = mock(AssemblerConfigurationSource.class);
468 when(configSource.getMavenSession()).thenReturn(session);
469 DefaultAssemblyArchiverTest.setupInterpolators(configSource, project);
470
471 final Archiver archiver = mock(Archiver.class);
472
473 task.addDependencySet(dependencySet, archiver, configSource);
474
475 ArgumentCaptor<ArchivedFileSet> archivedFileSet = ArgumentCaptor.forClass(ArchivedFileSet.class);
476 verify(archiver).addArchivedFileSet(archivedFileSet.capture(), isNull());
477 assertThat(archivedFileSet.getValue().isUsingDefaultExcludes(), is(false));
478
479 ArgumentCaptor<FileSet> fileSet = ArgumentCaptor.forClass(FileSet.class);
480 verify(archiver).addFileSet(fileSet.capture());
481 assertThat(fileSet.getValue().isUsingDefaultExcludes(), is(false));
482 }
483
484 private static File newFile(File parent, String child) throws IOException {
485 File result = new File(parent, child);
486 result.createNewFile();
487 return result;
488 }
489
490 private static File newFolder(File root, String... subDirs) throws IOException {
491 String subFolder = String.join("/", subDirs);
492 File result = new File(root, subFolder);
493 if (!result.mkdirs()) {
494 throw new IOException("Couldn't create folders " + root);
495 }
496 return result;
497 }
498 }