external build: remove deleted files from src-output mapping only when compilation of target is finished (because these mappings are used by some builders), build loggers unified

This commit is contained in:
nik
2012-11-02 13:20:12 +04:00
parent ca96f836a4
commit a4916e476d
20 changed files with 124 additions and 212 deletions
@@ -5,19 +5,21 @@ import org.jetbrains.jps.builders.logging.ProjectBuilderLogger;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* @author nik
*/
public abstract class ProjectBuilderLoggerBase implements ProjectBuilderLogger {
@Override
public void logDeletedFiles(Collection<String> outputs) {
if (outputs.isEmpty()) return;
final String[] buffer = new String[outputs.size()];
public void logDeletedFiles(Collection<String> paths) {
if (paths.isEmpty()) return;
final String[] buffer = new String[paths.size()];
int i = 0;
for (final String o : outputs) {
for (final String o : paths) {
buffer[i++] = o;
}
Arrays.sort(buffer);
@@ -43,5 +45,14 @@ public abstract class ProjectBuilderLoggerBase implements ProjectBuilderLogger {
logLine("End of files");
}
@Override
public void logCompiledPaths(Collection<String> paths, String builderName, String description) throws IOException {
List<File> files = new ArrayList<File>(paths.size());
for (String path : paths) {
files.add(new File(path));
}
logCompiledFiles(files, builderName, description);
}
protected abstract void logLine(String message);
}
@@ -7,9 +7,9 @@ import com.intellij.openapi.util.io.FileUtil;
import gnu.trove.THashSet;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.FSOperations;
import org.jetbrains.jps.incremental.ModuleBuildTarget;
@@ -140,9 +140,6 @@ public class JavaBuilderUtil {
globalMappings.integrate(delta);
// safe to remove everything that has been integrated
dropRemovedPaths(context, chunk);
return additionalPassRequired;
}
catch (RuntimeException e) {
@@ -208,7 +205,7 @@ public class JavaBuilderUtil {
}
private static Set<String> getRemovedPaths(CompileContext context, ModuleChunk chunk) {
final Map<ModuleBuildTarget, Collection<String>> map = Utils.REMOVED_SOURCES_KEY.get(context);
final Map<BuildTarget<?>, Collection<String>> map = Utils.REMOVED_SOURCES_KEY.get(context);
if (map == null) {
return Collections.emptySet();
}
@@ -222,21 +219,6 @@ public class JavaBuilderUtil {
return removed;
}
private static void dropRemovedPaths(CompileContext context, ModuleChunk chunk) throws IOException {
final Map<ModuleBuildTarget, Collection<String>> map = Utils.REMOVED_SOURCES_KEY.get(context);
if (map != null) {
for (ModuleBuildTarget target : chunk.getTargets()) {
final Collection<String> paths = map.remove(target);
if (paths != null) {
final SourceToOutputMapping storage = context.getProjectDescriptor().dataManager.getSourceToOutputMap(target);
for (String path : paths) {
storage.remove(path);
}
}
}
}
}
public static void cleanupChunkResources(CompileContext context) {
ALL_AFFECTED_FILES_KEY.set(context, null);
ALL_COMPILED_FILES_KEY.set(context, null);
@@ -2,29 +2,18 @@ package org.jetbrains.jps.builders.logging;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.impl.logging.ProjectBuilderLoggerImpl;
import org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLogger;
import org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLoggerImpl;
/**
* @author nik
*/
public class BuildLoggingManager {
public static final BuildLoggingManager DEFAULT = new BuildLoggingManager(new ArtifactBuilderLoggerImpl(),
new ProjectBuilderLoggerImpl());
private ArtifactBuilderLogger myArtifactBuilderLogger;
public static final BuildLoggingManager DEFAULT = new BuildLoggingManager(new ProjectBuilderLoggerImpl());
private final ProjectBuilderLogger myProjectLogger;
public BuildLoggingManager(@NotNull ArtifactBuilderLogger artifactBuilderLogger,
@NotNull ProjectBuilderLogger projectLogger) {
myArtifactBuilderLogger = artifactBuilderLogger;
public BuildLoggingManager(@NotNull ProjectBuilderLogger projectLogger) {
myProjectLogger = projectLogger;
}
@NotNull
public ArtifactBuilderLogger getArtifactBuilderLogger() {
return myArtifactBuilderLogger;
}
@NotNull
public ProjectBuilderLogger getProjectBuilderLogger() {
return myProjectLogger;
@@ -13,4 +13,6 @@ public interface ProjectBuilderLogger {
void logDeletedFiles(Collection<String> paths);
void logCompiledFiles(Collection<File> files, String builderName, String description) throws IOException;
void logCompiledPaths(Collection<String> paths, String builderName, String description) throws IOException;
}
@@ -17,6 +17,7 @@ import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
/**
* @author Eugene Zhuravlev
@@ -54,14 +55,7 @@ public class BuildOperations {
configuration.save();
}
else if (pd.fsState.markInitialScanPerformed(target)) {
if (target instanceof ModuleBasedTarget) {
initTargetFSState(context, target, false);
}
else {
// todo: check why other non-associated with module targets have to initialize deleted outputs by themselves
// instead of getting this functionality out-of the box
FSOperations.markDirtyFiles(context, target, timestamps, false, null);
}
initTargetFSState(context, target, false);
}
}
@@ -107,7 +101,7 @@ public class BuildOperations {
final ProjectDescriptor pd = context.getProjectDescriptor();
final BuildFSState fsState = pd.fsState;
if (!Utils.errorsDetected(context) && !context.getCancelStatus().isCanceled()) {
boolean marked = false;
boolean marked = dropRemovedPaths(context, chunk);
for (BuildTarget<?> target : chunk.getTargets()) {
if (context.isMake() && target instanceof ModuleBuildTarget) {
// ensure non-incremental flag cleared
@@ -128,6 +122,24 @@ public class BuildOperations {
}
}
private static boolean dropRemovedPaths(CompileContext context, BuildTargetChunk chunk) throws IOException {
final Map<BuildTarget<?>, Collection<String>> map = Utils.REMOVED_SOURCES_KEY.get(context);
boolean dropped = false;
if (map != null) {
for (BuildTarget<?> target : chunk.getTargets()) {
final Collection<String> paths = map.remove(target);
if (paths != null) {
final SourceToOutputMapping storage = context.getProjectDescriptor().dataManager.getSourceToOutputMap(target);
for (String path : paths) {
storage.remove(path);
dropped = true;
}
}
}
}
return dropped;
}
private static class BuildOutputConsumerImpl implements BuildOutputConsumer {
private final BuildTarget<?> myTarget;
private final CompileContext myContext;
@@ -576,10 +576,10 @@ public class IncProjectBuilder {
try {
// restore deleted paths that were not procesesd by 'integrate'
final Map<ModuleBuildTarget, Collection<String>> map = Utils.REMOVED_SOURCES_KEY.get(context);
final Map<BuildTarget<?>, Collection<String>> map = Utils.REMOVED_SOURCES_KEY.get(context);
if (map != null) {
for (Map.Entry<ModuleBuildTarget, Collection<String>> entry : map.entrySet()) {
final ModuleBuildTarget target = entry.getKey();
for (Map.Entry<BuildTarget<?>, Collection<String>> entry : map.entrySet()) {
final BuildTarget<?> target = entry.getKey();
final Collection<String> paths = entry.getValue();
if (paths != null) {
for (String path : paths) {
@@ -648,16 +648,14 @@ public class IncProjectBuilder {
boolean doneSomething = false;
try {
// cleanup outputs
final Map<ModuleBuildTarget, Collection<String>> moduleTargetRemovedSources = new HashMap<ModuleBuildTarget, Collection<String>>();
final Map<BuildTarget<?>, Collection<String>> targetToRemovedSources = new HashMap<BuildTarget<?>, Collection<String>>();
for (BuildTarget<?> target : targets) {
final Collection<String> deletedPaths = myProjectDescriptor.fsState.getAndClearDeletedPaths(target);
if (deletedPaths.isEmpty()) {
continue;
}
if (target instanceof ModuleBuildTarget) {
moduleTargetRemovedSources.put((ModuleBuildTarget)target, deletedPaths);
}
targetToRemovedSources.put(target, deletedPaths);
final SourceToOutputMapping sourceToOutputStorage = context.getProjectDescriptor().dataManager.getSourceToOutputMap(target);
final ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger();
@@ -694,28 +692,22 @@ public class IncProjectBuilder {
sourceToFormMap.remove(deletedSource);
}
}
else {
if (outputs != null) {
// for all other targets can clean the mapping right now
sourceToOutputStorage.remove(deletedSource);
}
}
}
}
if (!moduleTargetRemovedSources.isEmpty()) {
final Map<ModuleBuildTarget, Collection<String>> existing = Utils.REMOVED_SOURCES_KEY.get(context);
if (!targetToRemovedSources.isEmpty()) {
final Map<BuildTarget<?>, Collection<String>> existing = Utils.REMOVED_SOURCES_KEY.get(context);
if (existing != null) {
for (Map.Entry<ModuleBuildTarget, Collection<String>> entry : existing.entrySet()) {
final Collection<String> paths = moduleTargetRemovedSources.get(entry.getKey());
for (Map.Entry<BuildTarget<?>, Collection<String>> entry : existing.entrySet()) {
final Collection<String> paths = targetToRemovedSources.get(entry.getKey());
if (paths != null) {
paths.addAll(entry.getValue());
}
else {
moduleTargetRemovedSources.put(entry.getKey(), entry.getValue());
targetToRemovedSources.put(entry.getKey(), entry.getValue());
}
}
}
Utils.REMOVED_SOURCES_KEY.set(context, moduleTargetRemovedSources);
Utils.REMOVED_SOURCES_KEY.set(context, targetToRemovedSources);
}
}
catch (IOException e) {
@@ -5,6 +5,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.serialization.JpsProjectLoader;
import org.jetbrains.jps.model.serialization.PathMacroUtil;
@@ -19,7 +20,7 @@ import java.util.*;
* Date: 10/20/11
*/
public class Utils {
public static final Key<Map<ModuleBuildTarget, Collection<String>>> REMOVED_SOURCES_KEY = Key.create("_removed_sources_");
public static final Key<Map<BuildTarget<?>, Collection<String>>> REMOVED_SOURCES_KEY = Key.create("_removed_sources_");
public static final Key<Boolean> PROCEED_ON_ERROR_KEY = Key.create("_proceed_on_error_");
public static final Key<Boolean> ERRORS_DETECTED_KEY = Key.create("_errors_detected_");
private static volatile File ourSystemRoot = new File(System.getProperty("user.home"), ".idea-build");
@@ -1,12 +0,0 @@
package org.jetbrains.jps.incremental.artifacts;
/**
* @author nik
*/
public interface ArtifactBuilderLogger {
void fileCopied(String sourceFilePath);
void fileDeleted(String targetFilePath);
boolean isEnabled();
}
@@ -1,25 +0,0 @@
package org.jetbrains.jps.incremental.artifacts;
import com.intellij.openapi.diagnostic.Logger;
/**
* @author nik
*/
public class ArtifactBuilderLoggerImpl implements ArtifactBuilderLogger {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLoggerImpl");
@Override
public void fileCopied(String sourceFilePath) {
LOG.debug("Copied:" + sourceFilePath);
}
@Override
public void fileDeleted(String targetFilePath) {
LOG.debug("Deleted:" + targetFilePath);
}
@Override
public boolean isEnabled() {
return LOG.isDebugEnabled();
}
}
@@ -11,6 +11,7 @@ import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.BuildRootDescriptor;
import org.jetbrains.jps.builders.BuildRootIndex;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.logging.ProjectBuilderLogger;
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.BuildListener;
@@ -192,7 +193,6 @@ public class IncArtifactBuilder extends TargetBuilder<ArtifactRootDescriptor, Ar
}
if (deleted) {
context.getLoggingManager().getArtifactBuilderLogger().fileDeleted(filePath);
outSrcMapping.remove(filePath);
deletedPaths.add(filePath);
for (String sourcePath : filesToDelete.get(filePath)) {
@@ -208,6 +208,10 @@ public class IncArtifactBuilder extends TargetBuilder<ArtifactRootDescriptor, Ar
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.WARNING, "Cannot delete file '" + filePath + "'"));
}
}
ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger();
if (logger.isEnabled()) {
logger.logDeletedFiles(deletedPaths);
}
}
@Override
@@ -32,9 +32,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.logging.ProjectBuilderLogger;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.ProjectBuildException;
import org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLogger;
import org.jetbrains.jps.incremental.artifacts.ArtifactOutputToSourceMapping;
import org.jetbrains.jps.incremental.artifacts.IncArtifactBuilder;
import org.jetbrains.jps.incremental.artifacts.instructions.*;
@@ -187,11 +187,10 @@ public class JarsBuilder {
}
}
final ArtifactBuilderLogger logger = myContext.getLoggingManager().getArtifactBuilderLogger();
final ProjectBuilderLogger logger = myContext.getLoggingManager().getProjectBuilderLogger();
if (logger.isEnabled()) {
for (String filePath : packedFilePaths) {
logger.fileCopied(filePath);
}
logger.logCompiledPaths(packedFilePaths, IncArtifactBuilder.BUILDER_NAME, "Packing files:");
}
myOutputConsumer.registerOutputFile(targetJarPath, packedFilePaths);
@@ -3,9 +3,11 @@ package org.jetbrains.jps.incremental.artifacts.instructions;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.logging.ProjectBuilderLogger;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget;
import org.jetbrains.jps.incremental.artifacts.ArtifactOutputToSourceMapping;
import org.jetbrains.jps.incremental.artifacts.IncArtifactBuilder;
import org.jetbrains.jps.incremental.artifacts.impl.JpsArtifactPathUtil;
import java.io.File;
@@ -45,7 +47,10 @@ public class FileBasedArtifactRootDescriptor extends ArtifactRootDescriptor {
}
if (outSrcMapping.getState(targetPath) == null) {
context.getLoggingManager().getArtifactBuilderLogger().fileCopied(filePath);
ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger();
if (logger.isEnabled()) {
logger.logCompiledFiles(Collections.singletonList(file), IncArtifactBuilder.BUILDER_NAME, "Copying file:");
}
final File targetFile = new File(FileUtil.toSystemDependentName(targetPath));
FileUtil.copyContent(file, targetFile);
outputConsumer.registerOutputFile(targetPath, Collections.singletonList(filePath));
@@ -5,10 +5,11 @@ 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.builders.logging.ProjectBuilderLogger;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget;
import org.jetbrains.jps.incremental.artifacts.ArtifactOutputToSourceMapping;
import org.jetbrains.jps.incremental.artifacts.IncArtifactBuilder;
import org.jetbrains.jps.incremental.artifacts.JarPathUtil;
import org.jetbrains.jps.incremental.artifacts.impl.JpsArtifactPathUtil;
@@ -67,7 +68,10 @@ public class JarBasedArtifactRootDescriptor extends ArtifactRootDescriptor {
final int rootIndex, final String outputPath,
CompileContext context, final BuildOutputConsumer outputConsumer,
final ArtifactOutputToSourceMapping outSrcMapping) throws IOException {
context.getLoggingManager().getArtifactBuilderLogger().fileCopied(filePath);
ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger();
if (logger.isEnabled()) {
logger.logCompiledPaths(Collections.singletonList(filePath), IncArtifactBuilder.BUILDER_NAME, "Extracting archive:");
}
processEntries(new EntryProcessor() {
@Override
public void process(@Nullable InputStream inputStream, @NotNull String relativePath) throws IOException {
@@ -32,6 +32,7 @@ import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.api.GlobalOptions;
import org.jetbrains.jps.api.RequestFuture;
import org.jetbrains.jps.builders.BuildRootIndex;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.FileProcessor;
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
@@ -173,7 +174,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
private static boolean hasRemovedSources(CompileContext context) {
final Map<ModuleBuildTarget, Collection<String>> removed = Utils.REMOVED_SOURCES_KEY.get(context);
final Map<BuildTarget<?>, Collection<String>> removed = Utils.REMOVED_SOURCES_KEY.get(context);
return removed != null && !removed.isEmpty();
}
@@ -26,7 +26,6 @@ import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.builders.logging.BuildLoggingManager;
import org.jetbrains.jps.builders.impl.logging.ProjectBuilderLoggerBase;
import org.jetbrains.jps.incremental.Utils;
import org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLoggerImpl;
import org.jetbrains.jps.model.JpsDummyElement;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
@@ -171,8 +170,7 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
protected BuildResult doTestBuild(int makesCount) {
StringBuilder log = new StringBuilder();
String rootPath = FileUtil.toSystemIndependentName(workDir.getAbsolutePath()) + "/";
final ProjectDescriptor pd = createProjectDescriptor(new BuildLoggingManager(new ArtifactBuilderLoggerImpl(),
new StringProjectBuilderLogger(rootPath, log)));
final ProjectDescriptor pd = createProjectDescriptor(new BuildLoggingManager(new StringProjectBuilderLogger(rootPath, log)));
try {
doBuild(pd, CompileScopeTestBuilder.rebuild().allModules()).assertSuccessful();
@@ -19,7 +19,6 @@ import org.jetbrains.jps.incremental.BuilderRegistry;
import org.jetbrains.jps.incremental.IncProjectBuilder;
import org.jetbrains.jps.incremental.RebuildRequestedException;
import org.jetbrains.jps.incremental.Utils;
import org.jetbrains.jps.incremental.artifacts.ArtifactBuilderLoggerImpl;
import org.jetbrains.jps.incremental.fs.BuildFSState;
import org.jetbrains.jps.incremental.storage.BuildDataManager;
import org.jetbrains.jps.incremental.storage.BuildTargetsState;
@@ -205,7 +204,7 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
}
protected BuildResult doBuild(CompileScopeTestBuilder scope) {
ProjectDescriptor descriptor = createProjectDescriptor(new BuildLoggingManager(new ArtifactBuilderLoggerImpl(), myLogger));
ProjectDescriptor descriptor = createProjectDescriptor(new BuildLoggingManager(myLogger));
try {
myLogger.clear();
return doBuild(descriptor, scope);
@@ -216,7 +215,11 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
}
protected void assertCompiled(String builderName, String... paths) {
myLogger.assertCompiled(builderName, getOrCreateProjectDir(), paths);
myLogger.assertCompiled(builderName, new File[]{myProjectDir, myDataStorageRoot}, paths);
}
protected void assertDeleted(String... paths) {
myLogger.assertDeleted(new File[]{myProjectDir, myDataStorageRoot}, paths);
}
protected BuildResult doBuild(final ProjectDescriptor descriptor, CompileScopeTestBuilder scopeBuilder) {
@@ -273,19 +276,4 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
}
return addModule(moduleName, srcPaths, getAbsolutePath("out/production/" + moduleName), myJdk);
}
protected String getProjectRelativePath(String path) {
assertNotNull(myProjectDir);
final String projectDir = FileUtil.toSystemIndependentName(myProjectDir.getAbsolutePath());
String dataStorageRoot = FileUtil.toSystemIndependentName(myDataStorageRoot.getAbsolutePath());
if (FileUtil.isAncestor(projectDir, path, true)) {
return FileUtil.getRelativePath(projectDir, path, '/');
}
else if (FileUtil.isAncestor(dataStorageRoot, path, true)) {
return FileUtil.getRelativePath(dataStorageRoot, path, '/');
}
else {
return path;
}
}
}
@@ -3,6 +3,7 @@ package org.jetbrains.jps.builders;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.util.containers.MultiMap;
import gnu.trove.THashSet;
import org.jetbrains.jps.builders.impl.logging.ProjectBuilderLoggerBase;
import java.io.File;
@@ -10,16 +11,20 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* @author nik
*/
public class TestProjectBuilderLogger extends ProjectBuilderLoggerBase {
private MultiMap<String, File> myCompiledFiles = new MultiMap<String, File>();
private Set<File> myDeletedFiles = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
@Override
public void logDeletedFiles(Collection<String> outputs) {
super.logDeletedFiles(outputs);
public void logDeletedFiles(Collection<String> paths) {
for (String path : paths) {
myDeletedFiles.add(new File(path));
}
}
@Override
@@ -29,24 +34,32 @@ public class TestProjectBuilderLogger extends ProjectBuilderLoggerBase {
public void clear() {
myCompiledFiles.clear();
myDeletedFiles.clear();
}
public void assertCompiled(String builderName, File baseDir, String... paths) {
Collection<File> compiled = myCompiledFiles.get(builderName);
public void assertCompiled(String builderName, File[] baseDirs, String... paths) {
assertRelativePaths(baseDirs, myCompiledFiles.get(builderName), paths);
}
public void assertDeleted(File[] baseDirs, String... paths) {
assertRelativePaths(baseDirs, myDeletedFiles, paths);
}
private static void assertRelativePaths(File[] baseDirs, Collection<File> files, String[] expected) {
List<String> relativePaths = new ArrayList<String>();
for (File file : compiled) {
String path;
if (FileUtil.isAncestor(baseDir, file, false)) {
path = FileUtil.getRelativePath(baseDir, file);
}
else {
path = file.getAbsolutePath();
for (File file : files) {
String path = file.getAbsolutePath();
for (File baseDir : baseDirs) {
if (baseDir != null && FileUtil.isAncestor(baseDir, file, false)) {
path = FileUtil.getRelativePath(baseDir, file);
break;
}
}
relativePaths.add(FileUtil.toSystemIndependentName(path));
}
UsefulTestCase.assertSameElements(relativePaths, paths);
UsefulTestCase.assertSameElements(relativePaths, expected);
}
@Override
protected void logLine(String message) {
}
@@ -4,7 +4,6 @@ import com.intellij.util.PathUtil;
import org.jetbrains.jps.model.artifact.JpsArtifact;
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;
/**
@@ -163,7 +162,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase {
public void testUpdateManifest() {
final String manifestText1 = "Manifest-Version: 1.0\r\nMain-Class: A\r\n\r\n";
final String manifest = createFile("d/MANIFEST.MF", manifestText1);
final JpsArtifact a = addArtifact("a", archive("a.jar").dir("META-INF").parentDirCopy(manifest).fileCopy(createFile("a.txt")));
final JpsArtifact a = addArtifact("a", root().archive("a.jar").dir("META-INF").parentDirCopy(manifest).fileCopy(createFile("a.txt")));
buildAll();
assertOutput(a, fs().archive("a.jar").dir("META-INF").file("MANIFEST.MF", manifestText1).file("a.txt"));
@@ -17,14 +17,11 @@ package org.jetbrains.jps.incremental.artifacts;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.io.TestFileSystemBuilder;
import com.intellij.util.text.UniqueNameGenerator;
import org.jetbrains.jps.builders.BuildResult;
import org.jetbrains.jps.builders.CompileScopeTestBuilder;
import org.jetbrains.jps.builders.JpsBuildTestCase;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.builders.logging.BuildLoggingManager;
import org.jetbrains.jps.builders.impl.logging.ProjectBuilderLoggerImpl;
import org.jetbrains.jps.model.JpsElementFactory;
import org.jetbrains.jps.model.artifact.DirectoryArtifactType;
import org.jetbrains.jps.model.artifact.JpsArtifact;
@@ -38,7 +35,6 @@ import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.intellij.util.io.TestFileSystemItem.fs;
@@ -47,13 +43,6 @@ import static com.intellij.util.io.TestFileSystemItem.fs;
* @author nik
*/
public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase {
private TestArtifactBuilderLogger myArtifactBuilderLogger;
protected void setUp() throws Exception {
super.setUp();
myArtifactBuilderLogger = new TestArtifactBuilderLogger();
}
@Override
protected void tearDown() throws Exception {
for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(myProject)) {
@@ -102,19 +91,6 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase {
doBuild(CompileScopeTestBuilder.make().allModules().artifacts(artifacts)).assertSuccessful();
}
protected BuildResult doBuild(CompileScopeTestBuilder scope) {
BuildResult result;
ProjectDescriptor descriptor = createProjectDescriptor(new BuildLoggingManager(myArtifactBuilderLogger, new ProjectBuilderLoggerImpl()));
try {
myArtifactBuilderLogger.clear();
result = doBuild(descriptor, scope);
}
finally {
descriptor.release();
}
return result;
}
protected static String getJUnitJarPath() {
final File file = PathManager.findFileInLibDirectory("junit.jar");
assertTrue("File " + file.getAbsolutePath() + " doesn't exist", file.exists());
@@ -130,8 +106,7 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase {
}
protected void assertCopied(String... filePaths) {
assertSameElements(myArtifactBuilderLogger.myCopiedFilePaths, filePaths);
assertEmpty(myArtifactBuilderLogger.myDeletedFilePaths);
assertDeletedAndCopied(ArrayUtil.EMPTY_STRING_ARRAY, filePaths);
}
protected void assertDeletedAndCopied(String deletedPath, String... copiedPaths) {
@@ -139,27 +114,26 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase {
}
protected void assertDeletedAndCopied(String[] deletedPaths, String... copiedPaths) {
assertSameElements(myArtifactBuilderLogger.myDeletedFilePaths, deletedPaths);
assertSameElements(myArtifactBuilderLogger.myCopiedFilePaths, copiedPaths);
assertCompiled(IncArtifactBuilder.BUILDER_NAME, copiedPaths);
super.assertDeleted(deletedPaths);
}
@Override
protected void assertDeleted(String... paths) {
assertDeletedAndCopied(paths);
}
protected static void assertOutput(JpsArtifact a, TestFileSystemBuilder expected) {
assertOutput(a.getOutputPath(), expected);
}
protected void assertDeleted(String... filePaths) {
assertSameElements(myArtifactBuilderLogger.myDeletedFilePaths, filePaths);
assertEmpty(myArtifactBuilderLogger.myCopiedFilePaths);
}
protected void buildAllAndAssertUpToDate() {
buildAll();
assertUpToDate();
}
protected void assertUpToDate() {
assertEmpty(myArtifactBuilderLogger.myDeletedFilePaths);
assertEmpty(myArtifactBuilderLogger.myCopiedFilePaths);
assertDeletedAndCopied(ArrayUtil.EMPTY_STRING_ARRAY);
}
protected static void rename(String path, String newName) {
@@ -175,29 +149,4 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase {
throw new RuntimeException(e);
}
}
private class TestArtifactBuilderLogger implements ArtifactBuilderLogger {
private Set<String> myCopiedFilePaths = new LinkedHashSet<String>();
private Set<String> myDeletedFilePaths = new LinkedHashSet<String>();
@Override
public void fileCopied(String sourceFilePath) {
myCopiedFilePaths.add(getProjectRelativePath(sourceFilePath));
}
@Override
public void fileDeleted(String targetFilePath) {
myDeletedFilePaths.add(getProjectRelativePath(targetFilePath));
}
@Override
public boolean isEnabled() {
return true;
}
public void clear() {
myCopiedFilePaths.clear();
myDeletedFilePaths.clear();
}
}
}
@@ -74,7 +74,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase {
public void testRemoveDeletedFileFromArchive() {
String file1 = createFile("dir/a.txt");
createFile("dir/b.txt");
final JpsArtifact a = addArtifact("a", archive("a.jar").parentDirCopy(file1));
final JpsArtifact a = addArtifact("a", root().archive("a.jar").parentDirCopy(file1));
buildAll();
assertOutput(a, fs().archive("a.jar").file("a.txt").file("b.txt"));