blob: 10ea2438517cf2eacf0be93dfebd28b5a45410e7 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.incremental.artifacts;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.PathUtil;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.library.JpsLibrary;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.util.JpsPathUtil;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import static com.intellij.util.io.TestFileSystemBuilder.fs;
import static org.jetbrains.jps.incremental.artifacts.LayoutElementTestUtil.archive;
import static org.jetbrains.jps.incremental.artifacts.LayoutElementTestUtil.root;
/**
* @author nik
*/
public class ArtifactBuilderTest extends ArtifactBuilderTestCase {
public void testFileCopy() {
final JpsArtifact a = addArtifact(root().fileCopy(createFile("file.txt", "foo")));
buildAll();
assertOutput(a, fs().file("file.txt", "foo"));
}
public void testDir() {
final JpsArtifact a = addArtifact(
root()
.fileCopy(createFile("abc.txt"))
.dir("dir")
.fileCopy(createFile("xxx.txt", "bar"))
);
buildAll();
assertOutput(a, fs()
.file("abc.txt")
.dir("dir")
.file("xxx.txt", "bar")
);
}
public void testArchive() {
final JpsArtifact a = addArtifact(
root()
.archive("xxx.zip")
.fileCopy(createFile("X.class", "data"))
.dir("dir")
.fileCopy(createFile("Y.class"))
);
buildAll();
assertOutput(a, fs()
.archive("xxx.zip")
.file("X.class", "data")
.dir("dir")
.file("Y.class")
);
}
public void testTwoDirsInArchive() {
final String dir1 = PathUtil.getParentPath(PathUtil.getParentPath(createFile("dir1/a/x.txt")));
final String dir2 = PathUtil.getParentPath(PathUtil.getParentPath(createFile("dir2/a/y.txt")));
final JpsArtifact a = addArtifact(
root()
.archive("a.jar")
.dirCopy(dir1)
.dirCopy(dir2)
.dir("a").fileCopy(createFile("z.txt"))
);
buildAll();
assertOutput(a, fs()
.archive("a.jar")
.dir("a")
.file("x.txt")
.file("y.txt")
.file("z.txt")
);
}
public void testArchiveInArchive() {
final JpsArtifact a = addArtifact(
root()
.archive("a.jar")
.archive("b.jar")
.fileCopy(createFile("xxx.txt", "foo"))
);
buildAll();
assertOutput(a, fs()
.archive("a.jar")
.archive("b.jar")
.file("xxx.txt", "foo")
);
}
public void testIncludedArtifact() {
final JpsArtifact included = addArtifact("included",
root()
.fileCopy(createFile("aaa.txt")));
final JpsArtifact a = addArtifact(
root()
.dir("dir")
.artifact(included)
.end()
.fileCopy(createFile("bbb.txt"))
);
buildAll();
assertOutput(included, fs().file("aaa.txt"));
assertOutput(a, fs()
.dir("dir")
.file("aaa.txt")
.end()
.file("bbb.txt")
);
}
public void testMergeDirectories() {
final JpsArtifact included = addArtifact("included",
root().dir("dir").fileCopy(createFile("aaa.class")));
final JpsArtifact a = addArtifact(
root()
.artifact(included)
.dir("dir")
.fileCopy(createFile("bbb.class")));
buildAll();
assertOutput(a, fs()
.dir("dir")
.file("aaa.class")
.file("bbb.class")
);
}
public void testCopyLibrary() {
final JpsLibrary library = addProjectLibrary("lib", getJUnitJarPath());
final JpsArtifact a = addArtifact(root().lib(library));
buildAll();
assertOutput(a, fs().file("junit.jar"));
}
public void testModuleOutput() {
final String file = createFile("src/A.java", "public class A {}");
final JpsModule module = addModule("a", PathUtil.getParentPath(file));
final JpsArtifact artifact = addArtifact(root().module(module));
buildArtifacts(artifact);
assertOutput(artifact, fs().file("A.class"));
}
public void testCopyResourcesFromModuleOutput() {
String file = createFile("src/a.xml", "");
JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(myProject).addResourcePattern("*.xml");
JpsModule module = addModule("a", PathUtil.getParentPath(file));
JpsArtifact artifact = addArtifact(root().module(module));
buildArtifacts(artifact);
assertOutput(artifact, fs().file("a.xml"));
}
public void testIgnoredFile() {
final String file = createFile("a/.svn/a.txt");
createFile("a/svn/b.txt");
final JpsArtifact a = addArtifact(root().parentDirCopy(PathUtil.getParentPath(file)));
buildAll();
assertOutput(a, fs().dir("svn").file("b.txt"));
}
public void testIgnoredFileInArchive() {
final String file = createFile("a/.svn/a.txt");
createFile("a/svn/b.txt");
final JpsArtifact a = addArtifact(archive("a.jar").parentDirCopy(PathUtil.getParentPath(file)));
buildAll();
assertOutput(a, fs().archive("a.jar").dir("svn").file("b.txt"));
}
public void testCopyExcludedFolder() {
//explicitly added excluded files should be copied (e.g. compile output)
final String file = createFile("xxx/excluded/a.txt");
createFile("xxx/excluded/CVS");
final String excluded = PathUtil.getParentPath(file);
final String dir = PathUtil.getParentPath(excluded);
final JpsModule module = addModule("myModule");
module.getContentRootsList().addUrl(JpsPathUtil.pathToUrl(dir));
module.getExcludeRootsList().addUrl(JpsPathUtil.pathToUrl(excluded));
final JpsArtifact a = addArtifact(root().dirCopy(excluded));
buildAll();
assertOutput(a, fs().file("a.txt"));
}
public void testCopyExcludedFile() {
//excluded files under non-excluded directory should not be copied
final String file = createFile("xxx/excluded/a.txt");
createFile("xxx/b.txt");
createFile("xxx/CVS");
final String dir = PathUtil.getParentPath(PathUtil.getParentPath(file));
JpsModule module = addModule("myModule");
module.getContentRootsList().addUrl(JpsPathUtil.pathToUrl(dir));
module.getExcludeRootsList().addUrl(JpsPathUtil.pathToUrl(PathUtil.getParentPath(file)));
final JpsArtifact a = addArtifact(root().dirCopy(dir));
buildAll();
assertOutput(a, fs().file("b.txt"));
}
public void testExtractDirectory() {
final JpsArtifact a = addArtifact("a", root().dir("dir").extractedDir(getJUnitJarPath(), "/junit/textui/"));
buildAll();
assertOutput(a, fs().dir("dir")
.file("ResultPrinter.class")
.file("TestRunner.class"));
}
public void testExtractDirectoryFromExcludedJar() throws IOException {
String jarPath = createFile("dir/lib/j.jar");
FileUtil.copy(new File(getJUnitJarPath()), new File(jarPath));
JpsModule module = addModule("m");
String libDir = PathUtil.getParentPath(jarPath);
module.getContentRootsList().addUrl(JpsPathUtil.pathToUrl(PathUtil.getParentPath(libDir)));
module.getExcludeRootsList().addUrl(JpsPathUtil.pathToUrl(libDir));
final JpsArtifact a = addArtifact("a", root().extractedDir(jarPath, "/junit/textui/"));
buildAll();
assertOutput(a, fs().file("ResultPrinter.class")
.file("TestRunner.class"));
}
public void testPackExtractedDirectory() {
final JpsArtifact a = addArtifact("a", root().archive("a.jar").extractedDir(getJUnitJarPath(), "/junit/textui/"));
buildAll();
assertOutput(a, fs().archive("a.jar")
.file("ResultPrinter.class")
.file("TestRunner.class"));
}
public void testSelfIncludingArtifact() {
final JpsArtifact a = addArtifact("a", root());
LayoutElementTestUtil.addArtifactToLayout(a, a);
assertBuildFailed(a);
}
public void testCircularInclusion() {
final JpsArtifact a = addArtifact("a", root());
final JpsArtifact b = addArtifact("b", root());
LayoutElementTestUtil.addArtifactToLayout(a, b);
LayoutElementTestUtil.addArtifactToLayout(b, a);
assertBuildFailed(a);
assertBuildFailed(b);
}
public void testArtifactContainingSelfIncludingArtifact() {
JpsArtifact c = addArtifact("c", root());
final JpsArtifact a = addArtifact("a", root().artifact(c));
LayoutElementTestUtil.addArtifactToLayout(a, a);
final JpsArtifact b = addArtifact("b", root().artifact(a));
buildArtifacts(c);
assertBuildFailed(b);
assertBuildFailed(a);
}
public void testArtifactContainingSelfIncludingArtifactWithoutOutput() {
final JpsArtifact a = addArtifact("a", root());
LayoutElementTestUtil.addArtifactToLayout(a, a);
final JpsArtifact b = addArtifact("b", root().artifact(a));
a.setOutputPath(null);
assertBuildFailed(b);
}
//IDEA-73893
public void testManifestFileIsFirstEntry() throws IOException {
final String firstFile = createFile("src/A.txt");
final String manifestFile = createFile("src/MANIFEST.MF");
final String lastFile = createFile("src/Z.txt");
final JpsArtifact a = addArtifact(archive("a.jar").dir("META-INF")
.fileCopy(firstFile).fileCopy(manifestFile).fileCopy(lastFile));
buildArtifacts(a);
final String jarPath = a.getOutputPath() + "/a.jar";
JarFile jarFile = new JarFile(new File(jarPath));
try {
final Enumeration<JarEntry> entries = jarFile.entries();
assertTrue(entries.hasMoreElements());
final JarEntry firstEntry = entries.nextElement();
assertEquals(JarFile.MANIFEST_NAME, firstEntry.getName());
}
finally {
jarFile.close();
}
}
public void testPreserveCompressionMethodForEntryExtractedFromOneArchiveAndPackedIntoAnother() throws IOException {
String path = createFile("data/a.jar");
ZipOutputStream output = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(new File(path))));
try {
ZipEntry entry = new ZipEntry("a.txt");
byte[] text = "text".getBytes();
entry.setMethod(ZipEntry.STORED);
entry.setSize(text.length);
CRC32 crc32 = new CRC32();
crc32.update(text);
entry.setCrc(crc32.getValue());
output.putNextEntry(entry);
output.write(text);
output.closeEntry();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
output.close();
}
JpsArtifact a = addArtifact(archive("b.jar").extractedDir(path, ""));
buildAll();
assertOutput(a, fs().archive("b.jar").file("a.txt", "text"));
final String jarPath = a.getOutputPath() + "/b.jar";
ZipFile zipFile = new ZipFile(new File(jarPath));
try {
ZipEntry entry = zipFile.getEntry("a.txt");
assertNotNull(entry);
assertEquals(ZipEntry.STORED, entry.getMethod());
}
finally {
zipFile.close();
}
}
public void testBuildModuleBeforeArtifactIfSomeDirectoryInsideModuleOutputIsCopiedToArtifact() {
String src = PathUtil.getParentPath(PathUtil.getParentPath(createFile("src/x/A.java", "package x; class A{}")));
JpsModule module = addModule("m", src);
File output = JpsJavaExtensionService.getInstance().getOutputDirectory(module, false);
JpsArtifact artifact = addArtifact(root().dirCopy(new File(output, "x").getAbsolutePath()));
rebuildAll();
assertOutput(module, fs().dir("x").file("A.class"));
assertOutput(artifact, fs().file("A.class"));
}
public void testClearOutputOnRebuild() throws IOException {
String file = createFile("d/a.txt");
JpsArtifact a = addArtifact(root().parentDirCopy(file));
buildAll();
createFileInArtifactOutput(a, "b.txt");
buildAllAndAssertUpToDate();
assertOutput(a, fs().file("a.txt").file("b.txt"));
rebuildAll();
assertOutput(a, fs().file("a.txt"));
}
public void testDeleteOnlyOutputFileOnRebuildForArchiveArtifact() throws IOException {
String file = createFile("a.txt");
JpsArtifact a = addArtifact(archive("a.jar").fileCopy(file));
buildAll();
createFileInArtifactOutput(a, "b.txt");
buildAllAndAssertUpToDate();
assertOutput(a, fs().archive("a.jar").file("a.txt").end().file("b.txt"));
rebuildAll();
assertOutput(a, fs().archive("a.jar").file("a.txt").end().file("b.txt"));
}
public void testDoNotCreateEmptyArchive() {
String file = createFile("dir/a.txt");
JpsArtifact a = addArtifact(archive("a.jar").parentDirCopy(file));
delete(file);
buildAll();
assertEmptyOutput(a);
}
public void testDoNotCreateEmptyArchiveInsideArchive() {
String file = createFile("dir/a.txt");
JpsArtifact a = addArtifact(archive("a.jar").archive("inner.jar").parentDirCopy(file));
delete(file);
buildAll();
assertEmptyOutput(a);
}
public void testDoNotCreateEmptyArchiveFromExtractedDirectory() {
final JpsArtifact a = addArtifact("a", archive("a.jar").dir("dir").extractedDir(getJUnitJarPath(), "/xxx/"));
buildAll();
assertEmptyOutput(a);
}
public void testExtractNonExistentJarFile() {
JpsArtifact a = addArtifact(root().extractedDir("this-file-does-not-exist.jar", "/"));
buildAll();
assertEmptyOutput(a);
}
public void testRepackNonExistentJarFile() {
JpsArtifact a = addArtifact(archive("a.jar").extractedDir("this-file-does-not-exist.jar", "/").fileCopy(createFile("a.txt")));
buildAll();
assertOutput(a, fs().archive("a.jar").file("a.txt"));
}
private static void createFileInArtifactOutput(JpsArtifact a, final String fileName) throws IOException {
assertTrue(new File(a.getOutputPath(), fileName).createNewFile());
}
}