From 5ac9d4d19b32259d18e6bde8523fcf1e32f94fdf Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 30 Oct 2012 12:41:14 +0400 Subject: [PATCH] external compiler: several fixes in artifact builder (IDEA-93026, IDEA-81955, IDEA-88716) --- .../impl/TranslatingCompilerFilesMonitor.java | 11 +++-- .../artifacts/IncArtifactBuilder.java | 15 +++--- .../artifacts/impl/JarsBuilder.java | 48 +++++++++++-------- .../instructions/ArtifactRootDescriptor.java | 4 +- .../FileBasedArtifactRootDescriptor.java | 6 +-- .../JarBasedArtifactRootDescriptor.java | 5 +- .../IncrementalArtifactBuildingTest.java | 13 +++++ .../intellij/testFramework/VfsTestUtil.java | 4 +- 8 files changed, 69 insertions(+), 37 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java index 83e3d602d8a3..050a1030c0ff 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java @@ -1601,7 +1601,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } private void processNewFile(final VirtualFile file, final boolean notifyServer) { - final Set pathsToMark = notifyServer ? new THashSet(FileUtil.FILE_HASHING_STRATEGY) : Collections.emptySet(); ApplicationManager.getApplication().runReadAction(new Runnable() { // need read action to ensure that the project was not disposed during the iteration over the project list public void run() { @@ -1616,9 +1615,6 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { final TranslatingCompiler[] translators = CompilerManager.getInstance(project).getCompilers(TranslatingCompiler.class); processRecursively(file, false, new FileProcessor() { public void execute(final VirtualFile file) { - if (notifyServer) { - pathsToMark.add(new File(file.getPath())); - } if (!projectSuspended && isCompilable(file)) { loadInfoAndAddSourceForRecompilation(projectId, file); } @@ -1647,6 +1643,13 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } }); if (notifyServer) { + final Set pathsToMark = new THashSet(FileUtil.FILE_HASHING_STRATEGY); + processRecursively(file, false, new FileProcessor() { + @Override + public void execute(VirtualFile file) { + pathsToMark.add(new File(file.getPath())); + } + }); notifyFilesChanged(pathsToMark); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java index 47681a066970..961b2cd6a3a4 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java @@ -134,18 +134,21 @@ public class IncArtifactBuilder extends TargetBuilderemptyList()); - changedJars.add(((JarDestinationInfo)destination).getJarInfo()); + else { + List sources = outSrcMapping.getState(destination.getOutputFilePath()); + if (sources == null || sources.size() > 0 && sources.get(0).getRootIndex() == descriptor.getRootIndex()) { + outSrcMapping.update(destination.getOutputFilePath(), + Collections.emptyList()); + changedJars.add(((JarDestinationInfo)destination).getJarInfo()); + } } } } context.checkCanceled(); - JarsBuilder builder = new JarsBuilder(changedJars, context, srcOutMapping, outSrcMapping); + JarsBuilder builder = new JarsBuilder(changedJars, context, outputConsumer, outSrcMapping); builder.buildJars(); } catch (IOException e) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JarsBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JarsBuilder.java index c57c2f7e6fc0..1469dc69a044 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JarsBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JarsBuilder.java @@ -31,7 +31,7 @@ import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.builders.storage.SourceToOutputMapping; +import org.jetbrains.jps.builders.BuildOutputConsumer; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.ProjectBuildException; import org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLogger; @@ -58,12 +58,12 @@ public class JarsBuilder { private final Set myJarsToBuild; private final CompileContext myContext; private Map myBuiltJars; - private final SourceToOutputMapping mySrcOutMapping; + private final BuildOutputConsumer myOutputConsumer; private final ArtifactOutputToSourceMapping myOutSrcMapping; - public JarsBuilder(Set jarsToBuild, CompileContext context, SourceToOutputMapping srcOutMapping, + public JarsBuilder(Set jarsToBuild, CompileContext context, BuildOutputConsumer outputConsumer, ArtifactOutputToSourceMapping outSrcMapping) { - mySrcOutMapping = srcOutMapping; + myOutputConsumer = outputConsumer; myOutSrcMapping = outSrcMapping; DependentJarsEvaluator evaluator = new DependentJarsEvaluator(); for (JarInfo jarInfo : jarsToBuild) { @@ -147,7 +147,8 @@ public class JarsBuilder { FileUtil.createParentDirs(jarFile); final String targetJarPath = jar.getDestination().getOutputFilePath(); - Manifest manifest = loadManifest(jar, targetJarPath); + List packedFilePaths = new ArrayList(); + Manifest manifest = loadManifest(jar, packedFilePaths); final JarOutputStream jarOutputStream = createJarOutputStream(jarFile, manifest); try { @@ -161,15 +162,13 @@ public class JarsBuilder { if (pair.getSecond() instanceof ArtifactRootDescriptor) { final ArtifactRootDescriptor descriptor = (ArtifactRootDescriptor)pair.getSecond(); final int rootIndex = descriptor.getRootIndex(); - final ArtifactBuilderLogger logger = myContext.getLoggingManager().getArtifactBuilderLogger(); if (descriptor instanceof FileBasedArtifactRootDescriptor) { addFileToJar(jarOutputStream, jarFile, descriptor.getRootFile(), descriptor.getFilter(), relativePath, targetJarPath, writtenPaths, - rootIndex); + packedFilePaths, rootIndex); } else { final String filePath = FileUtil.toSystemIndependentName(descriptor.getRootFile().getAbsolutePath()); - logger.fileCopied(filePath); - mySrcOutMapping.appendOutput(filePath, targetJarPath); + packedFilePaths.add(filePath); myOutSrcMapping.appendData(targetJarPath, Collections .singletonList(new ArtifactOutputToSourceMapping.SourcePathAndRootIndex(filePath, rootIndex))); extractFileAndAddToJar(jarOutputStream, (JarBasedArtifactRootDescriptor)descriptor, relativePath, writtenPaths); @@ -179,13 +178,23 @@ public class JarsBuilder { JarInfo nestedJar = (JarInfo)pair.getSecond(); File nestedJarFile = myBuiltJars.get(nestedJar); if (nestedJarFile != null) { - addFileToJar(jarOutputStream, jarFile, nestedJarFile, SourceFileFilter.ALL, relativePath, targetJarPath, writtenPaths, -1); + addFileToJar(jarOutputStream, jarFile, nestedJarFile, SourceFileFilter.ALL, relativePath, targetJarPath, writtenPaths, + packedFilePaths, -1); } else { LOG.debug("nested jar file " + relativePath + " for " + jar.getPresentableDestination() + " not found"); } } } + + final ArtifactBuilderLogger logger = myContext.getLoggingManager().getArtifactBuilderLogger(); + if (logger.isEnabled()) { + for (String filePath : packedFilePaths) { + logger.fileCopied(filePath); + } + } + myOutputConsumer.registerOutputFile(targetJarPath, packedFilePaths); + } finally { jarOutputStream.close(); @@ -201,7 +210,7 @@ public class JarsBuilder { } @Nullable - private Manifest loadManifest(JarInfo jar, String targetJarPath) throws IOException { + private Manifest loadManifest(JarInfo jar, List packedFilePaths) throws IOException { for (Pair pair : jar.getContent()) { if (pair.getSecond() instanceof ArtifactRootDescriptor) { final String rootPath = pair.getFirst(); @@ -214,8 +223,7 @@ public class JarsBuilder { final File manifestFile = new File(descriptor.getRootFile(), manifestPath); if (manifestFile.exists()) { final String fullManifestPath = FileUtil.toSystemIndependentName(manifestFile.getAbsolutePath()); - myContext.getLoggingManager().getArtifactBuilderLogger().fileCopied(fullManifestPath); - mySrcOutMapping.appendOutput(fullManifestPath, targetJarPath); + packedFilePaths.add(fullManifestPath); //noinspection IOResourceOpenedButNotSafelyClosed return createManifest(new FileInputStream(manifestFile), manifestFile); } @@ -284,20 +292,23 @@ public class JarsBuilder { private void addFileToJar(final @NotNull JarOutputStream jarOutputStream, final @NotNull File jarFile, @NotNull File file, SourceFileFilter filter, @NotNull String relativePath, String targetJarPath, - final @NotNull Set writtenPaths, final int rootIndex) throws IOException { + final @NotNull Set writtenPaths, List packedFilePaths, final int rootIndex) throws IOException { if (!file.exists() || FileUtil.isAncestor(file, jarFile, false)) { return; } relativePath = addParentDirectories(jarOutputStream, writtenPaths, relativePath); - addFileOrDirRecursively(jarOutputStream, file, filter, relativePath, targetJarPath, writtenPaths, rootIndex); + addFileOrDirRecursively(jarOutputStream, file, filter, relativePath, targetJarPath, writtenPaths, packedFilePaths, rootIndex); } private void addFileOrDirRecursively(@NotNull ZipOutputStream jarOutputStream, @NotNull File file, SourceFileFilter filter, @NotNull String relativePath, - String targetJarPath, @NotNull Set writtenItemRelativePaths, int rootIndex) throws IOException { + String targetJarPath, + @NotNull Set writtenItemRelativePaths, + List packedFilePaths, + int rootIndex) throws IOException { final String filePath = FileUtil.toSystemIndependentName(file.getAbsolutePath()); if (!filter.accept(filePath, myContext.getProjectDescriptor().dataManager)) { return; @@ -312,7 +323,7 @@ public class JarsBuilder { if (children != null) { for (File child : children) { addFileOrDirRecursively(jarOutputStream, child, filter, directoryPath + child.getName(), targetJarPath, writtenItemRelativePaths, - rootIndex); + packedFilePaths, rootIndex); } } return; @@ -322,8 +333,7 @@ public class JarsBuilder { if (rootIndex != -1) { myOutSrcMapping.appendData(targetJarPath, Collections.singletonList(new ArtifactOutputToSourceMapping.SourcePathAndRootIndex(filePath, rootIndex))); if (added) { - mySrcOutMapping.appendOutput(filePath, targetJarPath); - myContext.getLoggingManager().getArtifactBuilderLogger().fileCopied(filePath); + packedFilePaths.add(filePath); } } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactRootDescriptor.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactRootDescriptor.java index 2b3ca83ff73b..28237af4901b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactRootDescriptor.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactRootDescriptor.java @@ -1,8 +1,8 @@ package org.jetbrains.jps.incremental.artifacts.instructions; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.builders.BuildOutputConsumer; import org.jetbrains.jps.builders.BuildRootDescriptor; -import org.jetbrains.jps.builders.storage.SourceToOutputMapping; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget; import org.jetbrains.jps.incremental.artifacts.ArtifactOutputToSourceMapping; @@ -77,7 +77,7 @@ public abstract class ArtifactRootDescriptor extends BuildRootDescriptor { public abstract void copyFromRoot(String filePath, int rootIndex, String outputPath, - CompileContext context, SourceToOutputMapping srcOutMapping, + CompileContext context, BuildOutputConsumer outputConsumer, ArtifactOutputToSourceMapping outSrcMapping) throws IOException; public SourceFileFilter getFilter() { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/FileBasedArtifactRootDescriptor.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/FileBasedArtifactRootDescriptor.java index 1596f8bbbd84..d2dbd4bc83ba 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/FileBasedArtifactRootDescriptor.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/FileBasedArtifactRootDescriptor.java @@ -2,7 +2,7 @@ package org.jetbrains.jps.incremental.artifacts.instructions; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.builders.storage.SourceToOutputMapping; +import org.jetbrains.jps.builders.BuildOutputConsumer; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget; import org.jetbrains.jps.incremental.artifacts.ArtifactOutputToSourceMapping; @@ -31,7 +31,7 @@ public class FileBasedArtifactRootDescriptor extends ArtifactRootDescriptor { public void copyFromRoot(String filePath, int rootIndex, String outputPath, - CompileContext context, SourceToOutputMapping srcOutMapping, + CompileContext context, BuildOutputConsumer outputConsumer, ArtifactOutputToSourceMapping outSrcMapping) throws IOException { final File file = new File(FileUtil.toSystemDependentName(filePath)); if (!file.exists()) return; @@ -48,7 +48,7 @@ public class FileBasedArtifactRootDescriptor extends ArtifactRootDescriptor { context.getLoggingManager().getArtifactBuilderLogger().fileCopied(filePath); final File targetFile = new File(FileUtil.toSystemDependentName(targetPath)); FileUtil.copyContent(file, targetFile); - srcOutMapping.appendOutput(filePath, targetPath); + outputConsumer.registerOutputFile(targetPath, Collections.singletonList(filePath)); } outSrcMapping.appendData(targetPath, Collections.singletonList(new ArtifactOutputToSourceMapping.SourcePathAndRootIndex(filePath, rootIndex))); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactRootDescriptor.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactRootDescriptor.java index 02ec06acd63c..aa6c7244ac3d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactRootDescriptor.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactRootDescriptor.java @@ -4,6 +4,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.builders.BuildOutputConsumer; import org.jetbrains.jps.builders.storage.SourceToOutputMapping; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget; @@ -64,7 +65,7 @@ public class JarBasedArtifactRootDescriptor extends ArtifactRootDescriptor { public void copyFromRoot(final String filePath, final int rootIndex, final String outputPath, - CompileContext context, final SourceToOutputMapping srcOutMapping, + CompileContext context, final BuildOutputConsumer outputConsumer, final ArtifactOutputToSourceMapping outSrcMapping) throws IOException { context.getLoggingManager().getArtifactBuilderLogger().fileCopied(filePath); processEntries(new EntryProcessor() { @@ -89,7 +90,7 @@ public class JarBasedArtifactRootDescriptor extends ArtifactRootDescriptor { from.close(); to.close(); } - srcOutMapping.appendOutput(filePath, fullOutputPath); + outputConsumer.registerOutputFile(fullOutputPath, Collections.singletonList(filePath)); } outSrcMapping.appendData(fullOutputPath, Collections.singletonList(new ArtifactOutputToSourceMapping.SourcePathAndRootIndex(fullSourcePath, rootIndex))); } diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/IncrementalArtifactBuildingTest.java b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/IncrementalArtifactBuildingTest.java index f00c5d965ddc..860c47269cbb 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/IncrementalArtifactBuildingTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/incremental/artifacts/IncrementalArtifactBuildingTest.java @@ -85,6 +85,19 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase { buildAllAndAssertUpToDate(); } + public void testAddFileToArchive() { + String file = createFile("dir/a.txt"); + JpsArtifact a = addArtifact("a", archive("a.jar").parentDirCopy(file)); + buildAll(); + assertOutput(a, fs().archive("a.jar").file("a.txt")); + + createFile("dir/b.txt"); + buildAll(); + assertOutput(a, fs().archive("a.jar").file("a.txt").file("b.txt")); + assertCopied("dir/a.txt", "dir/b.txt"); + buildAllAndAssertUpToDate(); + } + public void testOneFileInTwoArtifacts() { final String file = createFile("file.txt"); final JpsArtifact a1 = addArtifact("a1", root().dir("dir").fileCopy(file)); diff --git a/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java index 6dcffbd70251..76fc4ee4dce1 100644 --- a/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/VfsTestUtil.java @@ -68,7 +68,9 @@ public class VfsTestUtil { } else { file = parent.createChildData(VfsTestUtil.class, PathUtil.getFileName(relativePath)); - VfsUtil.saveText(file, text); + if (!text.isEmpty()) { + VfsUtil.saveText(file, text); + } } return file; }