diff --git a/base/src/META-INF/blaze-base.xml b/base/src/META-INF/blaze-base.xml index da34e9df219..b1bf1eed23f 100644 --- a/base/src/META-INF/blaze-base.xml +++ b/base/src/META-INF/blaze-base.xml @@ -408,9 +408,6 @@ - diff --git a/base/src/com/google/idea/blaze/base/async/executor/ProgressIndicatorStub.kt b/base/src/com/google/idea/blaze/base/async/executor/ProgressIndicatorStub.kt deleted file mode 100644 index fa24de52e9a..00000000000 --- a/base/src/com/google/idea/blaze/base/async/executor/ProgressIndicatorStub.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.google.idea.blaze.base.async.executor - -import com.intellij.openapi.application.ModalityState -import com.intellij.openapi.progress.ProgressIndicator -import com.intellij.openapi.progress.TaskInfo -import com.intellij.openapi.wm.ex.ProgressIndicatorEx - -object ProgressIndicatorStub : ProgressIndicatorEx { - override fun start() { } - - override fun stop() { } - - override fun isRunning(): Boolean { return false } - - override fun cancel() { } - - override fun isCanceled(): Boolean { return false } - - override fun setText(p0: String?) { } - - override fun getText(): String { return "" } - - override fun setText2(p0: String?) { } - - override fun getText2(): String { return "" } - - override fun getFraction(): Double { return 0.0 } - - override fun setFraction(p0: Double) { } - - override fun pushState() { } - - override fun popState() { } - - override fun isModal(): Boolean { return false } - - override fun getModalityState(): ModalityState { return ModalityState.NON_MODAL /* required for backwards compatability */ } - - override fun setModalityProgress(p0: ProgressIndicator?) { } - - override fun isIndeterminate(): Boolean { return false; } - - override fun setIndeterminate(p0: Boolean) { } - - override fun checkCanceled() { } - - override fun isPopupWasShown(): Boolean { return false; } - - override fun isShowing(): Boolean { return false; } - - override fun addStateDelegate(p0: ProgressIndicatorEx) { } - - override fun finish(p0: TaskInfo) { } - - override fun isFinished(p0: TaskInfo): Boolean { return false; } - - override fun wasStarted(): Boolean { return false; } - - override fun processFinish() { } - - override fun initStateFrom(p0: ProgressIndicator) { } -} \ No newline at end of file diff --git a/base/src/com/google/idea/blaze/base/async/executor/ProgressiveTaskWithProgressIndicator.java b/base/src/com/google/idea/blaze/base/async/executor/ProgressiveTaskWithProgressIndicator.java index 8511e931108..63256bd9757 100644 --- a/base/src/com/google/idea/blaze/base/async/executor/ProgressiveTaskWithProgressIndicator.java +++ b/base/src/com/google/idea/blaze/base/async/executor/ProgressiveTaskWithProgressIndicator.java @@ -20,9 +20,11 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.progress.PerformInBackgroundOption; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Progressive; +import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase; import com.intellij.openapi.progress.util.ProgressWindow; @@ -106,7 +108,7 @@ public void submitTaskLater(Progressive progressive) { */ public ListenableFuture submitTaskWithResult(ProgressiveWithResult progressive) { if (modality == Modality.BUILD_VIEW) { - return executor.submit(() -> progressive.compute(ProgressIndicatorStub.INSTANCE)); + return executor.submit(() -> progressive.compute(new EmptyProgressIndicator(ModalityState.NON_MODAL))); } // The progress indicator must be created on the UI thread. diff --git a/base/src/com/google/idea/blaze/base/buildview/BazelService.kt b/base/src/com/google/idea/blaze/base/buildview/BazelExecService.kt similarity index 80% rename from base/src/com/google/idea/blaze/base/buildview/BazelService.kt rename to base/src/com/google/idea/blaze/base/buildview/BazelExecService.kt index a39d216d25a..6b6c6e55d89 100644 --- a/base/src/com/google/idea/blaze/base/buildview/BazelService.kt +++ b/base/src/com/google/idea/blaze/base/buildview/BazelExecService.kt @@ -28,13 +28,13 @@ import java.io.BufferedInputStream import java.io.FileInputStream import kotlin.io.path.pathString -private val LOG: Logger = Logger.getInstance(BazelService::class.java) +private val LOG: Logger = Logger.getInstance(BazelExecService::class.java) @Service(Service.Level.PROJECT) -class BazelService(private val project: Project) : Disposable { +class BazelExecService(private val project: Project) : Disposable { companion object { @JvmStatic - fun instance(project: Project): BazelService = project.service() + fun instance(project: Project): BazelExecService = project.service() } // #api223 use the injected scope @@ -67,27 +67,34 @@ class BazelService(private val project: Project) : Disposable { private suspend fun execute(ctx: BlazeContext, cmd: BlazeCommand): Int { val root = cmd.effectiveWorkspaceRoot.orElseGet { WorkspaceRoot.fromProject(project).path() } - val handler = GeneralCommandLine() + val cmdLine = GeneralCommandLine() .withExePath(cmd.binaryPath) .withParameters(cmd.toArgumentList()) .apply { setWorkDirectory(root.pathString) } // required for backwards compatability .withRedirectErrorStream(true) - .let(::OSProcessHandler) - handler.addProcessListener(object : ProcessListener { - override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) { - ctx.println(event.text.trimEnd()) + var handler: OSProcessHandler? = null + val exitCode = try { + handler = withContext(Dispatchers.IO) { + OSProcessHandler(cmdLine) } - }) - handler.startNotify() - try { - while (!handler.isProcessTerminated) delay(100) + handler.addProcessListener(object : ProcessListener { + override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) { + ctx.println(event.text.trimEnd()) + } + }) + handler.startNotify() + + while (!handler.isProcessTerminated) { + delay(100) + } + + handler.exitCode ?: 1 } finally { - handler.destroyProcess() + handler?.destroyProcess() } - val exitCode = handler.exitCode ?: 1 if (exitCode != 0) { ctx.setHasError() } @@ -97,12 +104,17 @@ class BazelService(private val project: Project) : Disposable { private suspend fun parseEvent(ctx: BlazeContext, stream: BufferedInputStream) { // make sure that there are at least four bytes already available - while (stream.available() < 4) delay(10) + while (stream.available() < 4) { + delay(10) + } // protobuf messages are delimited by size (encoded as varint32), // read size manually to ensure the entire message is already available val size = CodedInputStream.readRawVarint32(stream.read(), stream) - while (stream.available() < size) delay(10) + + while (stream.available() < size) { + delay(10) + } val eventStream = LimitedInputStream(stream, size) val event = try { @@ -118,18 +130,16 @@ class BazelService(private val project: Project) : Disposable { return } - if (event == null) { - delay(10) - } else { - BuildEventParser.parse(event)?.let(ctx::output) - } + BuildEventParser.parse(event)?.let(ctx::output) } private fun CoroutineScope.parseEvents(ctx: BlazeContext, helper: BuildResultHelper): Job { - return launch(CoroutineName("EventParser")) { + return launch(Dispatchers.IO + CoroutineName("EventParser")) { try { // wait for bazel to create the output file - while (!helper.outputFile.exists()) delay(10) + while (!helper.outputFile.exists()) { + delay(10) + } FileInputStream(helper.outputFile).buffered().use { stream -> // keep reading events while the coroutine is active, i.e. bazel is still running, @@ -138,11 +148,9 @@ class BazelService(private val project: Project) : Disposable { parseEvent(ctx, stream) } } - } - catch (e: CancellationException) { + } catch (e: CancellationException) { throw e - } - catch (e: Exception) { + } catch (e: Exception) { LOG.error("error in event parser", e) } } diff --git a/base/src/com/google/idea/blaze/base/buildview/BuildViewMigration.kt b/base/src/com/google/idea/blaze/base/buildview/BuildViewMigration.kt index 34796e2ea92..94298024165 100644 --- a/base/src/com/google/idea/blaze/base/buildview/BuildViewMigration.kt +++ b/base/src/com/google/idea/blaze/base/buildview/BuildViewMigration.kt @@ -2,11 +2,12 @@ package com.google.idea.blaze.base.buildview import com.google.idea.blaze.base.async.executor.ProgressiveTaskWithProgressIndicator import com.google.idea.blaze.base.scope.BlazeContext -import com.intellij.openapi.util.registry.Registry +import com.google.idea.blaze.base.settings.BlazeUserSettings object BuildViewMigration { @JvmStatic - val enabled get(): Boolean = Registry.`is`("bazel.new.sync.view") + val enabled + get(): Boolean = BlazeUserSettings.getInstance().useNewSyncView @JvmStatic fun present(ctx: BlazeContext): Boolean { diff --git a/base/src/com/google/idea/blaze/base/buildview/ContextExt.kt b/base/src/com/google/idea/blaze/base/buildview/ContextExt.kt index a5d615348c1..f1e2c8bead9 100644 --- a/base/src/com/google/idea/blaze/base/buildview/ContextExt.kt +++ b/base/src/com/google/idea/blaze/base/buildview/ContextExt.kt @@ -5,7 +5,6 @@ import com.google.idea.blaze.common.PrintOutput import com.intellij.openapi.progress.runBlockingMaybeCancellable import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async fun BlazeContext.println(msg: String) { @@ -17,7 +16,7 @@ fun BlazeContext.pushJob( name: String = "BazelContext", block: suspend CoroutineScope.() -> T, ): T { - val deferred = scope.async(Dispatchers.IO + CoroutineName(name)) { block() } + val deferred = scope.async(CoroutineName(name)) { block() } addCancellationHandler { deferred.cancel() } diff --git a/base/src/com/google/idea/blaze/base/buildview/events/BuildEventParser.kt b/base/src/com/google/idea/blaze/base/buildview/events/BuildEventParser.kt index 79b0466f248..4dc9b8ef89c 100644 --- a/base/src/com/google/idea/blaze/base/buildview/events/BuildEventParser.kt +++ b/base/src/com/google/idea/blaze/base/buildview/events/BuildEventParser.kt @@ -2,10 +2,10 @@ package com.google.idea.blaze.base.buildview.events import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEvent import com.google.idea.blaze.base.scope.output.IssueOutput -import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.extensions.ExtensionPointName -internal val LOG = Logger.getInstance(BuildEventParser::class.java) +internal val LOG = logger() interface BuildEventParser { companion object { diff --git a/base/src/com/google/idea/blaze/base/settings/BlazeUserSettings.java b/base/src/com/google/idea/blaze/base/settings/BlazeUserSettings.java index 28d9394e062..cbdba288cae 100644 --- a/base/src/com/google/idea/blaze/base/settings/BlazeUserSettings.java +++ b/base/src/com/google/idea/blaze/base/settings/BlazeUserSettings.java @@ -73,6 +73,7 @@ public String toString() { private boolean expandSyncToWorkingSet = true; private boolean showPerformanceWarnings = false; private boolean collapseProjectView = true; + private boolean useNewSyncView = false; private boolean javascriptTestrunnersEnabled = false; @@ -207,6 +208,14 @@ public void setCollapseProjectView(boolean collapseProjectView) { this.collapseProjectView = collapseProjectView; } + public boolean getUseNewSyncView() { + return useNewSyncView; + } + + public void setUseNewSyncView(boolean useNewSyncView) { + this.useNewSyncView = useNewSyncView; + } + public boolean isJavascriptTestrunnersEnabled() { return javascriptTestrunnersEnabled; } @@ -269,6 +278,7 @@ public ImmutableMap getApplicationSettings() { builder.put("blazeBinaryPath", settings.blazeBinaryPath); builder.put("bazelBinaryPath", settings.bazelBinaryPath); builder.put("buildifierBinaryPath", settings.buildifierBinaryPath); + builder.put("useNewSyncView", Boolean.toString(settings.useNewSyncView)); return builder.build(); } } diff --git a/base/src/com/google/idea/blaze/base/settings/ui/BlazeUserSettingsConfigurable.java b/base/src/com/google/idea/blaze/base/settings/ui/BlazeUserSettingsConfigurable.java index 40a2775d0a6..a88dc825b9d 100644 --- a/base/src/com/google/idea/blaze/base/settings/ui/BlazeUserSettingsConfigurable.java +++ b/base/src/com/google/idea/blaze/base/settings/ui/BlazeUserSettingsConfigurable.java @@ -110,6 +110,12 @@ public ImmutableCollection getSearchableText() { .setter(BlazeUserSettings::setCollapseProjectView) .componentFactory(SimpleComponent::createCheckBox); + private static final ConfigurableSetting USE_NEW_SYNC_VIEW = + setting("Use the new sync view") + .getter(BlazeUserSettings::getUseNewSyncView) + .setter(BlazeUserSettings::setUseNewSyncView) + .componentFactory(SimpleComponent::createCheckBox); + private static final ConfigurableSetting ALWAYS_SELECT_NEWEST_CHILD_TASK = setting("Always select the newest child task in Blaze view") .getter(BlazeUserSettings::getSelectNewestChildTask) @@ -170,6 +176,7 @@ public ImmutableCollection getSearchableText() { SHOW_PROBLEMS_VIEW_ON_RUN, ALLOW_JAVASCRIPT_TESTS, COLLAPSE_PROJECT_VIEW, + USE_NEW_SYNC_VIEW, FORMAT_BUILD_FILES_ON_SAVE, SHOW_ADD_FILE_TO_PROJECT, ALWAYS_SELECT_NEWEST_CHILD_TASK, @@ -199,6 +206,7 @@ public JComponent createComponent() { return SwingHelper.newLeftAlignedVerticalPanel( getFocusBehaviorSettingsUi(), createVerticalPanel( + USE_NEW_SYNC_VIEW, COLLAPSE_PROJECT_VIEW, ALLOW_JAVASCRIPT_TESTS, FORMAT_BUILD_FILES_ON_SAVE, diff --git a/base/src/com/google/idea/blaze/base/sync/BlazeSyncManager.java b/base/src/com/google/idea/blaze/base/sync/BlazeSyncManager.java index b2a9f726273..b0ed1f6805f 100644 --- a/base/src/com/google/idea/blaze/base/sync/BlazeSyncManager.java +++ b/base/src/com/google/idea/blaze/base/sync/BlazeSyncManager.java @@ -64,7 +64,6 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import java.util.Collection; @@ -123,7 +122,7 @@ public void requestProjectSync(BlazeSyncParams syncParams) { indicator -> Scope.root( context -> { - if (Registry.is("bazel.new.sync.view")) { + if (BuildViewMigration.getEnabled()) { context.push(new BuildViewScope(project, getRootInvocationTitle(syncParams))); } 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 ed1f476a0cd..bbf4b06d3a9 100644 --- a/base/src/com/google/idea/blaze/base/sync/BuildPhaseSyncTask.java +++ b/base/src/com/google/idea/blaze/base/sync/BuildPhaseSyncTask.java @@ -16,6 +16,7 @@ package com.google.idea.blaze.base.sync; import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.idea.blaze.base.issueparser.BlazeIssueParser.targetDetectionQueryParsers; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -398,6 +399,7 @@ private ImmutableList findTargetsBuildingSourceFiles( var newScope = new ToolWindowScope.Builder(project, task) .setProgressIndicator(indicator) .setPopupBehavior(BlazeUserSettings.FocusBehavior.ON_ERROR) + .setIssueParsers(targetDetectionQueryParsers(project, WorkspaceRoot.fromProject(project))) .build(); childContext.push(newScope); } diff --git a/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java b/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java index 112bb0edc9d..319f8ab8b76 100644 --- a/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java +++ b/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java @@ -34,13 +34,12 @@ import com.google.idea.blaze.base.async.FutureUtil; import com.google.idea.blaze.base.async.executor.BlazeExecutor; import com.google.idea.blaze.base.bazel.BuildSystem.BuildInvoker; -import com.google.idea.blaze.base.buildview.BazelService; +import com.google.idea.blaze.base.buildview.BazelExecService; import com.google.idea.blaze.base.command.BlazeCommand; import com.google.idea.blaze.base.command.BlazeCommandName; import com.google.idea.blaze.base.command.BlazeFlags; import com.google.idea.blaze.base.command.BlazeInvocationContext; import com.google.idea.blaze.base.command.BlazeInvocationContext.ContextType; -import com.google.idea.blaze.base.command.buildresult.BuildResultHelper; import com.google.idea.blaze.base.command.buildresult.LocalFileArtifact; import com.google.idea.blaze.base.command.buildresult.RemoteOutputArtifact; import com.google.idea.blaze.base.command.info.BlazeConfigurationHandler; @@ -772,7 +771,7 @@ private static BlazeBuildOutputs runBuildForTargets( aspectStrategy.addAspectAndOutputGroups( builder, outputGroups, activeLanguages, onlyDirectDeps); - return BazelService.instance(project).build(context, builder); + return BazelExecService.instance(project).build(context, builder); } finally { if (!Registry.is("bazel.sync.keep.target.files")) { try { diff --git a/kotlin/src/com/google/idea/blaze/kotlin/sync/BlazeKotlinSyncPlugin.java b/kotlin/src/com/google/idea/blaze/kotlin/sync/BlazeKotlinSyncPlugin.java index 2847370bba1..7828879fc41 100644 --- a/kotlin/src/com/google/idea/blaze/kotlin/sync/BlazeKotlinSyncPlugin.java +++ b/kotlin/src/com/google/idea/blaze/kotlin/sync/BlazeKotlinSyncPlugin.java @@ -20,7 +20,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.google.idea.blaze.base.async.executor.ProgressIndicatorStub; import com.google.idea.blaze.base.ideinfo.KotlinToolchainIdeInfo; import com.google.idea.blaze.base.model.BlazeProjectData; import com.google.idea.blaze.base.model.BlazeVersionData; @@ -42,9 +41,11 @@ import com.intellij.facet.ModifiableFacetModel; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; @@ -354,7 +355,7 @@ public void afterSync( writeActions.stream().forEach(Function0::invoke); }); } - }, ProgressIndicatorStub.INSTANCE); + }, new EmptyProgressIndicator(ModalityState.NON_MODAL)); } } }