IDEA-133754 Maven: resources builder: support outputDirectory parameters of maven...
[idea/community.git] / plugins / maven / src / test / java / org / jetbrains / idea / maven / compiler / ResourceCopyingTest.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.jetbrains.idea.maven.compiler;
17
18 import com.intellij.compiler.CompilerConfiguration;
19 import com.intellij.compiler.CompilerConfigurationImpl;
20 import com.intellij.openapi.application.AccessToken;
21 import com.intellij.openapi.application.WriteAction;
22 import com.intellij.openapi.command.WriteCommandAction;
23 import com.intellij.openapi.compiler.options.ExcludeEntryDescription;
24 import com.intellij.openapi.module.Module;
25 import com.intellij.openapi.module.ModuleManager;
26 import com.intellij.openapi.vfs.VirtualFile;
27 import com.intellij.testFramework.PsiTestUtil;
28
29 import java.io.File;
30
31 public class ResourceCopyingTest extends MavenCompilingTestCase {
32
33   @Override
34   protected void setUpInWriteAction() throws Exception {
35     super.setUpInWriteAction();
36
37     CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.xxx");
38     CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.yyy");
39     CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.zzz");
40   }
41
42   public void testBasic() throws Exception {
43     createProjectSubFile("src/main/resources/dir/file.properties");
44
45     importProject("<groupId>test</groupId>" +
46                   "<artifactId>project</artifactId>" +
47                   "<version>1</version>");
48     compileModules("project");
49
50     assertCopied("target/classes/dir/file.properties");
51   }
52
53   public void testCustomResources() throws Exception {
54     createProjectSubFile("res/dir1/file1.properties");
55     createProjectSubFile("testRes/dir2/file2.properties");
56
57     importProject("<groupId>test</groupId>" +
58                   "<artifactId>project</artifactId>" +
59                   "<version>1</version>" +
60
61                   "<build>" +
62                   "  <resources>" +
63                   "    <resource><directory>res</directory></resource>" +
64                   "  </resources>" +
65                   "  <testResources>" +
66                   "    <testResource><directory>testRes</directory></testResource>" +
67                   "  </testResources>" +
68                   "</build>");
69
70     compileModules("project");
71
72     assertCopied("target/classes/dir1/file1.properties");
73     assertCopied("target/test-classes/dir2/file2.properties");
74   }
75
76   public void testCustomTargetPath() throws Exception {
77     createProjectSubFile("res/dir/file.properties");
78
79     importProject("<groupId>test</groupId>" +
80                   "<artifactId>project</artifactId>" +
81                   "<version>1</version>" +
82
83                   "<build>" +
84                   "  <resources>" +
85                   "    <resource>" +
86                   "      <directory>res</directory>" +
87                   "      <targetPath>foo</targetPath>" +
88                   "    </resource>" +
89                   "  </resources>" +
90                   "</build>");
91
92     compileModules("project");
93     assertCopied("target/classes/foo/dir/file.properties");
94   }
95
96   public void testResourcesPluginCustomTargetPath() throws Exception {
97     createProjectSubFile("res/dir/file.properties");
98
99     importProject("<groupId>test</groupId>" +
100                   "<artifactId>project</artifactId>" +
101                   "<version>1</version>" +
102
103                   "<build>" +
104                   "  <plugins>" +
105                   "    <plugin>" +
106                   "      <artifactId>maven-resources-plugin</artifactId>" +
107                   "      <version>2.6</version>" +
108                   "      <configuration>" +
109                   "        <outputDirectory>${basedir}/target/resourceOutput</outputDirectory>" +
110                   "      </configuration>" +
111                   "    </plugin>" +
112                   "  </plugins>" +
113                   "  <resources>" +
114                   "    <resource>" +
115                   "      <directory>res</directory>" +
116                   "      <targetPath>foo</targetPath>" +
117                   "    </resource>" +
118                   "  </resources>" +
119                   "</build>");
120
121     compileModules("project");
122     assertCopied("target/resourceOutput/foo/dir/file.properties");
123   }
124
125   public void testResourcesPluginGoalAbsoluteCustomTargetPath() throws Exception {
126     createProjectSubFile("src/test/resources/dir/file.properties");
127
128     importProject("<groupId>test</groupId>" +
129                   "<artifactId>project</artifactId>" +
130                   "<version>1</version>" +
131
132                   "<build>" +
133                   "  <plugins>" +
134                   "    <plugin>" +
135                   "      <artifactId>maven-resources-plugin</artifactId>" +
136                   "      <version>2.6</version>" +
137                   "      <executions>" +
138                   "       <execution>" +
139                   "         <id>default-testResources</id>" +
140                   "         <phase>process-test-resources</phase>" +
141                   "         <goals>" +
142                   "           <goal>testResources</goal>" +
143                   "         </goals>" +
144                   "         <configuration>" +
145                   "           <outputDirectory>${project.build.testOutputDirectory}/custom</outputDirectory>" +
146                   "         </configuration>" +
147                   "       </execution>" +
148                   "      </executions>" +
149                   "    </plugin>" +
150                   "  </plugins>" +
151                   "</build>");
152
153     compileModules("project");
154     assertCopied("target/test-classes/custom/dir/file.properties");
155   }
156
157   public void testResourcesPluginGoalRelativeCustomTargetPath() throws Exception {
158     createProjectSubFile("src/test/resources/dir/file.properties");
159
160     importProject("<groupId>test</groupId>" +
161                   "<artifactId>project</artifactId>" +
162                   "<version>1</version>" +
163
164                   "<build>" +
165                   "  <plugins>" +
166                   "    <plugin>" +
167                   "      <artifactId>maven-resources-plugin</artifactId>" +
168                   "      <version>2.6</version>" +
169                   "      <executions>" +
170                   "       <execution>" +
171                   "         <id>default-testResources</id>" +
172                   "         <phase>process-test-resources</phase>" +
173                   "         <goals>" +
174                   "           <goal>testResources</goal>" +
175                   "         </goals>" +
176                   "         <configuration>" +
177                   "           <outputDirectory>target/test-classes/custom</outputDirectory>" +
178                   "         </configuration>" +
179                   "       </execution>" +
180                   "      </executions>" +
181                   "    </plugin>" +
182                   "  </plugins>" +
183                   "</build>");
184
185     compileModules("project");
186     assertCopied("target/test-classes/custom/dir/file.properties");
187   }
188
189   public void testAbsoluteCustomTargetPath() throws Exception {
190     createProjectSubFile("res/foo/file.properties");
191
192     importProject("<groupId>test</groupId>" +
193                   "<artifactId>project</artifactId>" +
194                   "<version>1</version>" +
195
196                   "<build>" +
197                   "  <resources>" +
198                   "    <resource>" +
199                   "      <directory>res</directory>" +
200                   "      <targetPath>${build.directory}/anotherDir</targetPath>" +
201                   "    </resource>" +
202                   "  </resources>" +
203                   "</build>");
204
205     compileModules("project");
206     assertCopied("target/anotherDir/foo/file.properties");
207   }
208
209   public void testMavenSpecifiedPattern() throws Exception {
210     createProjectSubFile("res/subdir/a.txt");
211     createProjectSubFile("res/b.txt");
212
213     importProject("<groupId>test</groupId>" +
214                   "<artifactId>project</artifactId>" +
215                   "<version>1</version>" +
216
217                   "<build>" +
218                   "  <resources>" +
219                   "    <resource>" +
220                   "      <directory>res</directory>" +
221                   "      <includes>" +
222                   "        <include>**/**</include>" +
223                   "      </includes>" +
224                   "    </resource>" +
225                   "  </resources>" +
226                   "</build>");
227
228     compileModules("project");
229
230     assertCopied("target/classes/subdir/a.txt");
231     assertCopied("target/classes/b.txt");
232   }
233
234   public void testMavenSpecifiedPatternEndSlash() throws Exception {
235     createProjectSubFile("res/subdir/a.txt");
236     createProjectSubFile("res/b.txt");
237
238     importProject("<groupId>test</groupId>" +
239                   "<artifactId>project</artifactId>" +
240                   "<version>1</version>" +
241
242                   "<build>" +
243                   "  <resources>" +
244                   "    <resource>" +
245                   "      <directory>res</directory>" +
246                   "      <includes>" +
247                   "        <include>**/</include>" +
248                   "      </includes>" +
249                   "    </resource>" +
250                   "  </resources>" +
251                   "</build>");
252
253     compileModules("project");
254
255     assertCopied("target/classes/subdir/a.txt");
256     assertCopied("target/classes/b.txt");
257   }
258
259   public void testIncludesAndExcludes() throws Exception {
260     createProjectSubFile("res/dir/file.xxx");
261     createProjectSubFile("res/dir/file.yyy");
262     createProjectSubFile("res/file.xxx");
263     createProjectSubFile("res/file.yyy");
264     createProjectSubFile("res/file.zzz");
265
266     importProject("<groupId>test</groupId>" +
267                   "<artifactId>project</artifactId>" +
268                   "<version>1</version>" +
269
270                   "<build>" +
271                   "  <resources>" +
272                   "    <resource>" +
273                   "      <directory>res</directory>" +
274                   "      <includes>" +
275                   "        <include>**/*.xxx</include>" +
276                   "        <include>**/*.yyy</include>" +
277                   "      </includes>" +
278                   "      <excludes>" +
279                   "        <exclude>*.xxx</exclude>" +
280                   "        <exclude>dir/*.yyy</exclude>" +
281                   "      </excludes>" +
282                   "    </resource>" +
283                   "  </resources>" +
284                   "</build>");
285
286     compileModules("project");
287
288     assertCopied("target/classes/dir/file.xxx");
289     assertNotCopied("target/classes/dir/file.yyy");
290     assertNotCopied("target/classes/file.xxx");
291     assertCopied("target/classes/file.yyy");
292     assertNotCopied("target/classes/file.zzz");
293   }
294
295   public void testDoNotCopyIgnoredFiles() throws Exception {
296     createProjectSubFile("res/CVS/file.properties");
297     createProjectSubFile("res/.svn/file.properties");
298     createProjectSubFile("res/zzz/file.properties");
299
300     importProject("<groupId>test</groupId>" +
301                   "<artifactId>project</artifactId>" +
302                   "<version>1</version>" +
303
304                   "<build>" +
305                   "  <resources>" +
306                   "    <resource>" +
307                   "      <directory>res</directory>" +
308                   "      <includes>" +
309                   "        <include>**/*.properties</include>" +
310                   "      </includes>" +
311                   "    </resource>" +
312                   "  </resources>" +
313                   "</build>");
314
315     compileModules("project");
316
317     assertNotCopied("target/classes/CVS");
318     assertNotCopied("target/classes/.svn");
319     assertCopied("target/classes/zzz/file.properties");
320   }
321
322   public void testDeletingFilesThatWasCopiedAndThenDeleted() throws Exception {
323     final VirtualFile file = createProjectSubFile("res/file.properties");
324
325     importProject("<groupId>test</groupId>" +
326                   "<artifactId>project</artifactId>" +
327                   "<version>1</version>" +
328
329                   "<build>" +
330                   "  <resources>" +
331                   "    <resource>" +
332                   "      <directory>res</directory>" +
333                   "    </resource>" +
334                   "  </resources>" +
335                   "</build>");
336
337     compileModules("project");
338     assertCopied("target/classes/file.properties");
339
340     new WriteCommandAction.Simple(myProject) {
341       @Override
342       protected void run() throws Throwable {
343         file.delete(this);
344       }
345     }.execute().throwException();
346
347     compileModules("project");
348     assertNotCopied("target/classes/file.properties");
349   }
350
351   public void testDeletingFilesThatWasCopiedAndThenExcluded() throws Exception {
352     createProjectSubFile("res/file.properties");
353
354     importProject("<groupId>test</groupId>" +
355                   "<artifactId>project</artifactId>" +
356                   "<version>1</version>" +
357
358                   "<build>" +
359                   "  <resources>" +
360                   "    <resource>" +
361                   "      <directory>res</directory>" +
362                   "    </resource>" +
363                   "  </resources>" +
364                   "</build>");
365
366     compileModules("project");
367     assertCopied("target/classes/file.properties");
368
369     createProjectPom("<groupId>test</groupId>" +
370                      "<artifactId>project</artifactId>" +
371                      "<version>1</version>" +
372
373                      "<build>" +
374                      "  <resources>" +
375                      "    <resource>" +
376                      "      <directory>res</directory>" +
377                      "      <excludes>" +
378                      "        <exclude>**/*</exclude>" +
379                      "      </excludes>" +
380                      "    </resource>" +
381                      "  </resources>" +
382                      "</build>");
383     importProject();
384
385     compileModules("project");
386     assertNotCopied("target/classes/file.properties");
387   }
388
389   public void testDoNotCopyExcludedStandardResources() throws Exception {
390
391     CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
392     configuration.addResourceFilePattern("*.zzz");
393
394     createProjectSubFile("res/file.xxx");
395     createProjectSubFile("res/file.zzz");
396
397     importProject("<groupId>test</groupId>" +
398                   "<artifactId>project</artifactId>" +
399                   "<version>1</version>" +
400
401                   "<build>" +
402                   "  <resources>" +
403                   "    <resource>" +
404                   "      <directory>res</directory>" +
405                   "      <includes>" +
406                   "        <include>**/*.xxx</include>" +
407                   "      </includes>" +
408                   "      <excludes>" +
409                   "        <exclude>**/*.zzz</exclude>" +
410                   "      </excludes>" +
411                   "    </resource>" +
412                   "  </resources>" +
413                   "</build>");
414
415     compileModules("project");
416     assertCopied("target/classes/file.xxx");
417     assertNotCopied("target/classes/file.zzz");
418   }
419
420   public void testDoNotDeleteFilesFromOtherModulesOutput() throws Exception {
421     createProjectSubFile("m1/resources/file.xxx");
422     createProjectSubFile("m2/resources/file.yyy");
423
424     createProjectPom("<groupId>test</groupId>" +
425                      "<artifactId>project</artifactId>" +
426                      "<version>1</version>" +
427
428                      "<modules>" +
429                      "  <module>m1</module>" +
430                      "  <module>m2</module>" +
431                      "</modules>");
432
433     createModulePom("m1",
434                     "<groupId>test</groupId>" +
435                     "<artifactId>m1</artifactId>" +
436                     "<version>1</version>" +
437
438                     "<build>" +
439                     "  <resources>" +
440                     "    <resource>" +
441                     "      <directory>resources</directory>" +
442                     "    </resource>" +
443                     "  </resources>" +
444                     "</build>");
445
446     createModulePom("m2",
447                     "<groupId>test</groupId>" +
448                     "<artifactId>m2</artifactId>" +
449                     "<version>1</version>" +
450
451                     "<build>" +
452                     "  <resources>" +
453                     "    <resource>" +
454                     "      <directory>resources</directory>" +
455                     "    </resource>" +
456                     "  </resources>" +
457                     "</build>");
458     importProject();
459
460     compileModules("project", "m1", "m2");
461     assertCopied("m1/target/classes/file.xxx");
462     assertCopied("m2/target/classes/file.yyy");
463
464     compileModules("m1");
465     assertCopied("m1/target/classes/file.xxx");
466     assertCopied("m2/target/classes/file.yyy");
467
468     compileModules("m2");
469     assertCopied("m1/target/classes/file.xxx");
470     assertCopied("m2/target/classes/file.yyy");
471
472     compileModules("project");
473     assertCopied("m1/target/classes/file.xxx");
474     assertCopied("m2/target/classes/file.yyy");
475   }
476
477   public void testDoNotDeleteFilesFromOtherModulesOutputWhenOutputIsTheSame() throws Exception {
478     createProjectSubFile("resources/file.xxx");
479
480     createProjectPom("<groupId>test</groupId>" +
481                      "<artifactId>project</artifactId>" +
482                      "<version>1</version>" +
483
484                      "<modules>" +
485                      "  <module>m1</module>" +
486                      "  <module>m2</module>" +
487                      "</modules>");
488
489     createModulePom("m1",
490                     "<groupId>test</groupId>" +
491                     "<artifactId>m1</artifactId>" +
492                     "<version>1</version>" +
493
494                     "<build>" +
495                     "  <resources>" +
496                     "    <resource>" +
497                     "      <directory>../resources</directory>" +
498                     "    </resource>" +
499                     "  </resources>" +
500                     "</build>");
501
502     createModulePom("m2",
503                     "<groupId>test</groupId>" +
504                     "<artifactId>m2</artifactId>" +
505                     "<version>1</version>" +
506
507                     "<build>" +
508                     "  <resources>" +
509                     "    <resource>" +
510                     "      <directory>../resources</directory>" +
511                     "    </resource>" +
512                     "  </resources>" +
513                     "</build>");
514     importProject();
515
516     new WriteCommandAction.Simple(myProject) {
517       @Override
518       protected void run() throws Throwable {
519         setModulesOutput(myProjectRoot.createChildDirectory(this, "output"), "project", "m1", "m2");
520       }
521     }.execute().throwException();
522
523
524     compileModules("project", "m1", "m2");
525     assertCopied("output/file.xxx");
526
527     compileModules("m1");
528     assertCopied("output/file.xxx");
529
530     compileModules("m2");
531     assertCopied("output/file.xxx");
532
533     compileModules("project");
534     assertCopied("output/file.xxx");
535   }
536
537   private void setModulesOutput(final VirtualFile output, final String... moduleNames) {
538     AccessToken accessToken = WriteAction.start();
539     try {
540       for (String each : moduleNames) {
541         PsiTestUtil.setCompilerOutputPath(getModule(each), output.getUrl(), false);
542         PsiTestUtil.setCompilerOutputPath(getModule(each), output.getUrl(), true);
543       }
544     }
545     finally {
546       accessToken.finish();
547     }
548   }
549
550   public void testWebResources() throws Exception {
551     if (ignore()) return;
552
553     createProjectSubFile("res/dir/file.properties");
554     createProjectSubFile("res/dir/file.xml");
555     createProjectSubFile("res/file.properties");
556     createProjectSubFile("res/file.xml");
557     createProjectSubFile("res/file.txt");
558
559     importProject("<groupId>test</groupId>" +
560                   "<artifactId>project</artifactId>" +
561                   "<version>1</version>" +
562                   "<packaging>war</packaging>" +
563
564                   "<build>" +
565                   "  <plugins>" +
566                   "    <plugin>" +
567                   "      <groupId>org.apache.maven.plugins</groupId>" +
568                   "      <artifactId>maven-war-plugin</artifactId>" +
569                   "      <configuration>" +
570                   "        <webResources>" +
571                   "          <directory>res</directory>" +
572                   "          <includes>" +
573                   "            <include>**/*.properties</include>" +
574                   "            <include>**/*.xml</include>" +
575                   "          </includes>" +
576                   "          <excludes>" +
577                   "            <exclude>*.properties</exclude>" +
578                   "            <exclude>dir/*.xml</exclude>" +
579                   "          </excludes>" +
580                   "        </webResources>" +
581                   "      </configuration>" +
582                   "    </plugin>" +
583                   "  </plugins>" +
584                   "</build>");
585
586     compileModules("project");
587
588     assertCopied("target/classes/dir/file.properties");
589     assertNotCopied("target/classes/dir/file.xml");
590     assertNotCopied("target/classes/file.properties");
591     assertCopied("target/classes/file.xml");
592     assertNotCopied("target/classes/file.txt");
593   }
594
595   public void testOverridingWebResourceFilters() throws Exception {
596     if (ignore()) return;
597
598     createProjectPom("<groupId>test</groupId>" +
599                      "<artifactId>project</artifactId>" +
600                      "<version>1</version>" +
601                      "<packaging>war</packaging>" +
602
603                      "<build>" +
604                      "  <plugins>" +
605                      "    <plugin>" +
606                      "      <groupId>org.apache.maven.plugins</groupId>" +
607                      "      <artifactId>maven-war-plugin</artifactId>" +
608                      "      <configuration>\n" +
609                      "        <!-- the default value is the filter list under build -->\n" +
610                      "        <!-- specifying a filter will override the filter list under build -->\n" +
611                      "        <filters>\n" +
612                      "          <filter>properties/config.prop</filter>\n" +
613                      "        </filters>\n" +
614                      "        <nonFilteredFileExtensions>\n" +
615                      "          <!-- default value contains jpg,jpeg,gif,bmp,png -->\n" +
616                      "          <nonFilteredFileExtension>pdf</nonFilteredFileExtensions>\n" +
617                      "        </nonFilteredFileExtensions>\n" +
618                      "        <webResources>\n" +
619                      "          <resource>\n" +
620                      "            <directory>resource2</directory>\n" +
621                      "            <!-- it's not a good idea to filter binary files -->\n" +
622                      "            <filtering>false</filtering>\n" +
623                      "          </resource>\n" +
624                      "          <resource>\n" +
625                      "            <directory>configurations</directory>\n" +
626                      "            <!-- enable filtering -->\n" +
627                      "            <filtering>true</filtering>\n" +
628                      "            <excludes>\n" +
629                      "              <exclude>**/properties</exclude>\n" +
630                      "            </excludes>\n" +
631                      "          </resource>\n" +
632                      "        </webResources>\n" +
633                      "      </configuration>" +
634                      "    </plugin>" +
635                      "  </plugins>" +
636                      "</build>");
637   }
638
639   public void testCopingNonMavenResources() throws Exception {
640     if (ignore()) return;
641
642     createProjectSubFile("src/resources/a.txt", "a");
643
644     VirtualFile configDir = createProjectSubDir("src/config");
645     createProjectSubFile("src/config/b.txt", "b");
646     createProjectSubFile("src/config/JavaClass.java", "class JavaClass {}");
647     createProjectSubFile("src/config/xxx.xxx", "xxx"); // *.xxx is excluded from resource coping, see setUpInWriteAction()
648
649     final VirtualFile excludedDir = createProjectSubDir("src/excluded");
650     createProjectSubFile("src/excluded/c.txt", "c");
651
652     importProject("<groupId>test</groupId>" +
653                   "<artifactId>project</artifactId>" +
654                   "<version>1</version>");
655
656     Module module = ModuleManager.getInstance(myProject).findModuleByName("project");
657     PsiTestUtil.addSourceRoot(module, configDir);
658     PsiTestUtil.addSourceRoot(module, excludedDir);
659
660     new WriteCommandAction.Simple(myProject) {
661       @Override
662       protected void run() throws Throwable {
663         CompilerConfiguration.getInstance(myProject).getExcludedEntriesConfiguration()
664           .addExcludeEntryDescription(new ExcludeEntryDescription(excludedDir, true, false, getTestRootDisposable()));
665
666         setModulesOutput(myProjectRoot.createChildDirectory(this, "output"), "project", "m1", "m2");
667       }
668     }.execute().throwException();
669
670     compileModules("project");
671
672     assertCopied("output/a.txt");
673     assertCopied("output/b.txt");
674
675     assertNotCopied("output/JavaClass.java");
676     assertNotCopied("output/xxx.xxx");
677     assertNotCopied("output/c.txt");
678   }
679
680   private void assertCopied(String path) {
681     assertTrue(new File(myProjectPom.getParent().getPath(), path).exists());
682   }
683
684   private void assertNotCopied(String path) {
685     assertFalse(new File(myProjectPom.getParent().getPath(), path).exists());
686   }
687 }