diff --git a/build.sbt b/build.sbt index 762b05261..10824cd8b 100644 --- a/build.sbt +++ b/build.sbt @@ -717,6 +717,7 @@ lazy val mainProj = (project in file("main")) mimaSettings, mimaBinaryIssueFilters ++= Vector( exclude[ReversedMissingMethodProblem]("sbt.ProjectMatrix.*"), + exclude[DirectMissingMethodProblem]("sbt.internal.ConsoleProject.*"), ), ) .dependsOn(lmCore, lmIvy, lmCoursierShadedPublishing) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 96747f085..5f90ebbe2 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -774,6 +774,27 @@ object Defaults extends BuildCommon { javacOptions :== Nil, scalacOptions :== Nil, 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(compilersSetting), derive(scalaBinaryVersion := binaryScalaVersion(scalaVersion.value)), @@ -1067,7 +1088,6 @@ object Defaults extends BuildCommon { cleanKeepGlobs ++= historyPath.value.map(_.toGlob).toVector, // clean := Def.taskDyn(Clean.task(resolvedScoped.value.scope, full = true)).value, clean := Clean.scopedTask.value, - consoleProject := consoleProjectTask.value, transitiveDynamicInputs := Def.uncached(WatchTransitiveDependencies.task.value), ) @@ -2053,12 +2073,7 @@ object Defaults extends BuildCommon { analysis.infos.allInfos.values.map(_.getMainClasses).flatten.toSeq.sorted } - def consoleProjectTask = - Def.task { - ConsoleProject(state.value, (consoleProject / initialCommands).value)(using streams.value.log) - println() - } - + def consoleProjectTask = ConsoleProject.consoleProjectTask def consoleTask: Initialize[Task[Unit]] = consoleTask(fullClasspath, console) def consoleQuickTask = consoleTask(externalDependencyClasspath, consoleQuick) def consoleTask(classpath: TaskKey[Classpath], task: TaskKey[?]): Initialize[Task[Unit]] = diff --git a/main/src/main/scala/sbt/internal/ConsoleProject.scala b/main/src/main/scala/sbt/internal/ConsoleProject.scala index ee0c333c0..35fd97906 100644 --- a/main/src/main/scala/sbt/internal/ConsoleProject.scala +++ b/main/src/main/scala/sbt/internal/ConsoleProject.scala @@ -12,58 +12,84 @@ package internal import sbt.ProjectExtra.extract import sbt.internal.classpath.AlternativeZincUtil import sbt.internal.inc.{ ScalaInstance, ZincLmUtil } +import sbt.internal.inc.classpath.ClasspathUtil import sbt.internal.util.Terminal +import sbt.io.IO +import sbt.librarymanagement.DependencyResolution import sbt.util.Logger +import xsbti.HashedVirtualFileRef import xsbti.compile.ClasspathOptionsUtil -object ConsoleProject { - def apply(state: State, extra: String, cleanupCommands: String = "", options: Seq[String] = Nil)( - using log: Logger +object ConsoleProject: + def consoleProjectTask = + 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 = { val extracted = Project.extract(state) val cpImports = new Imports(extracted, state) + // Bindings are blocked by https://github.com/scala/scala3/issues/5069 val bindings = ("currentState" -> state) :: ("extracted" -> extracted) :: ("cpHelpers" -> cpImports) :: Nil val unit = extracted.currentUnit - val (state1, dependencyResolution) = - extracted.runTask(Keys.dependencyResolution, state) - val (_, scalaCompilerBridgeBinaryBin) = - extracted.runTask(Keys.consoleProject / Keys.scalaCompilerBridgeBin, state1) + val tempDir0 = extracted.get(Keys.consoleProject / Keys.taskTemporaryDirectory) + val tempDir = IO.createUniqueDirectory(tempDir0).toPath() val conv = extracted.get(Keys.fileConverter) - val scalaInstance = { - val scalaProvider = state.configuration.provider.scalaProvider - ScalaInstance(scalaProvider.version, scalaProvider) - } val g = BuildPaths.getGlobalBase(state) val zincDir = BuildPaths.getZincDirectory(state, g) val app = state.configuration val launcher = app.provider.scalaProvider.launcher - val compiler = scalaCompilerBridgeBinaryBin.toList match + val compiler = compilerBridgeBinaryBin.toList match case jar :: xs => AlternativeZincUtil.scalaCompiler( - scalaInstance = scalaInstance, + scalaInstance = si, classpathOptions = ClasspathOptionsUtil.repl, compilerBridgeJar = conv.toPath(jar).toFile(), - classLoaderCache = state1.get(BasicKeys.classLoaderCache) + classLoaderCache = state.get(BasicKeys.classLoaderCache) ) case Nil => ZincLmUtil.scalaCompiler( - scalaInstance = scalaInstance, + scalaInstance = si, classpathOptions = ClasspathOptionsUtil.repl, globalLock = launcher.globalLock, componentProvider = app.provider.components, secondaryCacheDir = Option(zincDir), - dependencyResolution = dependencyResolution, + dependencyResolution = dr, compilerBridgeSource = extracted.get(Keys.consoleProject / Keys.scalaCompilerBridgeSource), scalaJarsTarget = zincDir, - classLoaderCache = state1.get(BasicKeys.classLoaderCache), + classLoaderCache = state.get(BasicKeys.classLoaderCache), log = log ) val imports = BuildUtil.getImports(unit.unit) ++ BuildUtil.importAll(bindings.map(_._1)) val importString = imports.mkString("", ";\n", ";\n\n") val initCommands = importString + extra - + val loader = ClasspathUtil.makeLoader(unit.classpath, si, tempDir) val terminal = Terminal.get // TODO - Hook up dsl classpath correctly... (new Console(compiler))( @@ -72,7 +98,7 @@ object ConsoleProject { initCommands, cleanupCommands, 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)) } final class Evaluate[T] private[sbt] (val eval: T) -} +end ConsoleProject