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.assembly.archive.phase;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.nio.charset.StandardCharsets;
24  import java.nio.file.Files;
25  import java.util.Collections;
26  
27  import org.apache.maven.model.Model;
28  import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
29  import org.apache.maven.plugins.assembly.model.Assembly;
30  import org.apache.maven.plugins.assembly.model.FileItem;
31  import org.apache.maven.plugins.assembly.utils.TypeConversionUtils;
32  import org.apache.maven.project.MavenProject;
33  import org.codehaus.plexus.archiver.Archiver;
34  import org.codehaus.plexus.components.io.resources.PlexusIoResource;
35  import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
36  import org.junit.jupiter.api.Test;
37  import org.junit.jupiter.api.extension.ExtendWith;
38  import org.junit.jupiter.api.io.TempDir;
39  import org.mockito.junit.jupiter.MockitoExtension;
40  import org.mockito.junit.jupiter.MockitoSettings;
41  import org.mockito.quality.Strictness;
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  
45  import static org.mockito.ArgumentMatchers.any;
46  import static org.mockito.ArgumentMatchers.eq;
47  import static org.mockito.Mockito.mock;
48  import static org.mockito.Mockito.verify;
49  import static org.mockito.Mockito.when;
50  
51  @MockitoSettings(strictness = Strictness.WARN)
52  @ExtendWith(MockitoExtension.class)
53  public class FileItemAssemblyPhaseTest {
54      private final Logger logger = LoggerFactory.getLogger(getClass());
55  
56      @TempDir
57      private File temporaryFolder;
58  
59      @Test
60      public void testExecuteShouldAddNothingWhenNoFileItemsArePresent() throws Exception {
61          final AssemblerConfigurationSource macCS = mock(AssemblerConfigurationSource.class);
62  
63          final File basedir = temporaryFolder;
64  
65          when(macCS.getBasedir()).thenReturn(basedir);
66  
67          final Assembly assembly = new Assembly();
68          assembly.setId("test");
69  
70          new FileItemAssemblyPhase().execute(assembly, null, macCS);
71  
72          verify(macCS).getBasedir();
73      }
74  
75      @Test
76      public void testExecuteShouldAddAbsoluteFileNoFilterNoLineEndingConversion() throws Exception {
77          final AssemblerConfigurationSource macCS = mock(AssemblerConfigurationSource.class);
78  
79          final File basedir = temporaryFolder;
80  
81          final File file = newFile(temporaryFolder, "file.txt");
82          Files.write(file.toPath(), Collections.singletonList("This is a test file."), StandardCharsets.UTF_8);
83  
84          when(macCS.getBasedir()).thenReturn(basedir);
85          when(macCS.getProject()).thenReturn(new MavenProject(new Model()));
86          when(macCS.getFinalName()).thenReturn("final-name");
87          prepareInterpolators(macCS);
88  
89          final Archiver macArchiver = mock(Archiver.class);
90  
91          final Assembly assembly = new Assembly();
92          assembly.setId("test");
93  
94          final FileItem fi = new FileItem();
95          fi.setSource(file.getAbsolutePath());
96          fi.setFiltered(false);
97          fi.setLineEnding("keep");
98          fi.setFileMode("777");
99  
100         assembly.addFile(fi);
101 
102         new FileItemAssemblyPhase().execute(assembly, macArchiver, macCS);
103 
104         verify(macArchiver)
105                 .addResource(
106                         any(PlexusIoResource.class), eq("file.txt"), eq(TypeConversionUtils.modeToInt("777", logger)));
107     }
108 
109     @Test
110     public void testExecuteShouldAddRelativeFileNoFilterNoLineEndingConversion() throws Exception {
111         final AssemblerConfigurationSource macCS = mock(AssemblerConfigurationSource.class);
112 
113         final File basedir = temporaryFolder;
114 
115         final File file = newFile(temporaryFolder, "file.txt");
116         Files.write(file.toPath(), Collections.singletonList("This is a test file."), StandardCharsets.UTF_8);
117 
118         when(macCS.getBasedir()).thenReturn(basedir);
119         when(macCS.getProject()).thenReturn(new MavenProject(new Model()));
120         when(macCS.getFinalName()).thenReturn("final-name");
121         prepareInterpolators(macCS);
122 
123         final Archiver macArchiver = mock(Archiver.class);
124 
125         final Assembly assembly = new Assembly();
126         assembly.setId("test");
127 
128         final FileItem fi = new FileItem();
129         fi.setSource("file.txt");
130         fi.setFiltered(false);
131         fi.setLineEnding("keep");
132         fi.setFileMode("777");
133 
134         assembly.addFile(fi);
135 
136         new FileItemAssemblyPhase().execute(assembly, macArchiver, macCS);
137 
138         verify(macArchiver)
139                 .addResource(
140                         any(PlexusIoResource.class), eq("file.txt"), eq(TypeConversionUtils.modeToInt("777", logger)));
141     }
142 
143     @Test
144     public void testExecuteWithOutputDirectory() throws Exception {
145         final AssemblerConfigurationSource macCS = mock(AssemblerConfigurationSource.class);
146 
147         final File basedir = temporaryFolder;
148 
149         final File readmeFile = newFile(temporaryFolder, "README.txt");
150         Files.write(
151                 readmeFile.toPath(),
152                 Collections.singletonList("This is a test file for README.txt."),
153                 StandardCharsets.UTF_8);
154 
155         final File licenseFile = newFile(temporaryFolder, "LICENSE.txt");
156         Files.write(
157                 licenseFile.toPath(),
158                 Collections.singletonList("This is a test file for LICENSE.txt."),
159                 StandardCharsets.UTF_8);
160 
161         final File configFile = new File(newFolder(temporaryFolder, "config"), "config.txt");
162         Files.write(
163                 configFile.toPath(),
164                 Collections.singletonList("This is a test file for config/config.txt"),
165                 StandardCharsets.UTF_8);
166 
167         when(macCS.getBasedir()).thenReturn(basedir);
168         when(macCS.getProject()).thenReturn(new MavenProject(new Model()));
169         when(macCS.getFinalName()).thenReturn("final-name");
170         prepareInterpolators(macCS);
171 
172         final Archiver macArchiver = mock(Archiver.class);
173 
174         final Assembly assembly = new Assembly();
175         assembly.setId("test");
176         assembly.setIncludeBaseDirectory(true);
177 
178         final FileItem readmeFileItem = new FileItem();
179         readmeFileItem.setSource("README.txt");
180         readmeFileItem.setOutputDirectory("");
181         readmeFileItem.setFiltered(false);
182         readmeFileItem.setLineEnding("keep");
183         readmeFileItem.setFileMode("777");
184 
185         final FileItem licenseFileItem = new FileItem();
186         licenseFileItem.setSource("LICENSE.txt");
187         licenseFileItem.setOutputDirectory("/");
188         licenseFileItem.setFiltered(false);
189         licenseFileItem.setLineEnding("keep");
190         licenseFileItem.setFileMode("777");
191 
192         final FileItem configFileItem = new FileItem();
193         configFileItem.setSource("config/config.txt");
194         configFileItem.setOutputDirectory("config");
195         configFileItem.setFiltered(false);
196         configFileItem.setLineEnding("keep");
197         configFileItem.setFileMode("777");
198 
199         assembly.addFile(readmeFileItem);
200         assembly.addFile(licenseFileItem);
201         assembly.addFile(configFileItem);
202 
203         new FileItemAssemblyPhase().execute(assembly, macArchiver, macCS);
204 
205         verify(macArchiver)
206                 .addResource(
207                         any(PlexusIoResource.class),
208                         eq("README.txt"),
209                         eq(TypeConversionUtils.modeToInt("777", logger)));
210         verify(macArchiver)
211                 .addResource(
212                         any(PlexusIoResource.class),
213                         eq("LICENSE.txt"),
214                         eq(TypeConversionUtils.modeToInt("777", logger)));
215         verify(macArchiver)
216                 .addResource(
217                         any(PlexusIoResource.class),
218                         eq("config/config.txt"),
219                         eq(TypeConversionUtils.modeToInt("777", logger)));
220     }
221 
222     @Test
223     public void testExecuteWithOutputDirectoryAndDestName() throws Exception {
224         final AssemblerConfigurationSource macCS = mock(AssemblerConfigurationSource.class);
225 
226         final File basedir = temporaryFolder;
227 
228         final File readmeFile = newFile(temporaryFolder, "README.txt");
229         Files.write(
230                 readmeFile.toPath(),
231                 Collections.singletonList("This is a test file for README.txt."),
232                 StandardCharsets.UTF_8);
233 
234         final File licenseFile = newFile(temporaryFolder, "LICENSE.txt");
235         Files.write(
236                 licenseFile.toPath(),
237                 Collections.singletonList("This is a test file for LICENSE.txt."),
238                 StandardCharsets.UTF_8);
239 
240         final File configFile = new File(newFolder(temporaryFolder, "config"), "config.txt");
241         Files.write(
242                 configFile.toPath(),
243                 Collections.singletonList("This is a test file for config/config.txt"),
244                 StandardCharsets.UTF_8);
245 
246         when(macCS.getBasedir()).thenReturn(basedir);
247         when(macCS.getProject()).thenReturn(new MavenProject(new Model()));
248         when(macCS.getFinalName()).thenReturn("final-name");
249         prepareInterpolators(macCS);
250 
251         final Archiver macArchiver = mock(Archiver.class);
252 
253         final Assembly assembly = new Assembly();
254         assembly.setId("test");
255         assembly.setIncludeBaseDirectory(true);
256 
257         final FileItem readmeFileItem = new FileItem();
258         readmeFileItem.setSource("README.txt");
259         readmeFileItem.setOutputDirectory("");
260         readmeFileItem.setDestName("README_renamed.txt");
261         readmeFileItem.setFiltered(false);
262         readmeFileItem.setLineEnding("keep");
263         readmeFileItem.setFileMode("777");
264 
265         final FileItem licenseFileItem = new FileItem();
266         licenseFileItem.setSource("LICENSE.txt");
267         licenseFileItem.setOutputDirectory("/");
268         licenseFileItem.setDestName("LICENSE_renamed.txt");
269         licenseFileItem.setFiltered(false);
270         licenseFileItem.setLineEnding("keep");
271         licenseFileItem.setFileMode("777");
272 
273         final FileItem configFileItem = new FileItem();
274         configFileItem.setSource("config/config.txt");
275         configFileItem.setDestName("config_renamed.txt");
276         configFileItem.setOutputDirectory("config");
277         configFileItem.setFiltered(false);
278         configFileItem.setLineEnding("keep");
279         configFileItem.setFileMode("777");
280 
281         assembly.addFile(readmeFileItem);
282         assembly.addFile(licenseFileItem);
283         assembly.addFile(configFileItem);
284 
285         new FileItemAssemblyPhase().execute(assembly, macArchiver, macCS);
286 
287         verify(macArchiver)
288                 .addResource(
289                         any(PlexusIoResource.class),
290                         eq("README_renamed.txt"),
291                         eq(TypeConversionUtils.modeToInt("777", logger)));
292         verify(macArchiver)
293                 .addResource(
294                         any(PlexusIoResource.class),
295                         eq("LICENSE_renamed.txt"),
296                         eq(TypeConversionUtils.modeToInt("777", logger)));
297         verify(macArchiver)
298                 .addResource(
299                         any(PlexusIoResource.class),
300                         eq("config/config_renamed.txt"),
301                         eq(TypeConversionUtils.modeToInt("777", logger)));
302     }
303 
304     @Test
305     public void testExecuteWithOutputDirectoryAndDestNameAndIncludeBaseDirectoryFalse() throws Exception {
306         final AssemblerConfigurationSource macCS = mock(AssemblerConfigurationSource.class);
307 
308         final File basedir = temporaryFolder;
309 
310         final File readmeFile = newFile(temporaryFolder, "README.txt");
311         Files.write(
312                 readmeFile.toPath(),
313                 Collections.singletonList("This is a test file for README.txt."),
314                 StandardCharsets.UTF_8);
315 
316         final File licenseFile = newFile(temporaryFolder, "LICENSE.txt");
317         Files.write(
318                 licenseFile.toPath(),
319                 Collections.singletonList("This is a test file for LICENSE.txt."),
320                 StandardCharsets.UTF_8);
321 
322         final File configFile = new File(newFolder(temporaryFolder, "config"), "config.txt");
323         Files.write(
324                 configFile.toPath(),
325                 Collections.singletonList("This is a test file for config/config.txt"),
326                 StandardCharsets.UTF_8);
327 
328         when(macCS.getBasedir()).thenReturn(basedir);
329         when(macCS.getProject()).thenReturn(new MavenProject(new Model()));
330         when(macCS.getFinalName()).thenReturn("final-name");
331         prepareInterpolators(macCS);
332 
333         final Archiver macArchiver = mock(Archiver.class);
334 
335         final Assembly assembly = new Assembly();
336         assembly.setId("test");
337         assembly.setIncludeBaseDirectory(false);
338 
339         final FileItem readmeFileItem = new FileItem();
340         readmeFileItem.setSource("README.txt");
341         readmeFileItem.setDestName("README_renamed.txt");
342         readmeFileItem.setFiltered(false);
343         readmeFileItem.setLineEnding("keep");
344         readmeFileItem.setFileMode("777");
345 
346         final FileItem licenseFileItem = new FileItem();
347         licenseFileItem.setSource("LICENSE.txt");
348         licenseFileItem.setDestName("LICENSE_renamed.txt");
349         licenseFileItem.setFiltered(false);
350         licenseFileItem.setLineEnding("keep");
351         licenseFileItem.setFileMode("777");
352 
353         final FileItem configFileItem = new FileItem();
354         configFileItem.setSource("config/config.txt");
355         configFileItem.setDestName("config_renamed.txt");
356         configFileItem.setOutputDirectory("config");
357         configFileItem.setFiltered(false);
358         configFileItem.setLineEnding("keep");
359         configFileItem.setFileMode("777");
360 
361         assembly.addFile(readmeFileItem);
362         assembly.addFile(licenseFileItem);
363         assembly.addFile(configFileItem);
364 
365         new FileItemAssemblyPhase().execute(assembly, macArchiver, macCS);
366 
367         verify(macArchiver)
368                 .addResource(
369                         any(PlexusIoResource.class),
370                         eq("README_renamed.txt"),
371                         eq(TypeConversionUtils.modeToInt("777", logger)));
372         verify(macArchiver)
373                 .addResource(
374                         any(PlexusIoResource.class),
375                         eq("LICENSE_renamed.txt"),
376                         eq(TypeConversionUtils.modeToInt("777", logger)));
377         verify(macArchiver)
378                 .addResource(
379                         any(PlexusIoResource.class),
380                         eq("config/config_renamed.txt"),
381                         eq(TypeConversionUtils.modeToInt("777", logger)));
382     }
383 
384     private void prepareInterpolators(AssemblerConfigurationSource configSource) {
385         when(configSource.getCommandLinePropsInterpolator()).thenReturn(FixedStringSearchInterpolator.empty());
386         when(configSource.getEnvInterpolator()).thenReturn(FixedStringSearchInterpolator.empty());
387         when(configSource.getMainProjectInterpolator()).thenReturn(FixedStringSearchInterpolator.empty());
388     }
389 
390     private static File newFile(File parent, String child) throws IOException {
391         File result = new File(parent, child);
392         result.createNewFile();
393         return result;
394     }
395 
396     private static File newFolder(File root, String... subDirs) throws IOException {
397         String subFolder = String.join("/", subDirs);
398         File result = new File(root, subFolder);
399         if (!result.mkdirs()) {
400             throw new IOException("Couldn't create folders " + root);
401         }
402         return result;
403     }
404 }