external make: a runner for maven resource builder allowing to copy resources before module compilation starts (needed for android source generator)

This commit is contained in:
Eugene Zhuravlev
2012-10-30 17:32:57 +01:00
parent 6234aa8fda
commit 82b935a4e3
9 changed files with 356 additions and 189 deletions
@@ -0,0 +1,174 @@
package org.jetbrains.jps.incremental;
import com.intellij.openapi.util.io.FileUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.*;
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.fs.BuildFSState;
import org.jetbrains.jps.incremental.messages.FileGeneratedEvent;
import org.jetbrains.jps.incremental.messages.UptoDateFilesSavedEvent;
import org.jetbrains.jps.incremental.storage.BuildTargetConfiguration;
import org.jetbrains.jps.incremental.storage.Timestamps;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
/**
* @author Eugene Zhuravlev
* Date: 10/30/12
*/
public class BuildOperations {
private BuildOperations() {
}
public static void ensureFSStateInitialized(CompileContext context, BuildTargetChunk chunk) throws IOException {
for (BuildTarget<?> target : chunk.getTargets()) {
ensureFSStateInitialized(context, target);
}
}
public static void ensureFSStateInitialized(CompileContext context, BuildTarget<?> target) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final Timestamps timestamps = pd.timestamps.getStorage();
final BuildTargetConfiguration configuration = pd.getTargetsState().getTargetConfiguration(target);
if (context.isProjectRebuild()) {
FSOperations.markDirtyFiles(context, target, timestamps, true, null);
configuration.save();
}
else if (context.getScope().isRecompilationForced(target) || configuration.isTargetDirty()) {
if (target instanceof ModuleBuildTarget) {
// Using special FSState initialization, because for correct results of "integrate" operation of JavaBuilder
// we still need to know which sources were deleted from previous compilation
initTargetFSState(context, target, true);
}
else {
IncProjectBuilder.clearOutputFiles(context, target);
FSOperations.markDirtyFiles(context, target, timestamps, true, null);
}
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);
}
}
}
private static void initTargetFSState(CompileContext context, BuildTarget<?> target, final boolean forceMarkDirty) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final Timestamps timestamps = pd.timestamps.getStorage();
final THashSet<File> currentFiles = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
FSOperations.markDirtyFiles(context, target, timestamps, forceMarkDirty, currentFiles);
// handle deleted paths
final BuildFSState fsState = pd.fsState;
fsState.clearDeletedPaths(target);
final SourceToOutputMapping sourceToOutputMap = pd.dataManager.getSourceToOutputMap(target);
for (final Iterator<String> it = sourceToOutputMap.getSourcesIterator(); it.hasNext(); ) {
final String path = it.next();
// can check if the file exists
final File file = new File(path);
if (!currentFiles.contains(file)) {
fsState.registerDeleted(target, file, timestamps);
}
}
}
public static <R extends BuildRootDescriptor, T extends BuildTarget<R>>
void buildTarget(final T target, final CompileContext context, TargetBuilder<?, ?> builder) throws ProjectBuildException, IOException {
if (builder.getTargetTypes().contains(target.getTargetType())) {
DirtyFilesHolder<R, T> holder = new DirtyFilesHolder<R, T>() {
@Override
public void processDirtyFiles(@NotNull FileProcessor<R, T> processor) throws IOException {
context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor);
}
};
//noinspection unchecked
BuildOutputConsumerImpl outputConsumer = new BuildOutputConsumerImpl(target, context);
((TargetBuilder<R, T>)builder).build(target, holder, outputConsumer, context);
outputConsumer.fireFileGeneratedEvent();
context.checkCanceled();
}
}
public static void markTargetsUpToDate(CompileContext context, BuildTargetChunk chunk) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final BuildFSState fsState = pd.fsState;
if (!Utils.errorsDetected(context) && !context.getCancelStatus().isCanceled()) {
boolean marked = false;
for (BuildTarget<?> target : chunk.getTargets()) {
if (context.isMake() && target instanceof ModuleBuildTarget) {
// ensure non-incremental flag cleared
context.clearNonIncrementalMark((ModuleBuildTarget)target);
}
if (context.isProjectRebuild()) {
fsState.markInitialScanPerformed(target);
}
final Timestamps timestamps = pd.timestamps.getStorage();
for (BuildRootDescriptor rd : pd.getBuildRootIndex().getTargetRoots(target, context)) {
marked |= fsState.markAllUpToDate(context, rd, timestamps);
}
}
if (marked) {
context.processMessage(UptoDateFilesSavedEvent.INSTANCE);
}
}
}
private static class BuildOutputConsumerImpl implements BuildOutputConsumer {
private final BuildTarget<?> myTarget;
private final CompileContext myContext;
private FileGeneratedEvent myFileGeneratedEvent;
private Collection<File> myOutputs;
private THashSet<String> myRegisteredSources = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
public BuildOutputConsumerImpl(BuildTarget<?> target, CompileContext context) {
myTarget = target;
myContext = context;
myFileGeneratedEvent = new FileGeneratedEvent();
myOutputs = myTarget.getOutputDirs(context);
}
@Override
public void registerOutputFile(String outputFilePath, Collection<String> sourceFiles) throws IOException {
final File outputFile = new File(outputFilePath);
for (File outputDir : myOutputs) {
if (FileUtil.isAncestor(outputDir, outputFile, true)) {
final String relativePath = FileUtil.getRelativePath(outputDir, outputFile);
if (relativePath != null) {
myFileGeneratedEvent.add(FileUtil.toSystemIndependentName(outputDir.getPath()), FileUtil.toSystemIndependentName(relativePath));
}
break;
}
}
final SourceToOutputMapping mapping = myContext.getProjectDescriptor().dataManager.getSourceToOutputMap(myTarget);
for (String sourceFile : sourceFiles) {
if (myRegisteredSources.add(FileUtil.toSystemIndependentName(sourceFile))) {
mapping.setOutput(sourceFile, outputFilePath);
}
else {
mapping.appendOutput(sourceFile, outputFilePath);
}
}
}
public void fireFileGeneratedEvent() {
if (!myFileGeneratedEvent.getPaths().isEmpty()) {
myContext.processMessage(myFileGeneratedEvent);
}
}
}
}
@@ -5,6 +5,7 @@ package org.jetbrains.jps.incremental;
* Date: 9/17/11
*/
public enum BuilderCategory {
INITIAL,
SOURCE_GENERATOR,
SOURCE_INSTRUMENTER,
SOURCE_PROCESSOR,
@@ -31,11 +31,12 @@ import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.fs.BuildFSState;
import org.jetbrains.jps.incremental.java.ExternalJavacDescriptor;
import org.jetbrains.jps.incremental.java.JavaBuilder;
import org.jetbrains.jps.incremental.messages.*;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.incremental.messages.FileDeletedEvent;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.incremental.storage.BuildDataManager;
import org.jetbrains.jps.incremental.storage.BuildTargetConfiguration;
import org.jetbrains.jps.incremental.storage.OneToManyPathsMapping;
import org.jetbrains.jps.incremental.storage.Timestamps;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration;
import org.jetbrains.jps.service.SharedThreadPool;
@@ -364,9 +365,9 @@ public class IncProjectBuilder {
}
}
else {
context.processMessage(new CompilerMessage(BUILD_NAME, BuildMessage.Kind.WARNING, "Output path " +
outputRoot.getPath() +
" intersects with a source root. Only files that were created by build will be cleaned."));
context.processMessage(new CompilerMessage(
BUILD_NAME, BuildMessage.Kind.WARNING, "Output path " + outputRoot.getPath() + " intersects with a source root. Only files that were created by build will be cleaned.")
);
// clean only those files we are aware of
for (BuildTarget<?> target : entry.getValue()) {
clearOutputFiles(context, target);
@@ -509,9 +510,9 @@ public class IncProjectBuilder {
moduleTargets.add((ModuleBuildTarget)target);
}
else {
context.processMessage(new CompilerMessage(BUILD_NAME, BuildMessage.Kind.ERROR, "Cannot build " +
target.getPresentableName() +
" because it is included into a circular dependency"));
context.processMessage(new CompilerMessage(
BUILD_NAME, BuildMessage.Kind.ERROR, "Cannot build " + target.getPresentableName() + " because it is included into a circular dependency")
);
return false;
}
}
@@ -519,22 +520,22 @@ public class IncProjectBuilder {
return runModuleLevelBuilders(context, new ModuleChunk(moduleTargets));
}
BuildTarget<?> target = targets.iterator().next();
final BuildTarget<?> target = targets.iterator().next();
if (target instanceof ModuleBuildTarget) {
return runModuleLevelBuilders(context, new ModuleChunk(Collections.singleton((ModuleBuildTarget)target)));
}
else {
return runTargetBuilders(target, context);
}
}
private boolean runTargetBuilders(BuildTarget<?> target, CompileContext context) throws ProjectBuildException, IOException {
List<TargetBuilder<?, ?>> builders = BuilderRegistry.getInstance().getTargetBuilders();
for (TargetBuilder<?, ?> builder : builders) {
buildTarget(target, context, builder);
updateDoneFraction(context, 1.0f / builders.size());
try {
List<TargetBuilder<?, ?>> builders = BuilderRegistry.getInstance().getTargetBuilders();
for (TargetBuilder<?, ?> builder : builders) {
BuildOperations.buildTarget(target, context, builder);
updateDoneFraction(context, 1.0f / builders.size());
}
return true;
}
catch (IOException e) {
throw new ProjectBuildException(e);
}
return true;
}
private void updateDoneFraction(CompileContext context, final float delta) {
@@ -543,31 +544,12 @@ public class IncProjectBuilder {
context.setDone(processed / myTotalTargetsWork);
}
private static <R extends BuildRootDescriptor, T extends BuildTarget<R>> void buildTarget(final T target,
final CompileContext context,
TargetBuilder<?, ?> builder)
throws ProjectBuildException, IOException {
if (builder.getTargetTypes().contains(target.getTargetType())) {
DirtyFilesHolder<R, T> holder = new DirtyFilesHolder<R, T>() {
@Override
public void processDirtyFiles(@NotNull FileProcessor<R, T> processor) throws IOException {
context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor);
}
};
//noinspection unchecked
BuildOutputConsumerImpl outputConsumer = new BuildOutputConsumerImpl(target, context);
((TargetBuilder<R, T>)builder).build(target, holder, outputConsumer, context);
outputConsumer.fireFileGeneratedEvent();
context.checkCanceled();
}
}
private void buildTargetsChunk(CompileContext context, final BuildTargetChunk chunk) throws ProjectBuildException {
boolean doneSomething = false;
try {
Utils.ERRORS_DETECTED_KEY.set(context, Boolean.FALSE);
ensureFSStateInitialized(context, chunk);
BuildOperations.ensureFSStateInitialized(context, chunk);
if (context.isMake()) {
doneSomething |= processDeletedPaths(context, chunk.getTargets());
}
@@ -927,82 +909,7 @@ public class IncProjectBuilder {
fsState.clearContextRoundData(context);
fsState.clearContextChunk(context);
if (!Utils.errorsDetected(context) && !context.getCancelStatus().isCanceled()) {
boolean marked = false;
for (BuildTarget<?> target : chunk.getTargets()) {
if (context.isMake() && target instanceof ModuleBuildTarget) {
// ensure non-incremental flag cleared
context.clearNonIncrementalMark((ModuleBuildTarget)target);
}
if (context.isProjectRebuild()) {
fsState.markInitialScanPerformed(target);
}
final Timestamps timestamps = pd.timestamps.getStorage();
for (BuildRootDescriptor rd : pd.getBuildRootIndex().getTargetRoots(target, context)) {
marked |= fsState.markAllUpToDate(context, rd, timestamps);
}
}
if (marked) {
context.processMessage(UptoDateFilesSavedEvent.INSTANCE);
}
}
}
private static void ensureFSStateInitialized(CompileContext context, BuildTargetChunk chunk) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final Timestamps timestamps = pd.timestamps.getStorage();
for (BuildTarget<?> target : chunk.getTargets()) {
final BuildTargetConfiguration configuration = pd.getTargetsState().getTargetConfiguration(target);
if (context.isProjectRebuild()) {
FSOperations.markDirtyFiles(context, target, timestamps, true, null);
configuration.save();
}
else if (context.getScope().isRecompilationForced(target) || configuration.isTargetDirty()) {
if (target instanceof ModuleBuildTarget) {
// Using special FSState initialization, because for correct results of "integrate" operation of JavaBuilder
// we still need to know which sources were deleted from previous compilation
initTargetFSState(context, target, true);
}
else {
clearOutputFiles(context, target);
FSOperations.markDirtyFiles(context, target, timestamps, true, null);
}
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);
}
}
}
}
private static void initTargetFSState(CompileContext context, BuildTarget<?> target, final boolean forceMarkDirty) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final Timestamps timestamps = pd.timestamps.getStorage();
final THashSet<File> currentFiles = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
FSOperations.markDirtyFiles(context, target, timestamps, forceMarkDirty, currentFiles);
// handle deleted paths
final BuildFSState fsState = pd.fsState;
fsState.clearDeletedPaths(target);
final SourceToOutputMapping sourceToOutputMap = pd.dataManager.getSourceToOutputMap(target);
for (final Iterator<String> it = sourceToOutputMap.getSourcesIterator(); it.hasNext(); ) {
final String path = it.next();
// can check if the file exists
final File file = new File(path);
if (!currentFiles.contains(file)) {
fsState.registerDeleted(target, file, timestamps);
}
}
BuildOperations.markTargetsUpToDate(context, chunk);
}
private static class ChunkGroup {
@@ -1076,48 +983,4 @@ public class IncProjectBuilder {
}
});
}
private static class BuildOutputConsumerImpl implements BuildOutputConsumer {
private final BuildTarget<?> myTarget;
private final CompileContext myContext;
private FileGeneratedEvent myFileGeneratedEvent;
private Collection<File> myOutputs;
private THashSet<String> myRegisteredSources = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
public BuildOutputConsumerImpl(BuildTarget<?> target, CompileContext context) {
myTarget = target;
myContext = context;
myFileGeneratedEvent = new FileGeneratedEvent();
myOutputs = myTarget.getOutputDirs(context);
}
@Override
public void registerOutputFile(String outputFilePath, Collection<String> sourceFiles) throws IOException {
final File outputFile = new File(outputFilePath);
for (File outputDir : myOutputs) {
if (FileUtil.isAncestor(outputDir, outputFile, true)) {
final String relativePath = FileUtil.getRelativePath(outputDir, outputFile);
if (relativePath != null) {
myFileGeneratedEvent.add(FileUtil.toSystemIndependentName(outputDir.getPath()), FileUtil.toSystemIndependentName(relativePath));
}
break;
}
}
final SourceToOutputMapping mapping = myContext.getProjectDescriptor().dataManager.getSourceToOutputMap(myTarget);
for (String sourceFile : sourceFiles) {
if (myRegisteredSources.add(FileUtil.toSystemIndependentName(sourceFile))) {
mapping.setOutput(sourceFile, outputFilePath);
}
else {
mapping.appendOutput(sourceFile, outputFilePath);
}
}
}
public void fireFileGeneratedEvent() {
if (!myFileGeneratedEvent.getPaths().isEmpty()) {
myContext.processMessage(myFileGeneratedEvent);
}
}
}
}
@@ -151,10 +151,10 @@ public class BuildFSState extends FSState {
if (!rd.isGenerated() && (currentFileStamp > compilationStartStamp || getEventRegistrationStamp(file) > compilationStartStamp)) {
// if the file was modified after the compilation had started,
// do not save the stamp considering file dirty
delta.markRecompile(rd, file);
if (Utils.IS_TEST_MODE) {
LOG.info("Timestamp after compilation started; marking dirty again: " + file.getPath());
}
delta.markRecompile(rd, file);
}
else {
marked = true;
@@ -18,6 +18,7 @@ package org.jetbrains.jps.maven.compiler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.incremental.BuilderService;
import org.jetbrains.jps.incremental.ModuleLevelBuilder;
import org.jetbrains.jps.incremental.TargetBuilder;
import org.jetbrains.jps.maven.model.impl.MavenResourcesTargetType;
@@ -35,6 +36,12 @@ public class MavenBuilderService extends BuilderService{
return Arrays.asList(MavenResourcesTargetType.PRODUCTION, MavenResourcesTargetType.TEST);
}
@NotNull
@Override
public List<? extends ModuleLevelBuilder> createModuleLevelBuilders() {
return Collections.singletonList(new MavenResourceBuilderRunner());
}
@NotNull
@Override
public List<? extends TargetBuilder<?, ?>> createBuilders() {
@@ -0,0 +1,129 @@
/*
* 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.maven.compiler;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetRegistry;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.maven.model.impl.MavenResourcesTarget;
import org.jetbrains.jps.maven.model.impl.MavenResourcesTargetType;
import org.jetbrains.jps.model.module.JpsModule;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Eugene Zhuravlev
* Date: 10/30/12
*/
public class MavenResourceBuilderRunner extends ModuleLevelBuilder{
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.maven.compiler.MavenResourceBuilderRunner");
private static final Key<List<MavenResourcesTarget>> PRODUCTION_TARGETS_KEY = Key.create("_maven_production_targets");
private static final Key<List<MavenResourcesTarget>> TEST_TARGETS_KEY = Key.create("_maven_test_targets");
private static final Key<MavenResourcesBuilder> BUILDER_KEY = Key.create("_maven_resources_builder_");
public MavenResourceBuilderRunner() {
super(BuilderCategory.INITIAL);
}
@Override
public void buildStarted(CompileContext context) {
BuildTargetRegistry targetRegistry = context.getProjectDescriptor().getBuildTargetIndex();
PRODUCTION_TARGETS_KEY.set(context, targetRegistry.getAllTargets(MavenResourcesTargetType.PRODUCTION));
TEST_TARGETS_KEY.set(context, targetRegistry.getAllTargets(MavenResourcesTargetType.TEST));
for (TargetBuilder<?, ?> builder : BuilderRegistry.getInstance().getTargetBuilders()) {
if (builder instanceof MavenResourcesBuilder) {
BUILDER_KEY.set(context, (MavenResourcesBuilder)builder);
break;
}
}
}
@Override
public String getName() {
return "MavenResourceBuilder Runner";
}
@Override
public String getDescription() {
return getName();
}
@Override
public ExitCode build(CompileContext context, ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder) throws ProjectBuildException {
ExitCode rc = ExitCode.NOTHING_DONE;
final MavenResourcesBuilder mavenBuilder = BUILDER_KEY.get(context);
if (mavenBuilder == null) {
return rc;
}
final Set<ModuleBuildTarget> chunkTargets = chunk.getTargets();
if (chunkTargets.isEmpty()) {
return rc;
}
final Set<JpsModule> productionModules = new HashSet<JpsModule>();
final Set<JpsModule> testModules = new HashSet<JpsModule>();
for (ModuleBuildTarget target : chunkTargets) {
(target.isTests()? testModules : productionModules).add(target.getModule());
}
try {
if (runMavenBuilderForModules(context, mavenBuilder, productionModules, PRODUCTION_TARGETS_KEY.get(context))) {
rc = ExitCode.OK;
}
if (runMavenBuilderForModules(context, mavenBuilder, testModules, TEST_TARGETS_KEY.get(context))) {
rc = ExitCode.OK;
}
return rc;
}
catch (IOException e) {
throw new ProjectBuildException(e);
}
}
private static boolean runMavenBuilderForModules(CompileContext context,
MavenResourcesBuilder mavenBuilder,
Set<JpsModule> modules,
@Nullable List<MavenResourcesTarget> allTargets)
throws ProjectBuildException, IOException {
if (allTargets == null || modules.isEmpty()) {
return false;
}
boolean doneSomething = false;
final Set<BuildTarget<?>> processed = new HashSet<BuildTarget<?>>();
for (MavenResourcesTarget mavenTarget : allTargets) {
if (modules.contains(mavenTarget.getModule())) {
BuildOperations.ensureFSStateInitialized(context, mavenTarget);
BuildOperations.buildTarget(mavenTarget, context, mavenBuilder);
processed.add(mavenTarget);
doneSomething = true;
}
}
if (!processed.isEmpty()) {
BuildOperations.markTargetsUpToDate(context, new BuildTargetChunk(processed));
}
return doneSomething;
}
}
@@ -42,19 +42,6 @@ import java.util.*;
*/
public class MavenResourcesTarget extends ModuleBasedTarget<MavenResourceRootDescriptor> {
private static final Comparator<String> STRING_COMPARATOR = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
private static final Comparator<ResourceRootConfiguration> ROOT_CONFIG_COMPARATOR = new Comparator<ResourceRootConfiguration>() {
@Override
public int compare(ResourceRootConfiguration o1, ResourceRootConfiguration o2) {
return STRING_COMPARATOR.compare(o1.directory, o2.directory);
}
};
MavenResourcesTarget(final MavenResourcesTargetType type, @NotNull JpsModule module) {
super(type, module);
}
@@ -21,9 +21,13 @@ import com.intellij.compiler.CompilerTestUtil;
import com.intellij.compiler.CompilerWorkspaceConfiguration;
import com.intellij.compiler.impl.ModuleCompileScope;
import com.intellij.compiler.impl.TranslatingCompilerFilesMonitor;
import com.intellij.compiler.server.BuildManager;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.*;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.compiler.CompileStatusNotification;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.EmptyProgressIndicator;
@@ -81,6 +85,9 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
Messages.setTestDialog(TestDialog.DEFAULT);
myProjectsManager.projectClosed();
removeFromLocalRepository("test");
if (useJps()) {
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory());
}
super.tearDown();
}
@@ -557,15 +564,9 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
UIUtil.dispatchAllInvocationEvents();
}
}
}
private static String collectMessages(CompileContext compileContext, CompilerMessageCategory messageType) {
String result = "";
for (CompilerMessage each : compileContext.getMessages(messageType)) {
VirtualFile file = each.getVirtualFile();
result += each.getMessage() + " FILE: " + (file == null ? "null" : file.getPath()) + "\n";
if (SwingUtilities.isEventDispatchThread()) {
UIUtil.dispatchAllInvocationEvents();
}
return result;
}
protected static AtomicInteger configConfirmationForYesAnswer() {
@@ -290,7 +290,7 @@ public abstract class MavenTestCase extends UsefulTestCase {
File ioFile = new File(myDir, "settings.xml");
ioFile.createNewFile();
VirtualFile f = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
setFileContent(f, content);
setFileContent(f, content, true);
getMavenGeneralSettings().setUserSettingsFile(f.getPath());
return f;
}
@@ -360,7 +360,7 @@ public abstract class MavenTestCase extends UsefulTestCase {
}.execute().getResultObject();
myAllPoms.add(f);
}
setFileContent(f, createPomXml(xml));
setFileContent(f, createPomXml(xml), true);
return f;
}
@@ -414,7 +414,7 @@ public abstract class MavenTestCase extends UsefulTestCase {
}
}.execute().getResultObject();
}
setFileContent(f, content);
setFileContent(f, content, true);
return f;
}
@@ -472,15 +472,20 @@ public abstract class MavenTestCase extends UsefulTestCase {
protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException {
VirtualFile file = createProjectSubFile(relativePath);
setFileContent(file, content);
setFileContent(file, content, false);
return file;
}
private static void setFileContent(final VirtualFile file, final String content) throws IOException {
private static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException {
new WriteAction<VirtualFile>() {
@Override
protected void run(Result<VirtualFile> result) throws Throwable {
file.setBinaryContent(content.getBytes(), file.getModificationStamp() + 4000, file.getTimeStamp() + 4000);
if (advanceStamps) {
file.setBinaryContent(content.getBytes(), file.getModificationStamp() + 4000, file.getTimeStamp() + 4000);
}
else {
file.setBinaryContent(content.getBytes(), file.getModificationStamp(), file.getTimeStamp());
}
}
}.execute().getResultObject();
}