From cc69834c831eff3e78134fe848a50147259b2342 Mon Sep 17 00:00:00 2001 From: Ittai Zeidman Date: Fri, 15 Nov 2019 12:23:49 +0200 Subject: [PATCH] if partial success (compilation issue) we issue another bazel build with info only This is to make sure we have the needed metadata even if build broke Relates to: https://github.com/bazelbuild/intellij/issues/1167 https://github.com/bazelbuild/bazel/issues/9413 Fix test --- .../blaze/base/sync/BlazeBuildParams.java | 7 ++++++ .../blaze/base/sync/BuildPhaseSyncTask.java | 4 +++- .../blaze/base/sync/SyncPhaseCoordinator.java | 23 +++++++++++++++++++ .../sharding/BlazeBuildTargetSharderTest.java | 1 + 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/base/src/com/google/idea/blaze/base/sync/BlazeBuildParams.java b/base/src/com/google/idea/blaze/base/sync/BlazeBuildParams.java index 9033879f7e1..74358a09b6d 100644 --- a/base/src/com/google/idea/blaze/base/sync/BlazeBuildParams.java +++ b/base/src/com/google/idea/blaze/base/sync/BlazeBuildParams.java @@ -32,6 +32,7 @@ public static BlazeBuildParams fromProject(Project project) { .setBlazeBinaryPath(provider.getSyncBinaryPath(project)) .setBlazeBinaryType(binaryType) .setParallelizeBuilds(binaryType.isRemote) + .setInfoOnly(false) .build(); } @@ -39,6 +40,10 @@ public static BlazeBuildParams fromProject(Project project) { public abstract BuildBinaryType blazeBinaryType(); + public abstract boolean infoOnly(); + + public abstract Builder toBuilder(); + /** * Whether batched build invocations are run in parallel, when possible (only when building * remotely). @@ -57,6 +62,8 @@ public abstract static class Builder { public abstract Builder setBlazeBinaryType(BuildBinaryType value); + public abstract Builder setInfoOnly(boolean value); + // not public; derived from BuildBinaryType abstract Builder setParallelizeBuilds(boolean parallelizeBuilds); diff --git a/base/src/com/google/idea/blaze/base/sync/BuildPhaseSyncTask.java b/base/src/com/google/idea/blaze/base/sync/BuildPhaseSyncTask.java index dbebe1af416..5cf197a4ab3 100644 --- a/base/src/com/google/idea/blaze/base/sync/BuildPhaseSyncTask.java +++ b/base/src/com/google/idea/blaze/base/sync/BuildPhaseSyncTask.java @@ -328,7 +328,9 @@ private BlazeBuildOutputs getBlazeBuildResult( projectState.getBlazeInfo(), shardedTargets, projectState.getLanguageSettings(), - ImmutableSet.of(OutputGroup.RESOLVE, OutputGroup.INFO)); + syncParams.blazeBuildParams().infoOnly() ? + ImmutableSet.of(OutputGroup.INFO): + ImmutableSet.of(OutputGroup.INFO, OutputGroup.RESOLVE)); }); } } diff --git a/base/src/com/google/idea/blaze/base/sync/SyncPhaseCoordinator.java b/base/src/com/google/idea/blaze/base/sync/SyncPhaseCoordinator.java index b13edbd481c..b4b002a7e73 100644 --- a/base/src/com/google/idea/blaze/base/sync/SyncPhaseCoordinator.java +++ b/base/src/com/google/idea/blaze/base/sync/SyncPhaseCoordinator.java @@ -391,6 +391,10 @@ void runSync(BlazeSyncParams params, boolean singleThreaded, BlazeContext contex projectState != null ? BuildPhaseSyncTask.runBuildPhase(project, params, projectState, buildId, context) : BlazeSyncBuildResult.builder().build(); + //If we have partial success we'll run the build again this time only with intellij-info-java + if (projectState != null && syncResultFromBuildPhase(buildResult, context) == SyncResult.PARTIAL_SUCCESS) { + buildResult = syncInfoOnly(params, context, buildId, projectState, buildResult); + } UpdatePhaseTask task = UpdatePhaseTask.builder() .setStartTime(startTime) @@ -418,6 +422,25 @@ void runSync(BlazeSyncParams params, boolean singleThreaded, BlazeContext contex } } + private BlazeSyncBuildResult syncInfoOnly(BlazeSyncParams params, BlazeContext context, + int buildId, SyncProjectState projectState, BlazeSyncBuildResult buildResult) { + final BlazeSyncParams infoOnlySyncParams = params.toBuilder().setBlazeBuildParams( + params.blazeBuildParams().toBuilder().setInfoOnly(true).build() + ).build(); + final BlazeSyncBuildResult infoOnlySyncResult = BuildPhaseSyncTask + .runBuildPhase(project, infoOnlySyncParams, projectState, buildId, context); + /* + * updateResult should be used the other way around [ olderRun.updateResult(newerRun) ] + * since that is used to remove stale/old artifacts from targets which boths runs "saw" + * In our case both runs are sequential without artifacts changing. + * The second run only has IDE-INFO files + * For every target the first run was able to process it has all the data (first run does IDE-INFO and Resolve) + * What happens when we updateResult as below is that we basically just add the IDE-INFO files + * of the broken targets from the second run into the first run + */ + return infoOnlySyncResult.updateResult(buildResult); + } + private void queueUpdateTask( UpdatePhaseTask task, @Nullable ToolWindowScope syncToolWindowScope, BlazeSyncParams params) { synchronized (this) { diff --git a/base/tests/unittests/com/google/idea/blaze/base/sync/sharding/BlazeBuildTargetSharderTest.java b/base/tests/unittests/com/google/idea/blaze/base/sync/sharding/BlazeBuildTargetSharderTest.java index 482eae3fb98..a01c9e56b9a 100644 --- a/base/tests/unittests/com/google/idea/blaze/base/sync/sharding/BlazeBuildTargetSharderTest.java +++ b/base/tests/unittests/com/google/idea/blaze/base/sync/sharding/BlazeBuildTargetSharderTest.java @@ -373,6 +373,7 @@ private ShardedTargetsResult expandAndShardTargets( BlazeBuildParams.builder() .setBlazeBinaryPath("foo") .setBlazeBinaryType(buildBinaryType) + .setInfoOnly(false) .build(), ProjectViewSet.builder().add(projectView).build(), new WorkspacePathResolverImpl(workspaceRoot),