Skip to content

Commit

Permalink
Take into account interactively picked options when caching binaries
Browse files Browse the repository at this point in the history
  • Loading branch information
alexarchambault committed Dec 16, 2022
1 parent 26bd940 commit 647a920
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 53 deletions.
14 changes: 9 additions & 5 deletions modules/build/src/main/scala/scala/build/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import scala.build.compiler.{ScalaCompiler, ScalaCompilerMaker}
import scala.build.errors.*
import scala.build.input.VirtualScript.VirtualScriptNameRegex
import scala.build.input.*
import scala.build.interactive.Interactive
import scala.build.internal.resource.ResourceMapper
import scala.build.internal.{Constants, CustomCodeWrapper, MainClass, Util}
import scala.build.options.ScalaVersionUtil.asVersion
Expand Down Expand Up @@ -65,21 +66,24 @@ object Build {
mainClasses: Seq[String],
commandString: String,
logger: Logger
): Either[BuildException, String] = {
): Either[BuildException, Interactive.Value] = {
val defaultMainClassOpt = sources.defaultMainClass
.filter(name => mainClasses.contains(name))
def foundMainClass: Either[BuildException, String] =
def foundMainClass: Either[BuildException, Interactive.Value] =
mainClasses match {
case Seq() => Left(new NoMainClassFoundError)
case Seq(mainClass) => Right(mainClass)
case Seq(mainClass) => Right(Interactive.Value(mainClass, Nil))
case _ =>
inferredMainClass(mainClasses, logger)
.map(Interactive.Value(_, Nil))
.left.flatMap { mainClasses =>
options.interactive.flatMap { interactive =>
interactive
.chooseOne(
"Found several main classes. Which would you like to run?",
mainClasses.toList
mainClasses
.map(cls => Interactive.Value(cls, Seq("--main-class", cls)))
.toList
)
.toRight {
SeveralMainClassesFoundError(
Expand All @@ -93,7 +97,7 @@ object Build {
}

defaultMainClassOpt match {
case Some(cls) => Right(cls)
case Some(cls) => Right(Interactive.Value(cls, Nil))
case None => foundMainClass
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import java.nio.charset.Charset
import java.util

import scala.build.Logger
import scala.build.interactive.Interactive
import scala.cli.CurrentParams
import scala.cli.commands.ScalaCommand
import scala.cli.internal.{Argv0, ProfileFileUpdater}
Expand All @@ -34,7 +35,11 @@ object InstallCompletions extends ScalaCommand[InstallCompletionsOptions] {
val name = getName(options.name)
val format = getFormat(options.format).getOrElse {
val msg = "Cannot determine current shell. Which would you like to use?"
interactive.chooseOne(msg, List("zsh", "bash")).getOrElse {
val options = List(
Interactive.Value("zsh", Seq("--shell", "zsh")),
Interactive.Value("bash", Seq("--shell", "bash"))
)
interactive.chooseOne(msg, options).map(_.value).getOrElse {
System.err.println(
"Cannot determine current shell, pass the shell you use with --shell, like"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import scala.build.EitherCps.{either, value}
import scala.build.Ops.*
import scala.build.*
import scala.build.errors.*
import scala.build.interactive.InteractiveFileOps
import scala.build.interactive.{Interactive, InteractiveFileOps}
import scala.build.internal.Util.*
import scala.build.internal.resource.NativeResourceMapper
import scala.build.internal.{Runner, ScalaJsLinkerConfig}
Expand Down Expand Up @@ -250,6 +250,12 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
case _ => "app"
}

lazy val mainClass: Either[BuildException, Interactive.Value] =
build.options.mainClass match {
case Some(cls) => Right(Interactive.Value(cls, Nil))
case None => build.retainedMainClass(logger)
}

val packageOutput = build.options.notForBloopOptions.packageOptions.output
val dest = outputOpt.orElse(packageOutput)
.orElse {
Expand All @@ -258,9 +264,11 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
.map(_.stripSuffix("_sc"))
.map(_ + extension)
}
.orElse(build.retainedMainClass(logger).map(
_.stripSuffix("_sc") + extension
).toOption)
.orElse {
mainClass
.toOption
.map(_.value.stripSuffix("_sc") + extension)
}
.orElse(build.sources.paths.collectFirst(_._1.baseName + extension))
.getOrElse(defaultName)
val destPath = os.Path(dest, Os.pwd)
Expand All @@ -286,12 +294,6 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {

value(alreadyExistsCheck())

def mainClass: Either[BuildException, String] =
build.options.mainClass match {
case Some(cls) => Right(cls)
case None => build.retainedMainClass(logger)
}

def mainClassOpt: Option[String] =
build.options.mainClass.orElse {
build.retainedMainClassOpt(build.foundMainClasses(), logger)
Expand All @@ -301,7 +303,15 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {

val outputPath = packageType match {
case PackageType.Bootstrap =>
value(bootstrap(build, destPath, value(mainClass), () => alreadyExistsCheck(), logger))
value {
bootstrap(
build,
destPath,
value(mainClass).value,
() => alreadyExistsCheck(),
logger
)
}
destPath
case PackageType.LibraryJar =>
val content = Library.libraryJar(build)
Expand Down Expand Up @@ -338,12 +348,12 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
case e => e
}
}
Some(clsName)
Some(clsName.value)
}
else
mainClassOpt
case Some(false) => None
case Some(true) => Some(value(mainClass))
case Some(true) => Some(value(mainClass).value)
},
Nil,
withPreamble = a.addPreamble,
Expand Down Expand Up @@ -371,7 +381,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
destPath

case PackageType.Js =>
value(buildJs(build, destPath, value(mainClass), logger))
value(buildJs(build, destPath, value(mainClass).value, logger))

case PackageType.Native =>
val cachedDest = value(buildNative(build, value(mainClass), logger))
Expand All @@ -396,7 +406,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
bootstrap(
build,
bootstrapPath,
value(mainClass),
value(mainClass).value,
() => alreadyExistsCheck(),
logger
)
Expand Down Expand Up @@ -595,7 +605,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {

private def docker(
build: Build.Successful,
mainClass: String,
mainClass: Interactive.Value,
logger: Logger
): Either[BuildException, Unit] = either {
val packageOptions = build.options.notForBloopOptions.packageOptions
Expand Down Expand Up @@ -636,8 +646,9 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {

val appPath = os.temp.dir(prefix = "scala-cli-docker") / "app"
build.options.platform.value match {
case Platform.JVM => value(bootstrap(build, appPath, mainClass, () => Right(()), logger))
case Platform.JS => buildJs(build, appPath, mainClass, logger)
case Platform.JVM =>
value(bootstrap(build, appPath, mainClass.value, () => Right(()), logger))
case Platform.JS => buildJs(build, appPath, mainClass.value, logger)
case Platform.Native =>
val dest = value(buildNative(build, mainClass, logger))
os.copy(dest, appPath)
Expand Down Expand Up @@ -961,7 +972,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {

def buildNative(
build: Build.Successful,
mainClass: String,
mainClass: Interactive.Value,
logger: Logger
): Either[BuildException, os.Path] = either {
val dest = build.inputs.nativeWorkDir / s"main${if (Properties.isWin) ".exe" else ""}"
Expand All @@ -982,7 +993,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
Nil
val pythonCliOptions = pythonLdFlags.flatMap(f => Seq("--linking-option", f)).toList

val allCliOptions = pythonCliOptions ++ cliOptions
val allCliOptions = pythonCliOptions ++ cliOptions ++ mainClass.options

val nativeWorkDir = build.inputs.nativeWorkDir
os.makeDir.all(nativeWorkDir)
Expand All @@ -1009,7 +1020,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
"--workdir",
nativeWorkDir.toString(),
"--main",
mainClass
mainClass.value
) ++ classpath

val scalaNativeCli = build.artifacts.scalaOpt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
case Left(err) =>
logger.debug(s"Error while looking for main class: $err")
None
case Right(cls) => Some(cls)
case Right(cls) => Some(cls.value)
}
}
val content = Library.libraryJar(build, mainClassOpt)
Expand Down
22 changes: 12 additions & 10 deletions modules/cli/src/main/scala/scala/cli/commands/run/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import scala.build.EitherCps.{either, value}
import scala.build.*
import scala.build.errors.BuildException
import scala.build.input.Inputs
import scala.build.interactive.Interactive
import scala.build.internal.{Constants, Runner, ScalaJsLinkerConfig}
import scala.build.options.{BuildOptions, JavaOpt, Platform, ScalacOpt}
import scala.cli.CurrentParams
Expand Down Expand Up @@ -316,13 +317,14 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
else None
}
val mainClass = mainClassOpt match {
case Some(cls) => cls
case Some(cls) => Interactive.Value(cls, Nil)
case None => value(build.retainedMainClass(logger, mainClasses = potentialMainClasses))
}
val verbosity = build.options.internal.verbosity.getOrElse(0).toString

val (finalMainClass, finalArgs) =
if (jvmRunner) (Constants.runnerMainClass, mainClass +: verbosity +: args)
if (jvmRunner)
(Interactive.Value(Constants.runnerMainClass, Nil), mainClass.value +: verbosity +: args)
else (mainClass, args)
val res = runOnce(
build,
Expand All @@ -339,7 +341,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {

private def runOnce(
build: Build.Successful,
mainClass: String,
mainClass: Interactive.Value,
args: Seq[String],
logger: Logger,
allowExecve: Boolean,
Expand Down Expand Up @@ -368,7 +370,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
Package.linkJs(
build,
jsDest,
Some(mainClass),
Some(mainClass.value),
addTestInitializer = false,
linkerConfig,
build.options.scalaJsOptions.fullOpt,
Expand Down Expand Up @@ -482,7 +484,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
build.options.javaHome().value.javaCommand,
allJavaOpts,
build.fullClassPath,
mainClass,
mainClass.value,
args,
useManifest = build.options.notForBloopOptions.runWithManifest,
scratchDirOpt = scratchDirOpt
Expand All @@ -494,7 +496,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
build.options.javaHome().value.javaCommand,
allJavaOpts,
build.fullClassPath,
mainClass,
mainClass.value,
args,
logger,
allowExecve = allowExecve,
Expand All @@ -507,7 +509,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
value {
RunSpark.run(
build,
mainClass,
mainClass.value,
args,
mode.submitArgs,
logger,
Expand All @@ -520,7 +522,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
value {
RunSpark.runStandalone(
build,
mainClass,
mainClass.value,
args,
mode.submitArgs,
logger,
Expand All @@ -533,7 +535,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
value {
RunHadoop.run(
build,
mainClass,
mainClass.value,
args,
logger,
allowExecve,
Expand Down Expand Up @@ -573,7 +575,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {

def withNativeLauncher[T](
build: Build.Successful,
mainClass: String,
mainClass: Interactive.Value,
logger: Logger
)(f: os.Path => T): Either[BuildException, T] =
Package.buildNative(build, mainClass, logger).map(f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,13 +377,18 @@ final case class SharedOptions(
case (Some(true), _, Some(true)) => InteractiveAsk
case (_, Some(true), _) => InteractiveAsk
case (Some(true), _, _) =>
val yesMessage = "Yes"
val options = List(
Interactive.Value(yesMessage, Seq("--interactive")),
Interactive.Value("No", Seq("--interactive=false"))
)
val answers @ List(yesAnswer, _) = List("Yes", "No")
InteractiveAsk.chooseOne(
s"""You have run the current ${ScalaCli.baseRunnerName} command with the --interactive mode turned on.
|Would you like to leave it on permanently?""".stripMargin,
answers
) match {
case Some(answer) if answer == yesAnswer =>
options
).map(_.value) match {
case Some(`yesMessage`) =>
val configDb0 = value(configDb)
value {
configDb0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import scala.build.EitherCps.{either, value}
import scala.build.Ops.*
import scala.build.*
import scala.build.errors.{BuildException, CompositeBuildException}
import scala.build.interactive.Interactive
import scala.build.internal.{Constants, Runner}
import scala.build.options.{BuildOptions, JavaOpt, Platform, Scope}
import scala.build.testrunner.AsmTestRunner
Expand Down Expand Up @@ -210,7 +211,7 @@ object Test extends ScalaCommand[TestOptions] {
value {
Run.withNativeLauncher(
build,
"scala.scalanative.testinterface.TestMain",
Interactive.Value("scala.scalanative.testinterface.TestMain", Nil),
logger
) { launcher =>
Runner.testNative(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package scala.cli.commands.util

import scala.build.errors.BuildException
import scala.build.interactive.Interactive
import scala.build.{Build, Logger, Os}
import scala.cli.commands.ScalaCommand
import scala.cli.commands.shared.SharedOptions
Expand All @@ -11,7 +12,7 @@ trait BuildCommandHelpers { self: ScalaCommand[_] =>
def retainedMainClass(
logger: Logger,
mainClasses: Seq[String] = successfulBuild.foundMainClasses()
): Either[BuildException, String] =
): Either[BuildException, Interactive.Value] =
successfulBuild.retainedMainClass(
mainClasses,
self.argvOpt.map(_.mkString(" ")).getOrElse(actualFullCommand),
Expand Down
Loading

0 comments on commit 647a920

Please sign in to comment.