From 8770ad9de879eb90a50e67edc2cc62e9624643b7 Mon Sep 17 00:00:00 2001 From: Aleksandra Zdrojowa Date: Mon, 17 Nov 2025 10:18:56 +0100 Subject: [PATCH] trigger an additional reload only if it's a ConsoleChannel, an interactive NetworkChannel, or a NetworkChannel where the exec ID is known, to ensure the response can be propagated correctly #8371 --- main/src/main/scala/sbt/MainLoop.scala | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/main/src/main/scala/sbt/MainLoop.scala b/main/src/main/scala/sbt/MainLoop.scala index 7ccfa3a97..85ae7ce30 100644 --- a/main/src/main/scala/sbt/MainLoop.scala +++ b/main/src/main/scala/sbt/MainLoop.scala @@ -10,6 +10,7 @@ package sbt import sbt.BasicCommandStrings.{ StashOnFailure, networkExecPrefix } import sbt.ProjectExtra.extract +import sbt.internal.{ ConsoleChannel, FastTrackCommands, ShutdownHooks, SysProp, TaskProgress } import sbt.internal.langserver.ErrorCodes import sbt.internal.nio.CheckBuildSources.CheckBuildSourcesKey import sbt.internal.protocol.JsonRpcResponseError @@ -20,7 +21,6 @@ import sbt.internal.util.{ Prompt, Terminal as ITerminal } -import sbt.internal.{ FastTrackCommands, ShutdownHooks, SysProp, TaskProgress } import sbt.io.{ IO, Using } import sbt.protocol.* import sbt.util.{ Logger, LoggerContext } @@ -31,6 +31,7 @@ import java.util.concurrent.RejectedExecutionException import scala.annotation.tailrec import scala.concurrent.duration.* import scala.util.control.NonFatal +import sbt.internal.server.NetworkChannel import java.text.ParseException @@ -301,10 +302,22 @@ private[sbt] object MainLoop: .remove(Keys.terminalKey) .remove(Keys.currentCommandProgress) } + + val channel = channelName.flatMap(exchange.channelForName) + val (canReload, useLoadp) = channel match + case Some(nc: NetworkChannel) => + val isInteractive = nc.isInteractive + (isInteractive || exec.execId.nonEmpty, !isInteractive) + case Some(_: ConsoleChannel) => (true, false) + case _ => (false, false) + state.get(CheckBuildSourcesKey) match { - case Some(cbs) => - if (!cbs.needsReload(state, exec)) process() - else Exec("reload", None) +: exec +: state.remove(CheckBuildSourcesKey) + case Some(cbs) if canReload && cbs.needsReload(state, exec) => + val loadExec = + if (useLoadp) Exec("loadp", exec.execId, exec.source) + else Exec("reload", exec.source) + + loadExec +: exec +: state.remove(CheckBuildSourcesKey) case _ => process() } } catch {