provide information about build status for generic Target builders

GitOrigin-RevId: 522adbb48fa0b11a62815d43ff3d615bd874a9cd
This commit is contained in:
Eugene Zhuravlev
2023-01-16 16:58:53 +01:00
committed by intellij-monorepo-bot
parent c4fd464e03
commit d1e73bdc6d
11 changed files with 148 additions and 83 deletions

View File

@@ -104,7 +104,7 @@ public abstract class BuildTarget<R extends BuildRootDescriptor> {
/**
* Returns the list of output directories in which this target is going to produce its output. (The specific
* files produced need to be reported by {@link org.jetbrains.jps.incremental.TargetBuilder#build} through
* files produced need to be reported by {@link org.jetbrains.jps.incremental.TargetBuilder#buildTarget} through
*
* {@link BuildOutputConsumer#registerOutputFile}.)
* @param context the compilation context.

View File

@@ -24,7 +24,7 @@ import java.util.Collection;
* Provides list of files under {@link BuildTarget#computeRootDescriptors source roots} of a target which were modified or deleted since the
* previous build.
*
* @see org.jetbrains.jps.incremental.TargetBuilder#build
* @see org.jetbrains.jps.incremental.TargetBuilder#buildTarget
* @see org.jetbrains.jps.incremental.ModuleLevelBuilder#build
*/
public interface DirtyFilesHolder<R extends BuildRootDescriptor, T extends BuildTarget<R>> {

View File

@@ -0,0 +1,47 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.jps.builders.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
public class OutputTracker implements BuildOutputConsumer {
private final BuildOutputConsumer myDelegate;
private int myFilesRegistered = 0;
private int myDirsRegistered = 0;
public OutputTracker(BuildOutputConsumer delegate) {
myDelegate = delegate;
}
@Override
public void registerOutputFile(@NotNull File outputFile, @NotNull Collection<String> sourcePaths) throws IOException {
myFilesRegistered++;
myDelegate.registerOutputFile(outputFile, sourcePaths);
}
@Override
public void registerOutputDirectory(@NotNull File outputDir, @NotNull Collection<String> sourcePaths) throws IOException {
myDirsRegistered++;
myDelegate.registerOutputDirectory(outputDir, sourcePaths);
}
public int getRegisteredFilesCount() {
return myFilesRegistered;
}
public int getRegisteredDirsCount() {
return myDirsRegistered;
}
public boolean isOutputGenerated() {
return myFilesRegistered > 0 || myDirsRegistered > 0;
}
public static OutputTracker create(BuildOutputConsumer consumer) {
return new OutputTracker(consumer);
}
}

View File

@@ -1192,12 +1192,13 @@ public final class IncProjectBuilder {
final List<TargetBuilder<?, ?>> builders = BuilderRegistry.getInstance().getTargetBuilders();
int builderCount = 0;
boolean filesGenerated = false;
for (TargetBuilder<?, ?> builder : builders) {
buildTarget(target, context, builder);
filesGenerated |= buildTarget(target, context, builder);
builderCount++;
buildProgress.updateProgress(target, ((double)builderCount)/builders.size(), context);
}
return true;
return filesGenerated;
}
private static CompileContext wrapWithModuleInfoAppender(CompileContext context, Collection<ModuleBuildTarget> moduleTargets) {
@@ -1282,10 +1283,10 @@ public final class IncProjectBuilder {
}
private <R extends BuildRootDescriptor, T extends BuildTarget<R>>
void buildTarget(final T target, final CompileContext context, TargetBuilder<?, ?> builder) throws ProjectBuildException, IOException {
boolean buildTarget(final T target, final CompileContext context, TargetBuilder<?, ?> builder) throws ProjectBuildException, IOException {
if (builder.getTargetTypes().contains(target.getTargetType())) {
DirtyFilesHolder<R, T> holder = new DirtyFilesHolderBase<R, T>(context) {
DirtyFilesHolder<R, T> holder = new DirtyFilesHolderBase<>(context) {
@Override
public void processDirtyFiles(@NotNull FileProcessor<R, T> processor) throws IOException {
context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor);
@@ -1293,11 +1294,19 @@ public final class IncProjectBuilder {
};
BuildOutputConsumerImpl outputConsumer = new BuildOutputConsumerImpl(target, context);
long start = System.nanoTime();
((TargetBuilder<R, T>)builder).build(target, holder, outputConsumer, context);
//noinspection unchecked
TargetBuilder.ExitCode exitCode = ((TargetBuilder<R, T>)builder).buildTarget(target, holder, outputConsumer, context);
if (exitCode == TargetBuilder.ExitCode.ABORT) {
throw new StopBuildException(
JpsBuildBundle.message("build.message.builder.0.requested.build.stop", builder.getPresentableName())
);
}
storeBuilderStatistics(builder, System.nanoTime() - start, outputConsumer.getNumberOfProcessedSources());
outputConsumer.fireFileGeneratedEvent();
context.checkCanceled();
return exitCode != TargetBuilder.ExitCode.NOTHING_DONE;
}
return false;
}
private static <T extends BuildRootDescriptor> void cleanOldOutputs(final CompileContext context, final BuildTarget<T> target) throws ProjectBuildException{

View File

@@ -37,6 +37,17 @@ public abstract class TargetBuilder<R extends BuildRootDescriptor, T extends Bui
return myTargetTypes;
}
/**
* @deprecated Implement {@link TargetBuilder#buildTarget(BuildTarget, DirtyFilesHolder, BuildOutputConsumer, CompileContext)} instead
*/
public void build(@NotNull T target, @NotNull DirtyFilesHolder<R, T> holder, @NotNull BuildOutputConsumer outputConsumer, @NotNull CompileContext context)
throws ProjectBuildException, IOException {
}
public enum ExitCode {
NOTHING_DONE, OK, ABORT
}
/**
* Builds a single build target.
*
@@ -47,8 +58,12 @@ public abstract class TargetBuilder<R extends BuildRootDescriptor, T extends Bui
* to be reported here.)
* @param context compilation context (can be used to report compiler errors/warnings and to check whether the build
* has been cancelled and needs to be stopped).
* @return exit code describing the builder execution status
*/
public abstract void build(@NotNull T target, @NotNull DirtyFilesHolder<R, T> holder, @NotNull BuildOutputConsumer outputConsumer,
@NotNull CompileContext context) throws ProjectBuildException, IOException;
public ExitCode buildTarget(@NotNull T target, @NotNull DirtyFilesHolder<R, T> holder, @NotNull BuildOutputConsumer outputConsumer, @NotNull CompileContext context) throws ProjectBuildException, IOException {
// default implementation to make third-party implementations of the older API work
build(target, holder, outputConsumer, context);
return ExitCode.OK;
}
}

View File

@@ -42,14 +42,17 @@ public class IncArtifactBuilder extends TargetBuilder<ArtifactRootDescriptor, Ar
}
@Override
public void build(@NotNull ArtifactBuildTarget target,
@NotNull DirtyFilesHolder<ArtifactRootDescriptor, ArtifactBuildTarget> holder,
@NotNull BuildOutputConsumer outputConsumer, @NotNull final CompileContext context) throws ProjectBuildException {
public ExitCode buildTarget(@NotNull ArtifactBuildTarget target,
@NotNull DirtyFilesHolder<ArtifactRootDescriptor, ArtifactBuildTarget> holder,
@NotNull BuildOutputConsumer outputConsumer, @NotNull final CompileContext context) throws ProjectBuildException {
final boolean doneSomething;
try {
new IncArtifactBuilderHelper(target, outputConsumer, context).build(holder);
} catch (IOException e) {
doneSomething = new IncArtifactBuilderHelper(target, outputConsumer, context).build(holder);
}
catch (IOException e) {
throw new ProjectBuildException(e);
}
return doneSomething? ExitCode.OK : ExitCode.NOTHING_DONE;
}
@NotNull
@@ -84,7 +87,7 @@ public class IncArtifactBuilder extends TargetBuilder<ArtifactRootDescriptor, Ar
this.outSrcMapping = pd.dataManager.getStorage(target, ArtifactOutToSourceStorageProvider.INSTANCE);
}
public void build(DirtyFilesHolder<ArtifactRootDescriptor, ArtifactBuildTarget> holder) throws ProjectBuildException, IOException {
public boolean build(DirtyFilesHolder<ArtifactRootDescriptor, ArtifactBuildTarget> holder) throws ProjectBuildException, IOException {
if (startBuild()) {
createAndRunArtifactTasks(ArtifactBuildTaskProvider.ArtifactBuildPhase.PRE_PROCESSING);
@@ -98,7 +101,9 @@ public class IncArtifactBuilder extends TargetBuilder<ArtifactRootDescriptor, Ar
createAndRunArtifactTasks(ArtifactBuildTaskProvider.ArtifactBuildPhase.FINISHING_BUILD);
createAndRunArtifactTasks(ArtifactBuildTaskProvider.ArtifactBuildPhase.POST_PROCESSING);
return true;
}
return false;
}
private boolean startBuild() {

View File

@@ -32,18 +32,18 @@ public final class ProjectDependenciesResolver extends TargetBuilder<BuildRootDe
}
@Override
public void build(@NotNull ProjectDependenciesResolvingTarget target,
@NotNull DirtyFilesHolder<BuildRootDescriptor, ProjectDependenciesResolvingTarget> holder,
@NotNull BuildOutputConsumer outputConsumer,
@NotNull CompileContext context) {
public ExitCode buildTarget(@NotNull ProjectDependenciesResolvingTarget target,
@NotNull DirtyFilesHolder<BuildRootDescriptor, ProjectDependenciesResolvingTarget> holder,
@NotNull BuildOutputConsumer outputConsumer,
@NotNull CompileContext context) {
context.processMessage(new ProgressMessage(JpsBuildBundle.message("progress.message.resolving.repository.libraries.in.the.project")));
try {
DependencyResolvingBuilder.resolveMissingDependencies(context, context.getProjectDescriptor().getProject().getModules(),
BuildTargetChunk.forSingleTarget(target));
DependencyResolvingBuilder.resolveMissingDependencies(context, context.getProjectDescriptor().getProject().getModules(), BuildTargetChunk.forSingleTarget(target));
}
catch (Exception e) {
DependencyResolvingBuilder.reportError(context, "project", e);
}
return ExitCode.OK;
}
@NotNull

View File

@@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.JpsBuildBundle;
import org.jetbrains.jps.builders.impl.OutputTracker;
import org.jetbrains.jps.builders.java.ResourceRootDescriptor;
import org.jetbrains.jps.builders.java.ResourcesTargetType;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
@@ -43,14 +44,14 @@ public class ResourcesBuilder extends TargetBuilder<ResourceRootDescriptor, Reso
}
@Override
public void build(@NotNull ResourcesTarget target,
@NotNull DirtyFilesHolder<ResourceRootDescriptor, ResourcesTarget> holder,
@NotNull BuildOutputConsumer outputConsumer,
@NotNull CompileContext context) throws ProjectBuildException, IOException {
public ExitCode buildTarget(@NotNull ResourcesTarget target,
@NotNull DirtyFilesHolder<ResourceRootDescriptor, ResourcesTarget> holder,
@NotNull BuildOutputConsumer outputConsumer,
@NotNull CompileContext context) throws ProjectBuildException, IOException {
if (!isResourceProcessingEnabled(target.getModule())) {
return;
return ExitCode.NOTHING_DONE;
}
final OutputTracker out = OutputTracker.create(outputConsumer);
try {
final Map<ResourceRootDescriptor, Boolean> skippedRoots = new HashMap<>();
holder.processDirtyFiles((t, f, srcRoot) -> {
@@ -64,7 +65,7 @@ public class ResourcesBuilder extends TargetBuilder<ResourceRootDescriptor, Reso
return true;
}
try {
copyResource(context, srcRoot, f, outputConsumer);
copyResource(context, srcRoot, f, out);
return !context.getCancelStatus().isCanceled();
}
catch (IOException e) {
@@ -86,6 +87,7 @@ public class ResourcesBuilder extends TargetBuilder<ResourceRootDescriptor, Reso
catch (Exception e) {
throw new ProjectBuildException(e.getMessage(), e);
}
return out.isOutputGenerated()? ExitCode.OK : ExitCode.NOTHING_DONE;
}
private static boolean isResourceProcessingEnabled(JpsModule module) {

View File

@@ -8,7 +8,7 @@ import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.FileProcessor;
import org.jetbrains.jps.builders.impl.OutputTracker;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.gradle.GradleJpsBundle;
import org.jetbrains.jps.gradle.model.JpsGradleExtensionService;
@@ -21,7 +21,6 @@ import org.jetbrains.jps.incremental.java.JavaBuilder;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.*;
@@ -36,36 +35,26 @@ public class GradleResourcesBuilder extends TargetBuilder<GradleResourceRootDesc
}
@Override
public void build(@NotNull final GradleResourcesTarget target,
@NotNull final DirtyFilesHolder<GradleResourceRootDescriptor, GradleResourcesTarget> holder,
@NotNull final BuildOutputConsumer outputConsumer,
@NotNull final CompileContext context) throws ProjectBuildException, IOException {
public ExitCode buildTarget(@NotNull final GradleResourcesTarget target,
@NotNull final DirtyFilesHolder<GradleResourceRootDescriptor, GradleResourcesTarget> holder,
@NotNull final BuildOutputConsumer outputConsumer,
@NotNull final CompileContext context) throws ProjectBuildException, IOException {
if (!JavaBuilder.IS_ENABLED.get(context, Boolean.TRUE)) {
return;
return ExitCode.NOTHING_DONE;
}
final BuildDataPaths dataPaths = context.getProjectDescriptor().dataManager.getDataPaths();
final GradleProjectConfiguration projectConfig = JpsGradleExtensionService.getInstance().getGradleProjectConfiguration(dataPaths);
final GradleModuleResourceConfiguration config = target.getModuleResourcesConfiguration(dataPaths);
if (config == null) return;
if (config == null) {
return ExitCode.NOTHING_DONE;
}
final Map<GradleResourceRootDescriptor, List<File>> files = new HashMap<>();
holder.processDirtyFiles(new FileProcessor<GradleResourceRootDescriptor, GradleResourcesTarget>() {
@Override
public boolean apply(GradleResourcesTarget t, File file, GradleResourceRootDescriptor rd) throws IOException {
assert target == t;
List<File> fileList = files.get(rd);
if (fileList == null) {
fileList = new ArrayList<>();
files.put(rd, fileList);
}
fileList.add(file);
return true;
}
holder.processDirtyFiles((t, file, rd) -> {
assert target == t;
files.computeIfAbsent(rd, k -> new ArrayList<>()).add(file);
return true;
});
GradleResourceRootDescriptor[] roots = files.keySet().toArray(new GradleResourceRootDescriptor[0]);
@@ -92,18 +81,10 @@ public class GradleResourcesBuilder extends TargetBuilder<GradleResourceRootDesc
}
catch (Throwable t) {
LOG.warn("Can not create resource file processor", t);
fileProcessor = new ResourceFileProcessor() {
@Override
public void copyFile(File file,
Ref<File> targetFileRef,
ResourceRootConfiguration rootConfiguration,
CompileContext context,
FileFilter filteringFilter) throws IOException {
FSOperations.copy(file, targetFileRef.get());
}
};
fileProcessor = (file, targetFileRef, rootConfiguration, ctx, filteringFilter) -> FSOperations.copy(file, targetFileRef.get());
}
final OutputTracker out = OutputTracker.create(outputConsumer);
for (GradleResourceRootDescriptor rd : roots) {
for (File file : files.get(rd)) {
@@ -118,14 +99,17 @@ public class GradleResourcesBuilder extends TargetBuilder<GradleResourceRootDesc
final Ref<File> fileRef = Ref.create(new File(outputDir, relPath));
fileProcessor.copyFile(file, fileRef, rd.getConfiguration(), context, FileFilters.EVERYTHING);
outputConsumer.registerOutputFile(fileRef.get(), Collections.singleton(file.getPath()));
out.registerOutputFile(fileRef.get(), Collections.singleton(file.getPath()));
if (context.getCancelStatus().isCanceled()) return;
if (context.getCancelStatus().isCanceled()) {
return ExitCode.OK;
}
}
}
context.checkCanceled();
context.processMessage(new ProgressMessage(""));
return out.isOutputGenerated()? ExitCode.OK : ExitCode.NOTHING_DONE;
}
@Override

View File

@@ -5,8 +5,8 @@ import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.impl.OutputTracker;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.model.java.JpsJavaClasspathKind;
@@ -38,20 +38,20 @@ public class GroovyResourceChecker extends TargetBuilder<GroovyResourceRootDescr
}
@Override
public void build(@NotNull final CheckResourcesTarget target,
@NotNull DirtyFilesHolder<GroovyResourceRootDescriptor, CheckResourcesTarget> holder,
@NotNull final BuildOutputConsumer outputConsumer,
@NotNull CompileContext context) throws ProjectBuildException, IOException {
public ExitCode buildTarget(@NotNull final CheckResourcesTarget target,
@NotNull DirtyFilesHolder<GroovyResourceRootDescriptor, CheckResourcesTarget> holder,
@NotNull final BuildOutputConsumer outputConsumer,
@NotNull CompileContext context) throws ProjectBuildException, IOException {
if (context.getBuilderParameter(CHECKING_RESOURCES_REBUILD.toString()) == null) {
return;
return ExitCode.NOTHING_DONE;
}
new ResourceCheckingGroovycRunner(target).doBuild(context, singleModuleChunk(target.getModule()), holder, this, new GroovyOutputConsumer() {
@Override
public void registerCompiledClass(BuildTarget<?> target, File srcFile, File outputFile, byte[] bytes) throws IOException {
outputConsumer.registerOutputFile(outputFile, Collections.singleton(srcFile.getPath()));
}
});
final OutputTracker out = OutputTracker.create(outputConsumer);
new ResourceCheckingGroovycRunner(target).doBuild(
context, singleModuleChunk(target.getModule()), holder, this,
(tgt, srcFile, outputFile, bytes) -> out.registerOutputFile(outputFile, Collections.singleton(srcFile.getPath()))
);
return out.isOutputGenerated()? ExitCode.OK : ExitCode.NOTHING_DONE;
}
@NotNull

View File

@@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.FileProcessor;
import org.jetbrains.jps.builders.impl.OutputTracker;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.ProjectBuildException;
@@ -36,7 +37,7 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
}
@Override
public void build(@NotNull final MavenResourcesTarget target, @NotNull final DirtyFilesHolder<MavenResourceRootDescriptor, MavenResourcesTarget> holder, @NotNull final BuildOutputConsumer outputConsumer, @NotNull final CompileContext context) throws ProjectBuildException, IOException {
public ExitCode buildTarget(@NotNull final MavenResourcesTarget target, @NotNull final DirtyFilesHolder<MavenResourceRootDescriptor, MavenResourcesTarget> holder, @NotNull final BuildOutputConsumer outputConsumer, @NotNull final CompileContext context) throws ProjectBuildException, IOException {
final BuildDataPaths dataPaths = context.getProjectDescriptor().dataManager.getDataPaths();
final MavenProjectConfiguration projectConfig = JpsMavenExtensionService.getInstance().getMavenProjectConfiguration(dataPaths);
if (projectConfig == null) {
@@ -47,12 +48,12 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
final MavenModuleResourceConfiguration config = target.getModuleResourcesConfiguration(dataPaths);
if (config == null) {
return;
return ExitCode.NOTHING_DONE;
}
final Map<MavenResourceRootDescriptor, List<File>> files = new HashMap<>();
holder.processDirtyFiles(new FileProcessor<MavenResourceRootDescriptor, MavenResourcesTarget>() {
holder.processDirtyFiles(new FileProcessor<>() {
@Override
public boolean apply(MavenResourcesTarget t, File file, MavenResourceRootDescriptor rd) throws IOException {
@@ -89,7 +90,8 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
return res;
});
MavenResourceFileProcessor fileProcessor = new MavenResourceFileProcessor(projectConfig, target.getModule().getProject(), config);
final MavenResourceFileProcessor fileProcessor = new MavenResourceFileProcessor(projectConfig, target.getModule().getProject(), config);
final OutputTracker out = OutputTracker.create(outputConsumer);
context.processMessage(new ProgressMessage(MavenJpsBundle.message("copying.resources", target.getModule().getName())));
for (MavenResourceRootDescriptor rd : roots) {
@@ -108,7 +110,7 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
String sourcePath = file.getPath();
try {
fileProcessor.copyFile(file, outputFile, rd.getConfiguration(), context, FileFilters.EVERYTHING);
outputConsumer.registerOutputFile(outputFile, Collections.singleton(sourcePath));
out.registerOutputFile(outputFile, Collections.singleton(sourcePath));
}
catch (UnsupportedEncodingException e) {
context.processMessage(
@@ -122,14 +124,15 @@ public class MavenResourcesBuilder extends TargetBuilder<MavenResourceRootDescri
}
if (context.getCancelStatus().isCanceled()) {
return;
return out.isOutputGenerated()? ExitCode.OK : ExitCode.NOTHING_DONE;
}
}
}
context.checkCanceled();
context.processMessage(new ProgressMessage(""));
return out.isOutputGenerated()? ExitCode.OK : ExitCode.NOTHING_DONE;
}
@Override