mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
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:
@@ -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() {
|
||||
|
||||
+129
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-13
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user