Merge pull request #8459 from eed3si9n/wip/consoleproject

[2.x] Make some consoleProject progress
This commit is contained in:
eugene yokota 2026-01-10 14:08:57 -05:00 committed by GitHub
commit 4609b62d87
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 69 additions and 27 deletions

View File

@ -717,6 +717,7 @@ lazy val mainProj = (project in file("main"))
mimaSettings, mimaSettings,
mimaBinaryIssueFilters ++= Vector( mimaBinaryIssueFilters ++= Vector(
exclude[ReversedMissingMethodProblem]("sbt.ProjectMatrix.*"), exclude[ReversedMissingMethodProblem]("sbt.ProjectMatrix.*"),
exclude[DirectMissingMethodProblem]("sbt.internal.ConsoleProject.*"),
), ),
) )
.dependsOn(lmCore, lmIvy, lmCoursierShadedPublishing) .dependsOn(lmCore, lmIvy, lmCoursierShadedPublishing)

View File

@ -774,6 +774,27 @@ object Defaults extends BuildCommon {
javacOptions :== Nil, javacOptions :== Nil,
scalacOptions :== Nil, scalacOptions :== Nil,
scalaVersion := appConfiguration.value.provider.scalaProvider.version, scalaVersion := appConfiguration.value.provider.scalaProvider.version,
consoleProject := ConsoleProject.consoleProjectTask.value,
consoleProject / scalaInstance := {
val topLoader = classOf[org.jline.terminal.Terminal].getClassLoader
val scalaProvider = appConfiguration.value.provider.scalaProvider
val allJars = scalaProvider.jars
val libraryJars = allJars.filter { jar =>
jar.getName == "scala-library.jar" || jar.getName.startsWith("scala3-library_3")
}
val compilerJar = allJars.filter { jar =>
jar.getName == "scala-compiler.jar" || jar.getName.startsWith("scala3-compiler_3")
}
ScalaInstance(scalaProvider.version, scalaProvider.launcher)
Compiler.makeScalaInstance(
scalaProvider.version,
libraryJars,
allJars.toSeq,
Seq.empty,
state.value,
topLoader,
)
},
derive(crossScalaVersions := Seq(scalaVersion.value)), derive(crossScalaVersions := Seq(scalaVersion.value)),
derive(compilersSetting), derive(compilersSetting),
derive(scalaBinaryVersion := binaryScalaVersion(scalaVersion.value)), derive(scalaBinaryVersion := binaryScalaVersion(scalaVersion.value)),
@ -1067,7 +1088,6 @@ object Defaults extends BuildCommon {
cleanKeepGlobs ++= historyPath.value.map(_.toGlob).toVector, cleanKeepGlobs ++= historyPath.value.map(_.toGlob).toVector,
// clean := Def.taskDyn(Clean.task(resolvedScoped.value.scope, full = true)).value, // clean := Def.taskDyn(Clean.task(resolvedScoped.value.scope, full = true)).value,
clean := Clean.scopedTask.value, clean := Clean.scopedTask.value,
consoleProject := consoleProjectTask.value,
transitiveDynamicInputs := Def.uncached(WatchTransitiveDependencies.task.value), transitiveDynamicInputs := Def.uncached(WatchTransitiveDependencies.task.value),
) )
@ -2053,12 +2073,7 @@ object Defaults extends BuildCommon {
analysis.infos.allInfos.values.map(_.getMainClasses).flatten.toSeq.sorted analysis.infos.allInfos.values.map(_.getMainClasses).flatten.toSeq.sorted
} }
def consoleProjectTask = def consoleProjectTask = ConsoleProject.consoleProjectTask
Def.task {
ConsoleProject(state.value, (consoleProject / initialCommands).value)(using streams.value.log)
println()
}
def consoleTask: Initialize[Task[Unit]] = consoleTask(fullClasspath, console) def consoleTask: Initialize[Task[Unit]] = consoleTask(fullClasspath, console)
def consoleQuickTask = consoleTask(externalDependencyClasspath, consoleQuick) def consoleQuickTask = consoleTask(externalDependencyClasspath, consoleQuick)
def consoleTask(classpath: TaskKey[Classpath], task: TaskKey[?]): Initialize[Task[Unit]] = def consoleTask(classpath: TaskKey[Classpath], task: TaskKey[?]): Initialize[Task[Unit]] =

View File

@ -12,58 +12,84 @@ package internal
import sbt.ProjectExtra.extract import sbt.ProjectExtra.extract
import sbt.internal.classpath.AlternativeZincUtil import sbt.internal.classpath.AlternativeZincUtil
import sbt.internal.inc.{ ScalaInstance, ZincLmUtil } import sbt.internal.inc.{ ScalaInstance, ZincLmUtil }
import sbt.internal.inc.classpath.ClasspathUtil
import sbt.internal.util.Terminal import sbt.internal.util.Terminal
import sbt.io.IO
import sbt.librarymanagement.DependencyResolution
import sbt.util.Logger import sbt.util.Logger
import xsbti.HashedVirtualFileRef
import xsbti.compile.ClasspathOptionsUtil import xsbti.compile.ClasspathOptionsUtil
object ConsoleProject { object ConsoleProject:
def apply(state: State, extra: String, cleanupCommands: String = "", options: Seq[String] = Nil)( def consoleProjectTask =
using log: Logger Def.task {
val st = Keys.state.value
val si = (Keys.consoleProject / Keys.scalaInstance).value
val dr = (LocalRootProject / Keys.dependencyResolution).value
val compilerBridgeBinaryBin =
(LocalRootProject / Keys.consoleProject / Keys.scalaCompilerBridgeBin).value
ConsoleProject(
st,
si,
dr,
compilerBridgeBinaryBin,
(Keys.consoleProject / Keys.initialCommands).value
)(using
Keys.streams.value.log
)
println()
}
def apply(
state: State,
si: ScalaInstance,
dr: DependencyResolution,
compilerBridgeBinaryBin: Seq[HashedVirtualFileRef],
extra: String,
cleanupCommands: String = "",
options: Seq[String] = Nil
)(using
log: Logger
): Unit = { ): Unit = {
val extracted = Project.extract(state) val extracted = Project.extract(state)
val cpImports = new Imports(extracted, state) val cpImports = new Imports(extracted, state)
// Bindings are blocked by https://github.com/scala/scala3/issues/5069
val bindings = val bindings =
("currentState" -> state) :: ("extracted" -> extracted) :: ("cpHelpers" -> cpImports) :: Nil ("currentState" -> state) :: ("extracted" -> extracted) :: ("cpHelpers" -> cpImports) :: Nil
val unit = extracted.currentUnit val unit = extracted.currentUnit
val (state1, dependencyResolution) = val tempDir0 = extracted.get(Keys.consoleProject / Keys.taskTemporaryDirectory)
extracted.runTask(Keys.dependencyResolution, state) val tempDir = IO.createUniqueDirectory(tempDir0).toPath()
val (_, scalaCompilerBridgeBinaryBin) =
extracted.runTask(Keys.consoleProject / Keys.scalaCompilerBridgeBin, state1)
val conv = extracted.get(Keys.fileConverter) val conv = extracted.get(Keys.fileConverter)
val scalaInstance = {
val scalaProvider = state.configuration.provider.scalaProvider
ScalaInstance(scalaProvider.version, scalaProvider)
}
val g = BuildPaths.getGlobalBase(state) val g = BuildPaths.getGlobalBase(state)
val zincDir = BuildPaths.getZincDirectory(state, g) val zincDir = BuildPaths.getZincDirectory(state, g)
val app = state.configuration val app = state.configuration
val launcher = app.provider.scalaProvider.launcher val launcher = app.provider.scalaProvider.launcher
val compiler = scalaCompilerBridgeBinaryBin.toList match val compiler = compilerBridgeBinaryBin.toList match
case jar :: xs => case jar :: xs =>
AlternativeZincUtil.scalaCompiler( AlternativeZincUtil.scalaCompiler(
scalaInstance = scalaInstance, scalaInstance = si,
classpathOptions = ClasspathOptionsUtil.repl, classpathOptions = ClasspathOptionsUtil.repl,
compilerBridgeJar = conv.toPath(jar).toFile(), compilerBridgeJar = conv.toPath(jar).toFile(),
classLoaderCache = state1.get(BasicKeys.classLoaderCache) classLoaderCache = state.get(BasicKeys.classLoaderCache)
) )
case Nil => case Nil =>
ZincLmUtil.scalaCompiler( ZincLmUtil.scalaCompiler(
scalaInstance = scalaInstance, scalaInstance = si,
classpathOptions = ClasspathOptionsUtil.repl, classpathOptions = ClasspathOptionsUtil.repl,
globalLock = launcher.globalLock, globalLock = launcher.globalLock,
componentProvider = app.provider.components, componentProvider = app.provider.components,
secondaryCacheDir = Option(zincDir), secondaryCacheDir = Option(zincDir),
dependencyResolution = dependencyResolution, dependencyResolution = dr,
compilerBridgeSource = compilerBridgeSource =
extracted.get(Keys.consoleProject / Keys.scalaCompilerBridgeSource), extracted.get(Keys.consoleProject / Keys.scalaCompilerBridgeSource),
scalaJarsTarget = zincDir, scalaJarsTarget = zincDir,
classLoaderCache = state1.get(BasicKeys.classLoaderCache), classLoaderCache = state.get(BasicKeys.classLoaderCache),
log = log log = log
) )
val imports = BuildUtil.getImports(unit.unit) ++ BuildUtil.importAll(bindings.map(_._1)) val imports = BuildUtil.getImports(unit.unit) ++ BuildUtil.importAll(bindings.map(_._1))
val importString = imports.mkString("", ";\n", ";\n\n") val importString = imports.mkString("", ";\n", ";\n\n")
val initCommands = importString + extra val initCommands = importString + extra
val loader = ClasspathUtil.makeLoader(unit.classpath, si, tempDir)
val terminal = Terminal.get val terminal = Terminal.get
// TODO - Hook up dsl classpath correctly... // TODO - Hook up dsl classpath correctly...
(new Console(compiler))( (new Console(compiler))(
@ -72,7 +98,7 @@ object ConsoleProject {
initCommands, initCommands,
cleanupCommands, cleanupCommands,
terminal terminal
)(Some(unit.loader), bindings).get )(Some(loader), bindings).get
() ()
} }
@ -84,4 +110,4 @@ object ConsoleProject {
implicit def settingKeyEvaluate[T](s: SettingKey[T]): Evaluate[T] = new Evaluate(get(s)) implicit def settingKeyEvaluate[T](s: SettingKey[T]): Evaluate[T] = new Evaluate(get(s))
} }
final class Evaluate[T] private[sbt] (val eval: T) final class Evaluate[T] private[sbt] (val eval: T)
} end ConsoleProject