From 1cb2dc83330e3f34678c50a6189b70cd87986652 Mon Sep 17 00:00:00 2001 From: Marek Moryl Date: Wed, 31 Aug 2022 22:41:59 +0200 Subject: [PATCH] Add platform option --- .../scala/cli/commands/SharedOptions.scala | 4 +++ .../main/scala/scala/cli/commands/Bsp.scala | 5 +-- .../scala/scala/cli/commands/Compile.scala | 6 ++-- .../scala/cli/commands/DependencyUpdate.scala | 2 +- .../main/scala/scala/cli/commands/Doc.scala | 7 ++-- .../scala/scala/cli/commands/Export.scala | 2 +- .../main/scala/scala/cli/commands/Fmt.scala | 4 +-- .../scala/scala/cli/commands/Metabrowse.scala | 4 +-- .../scala/scala/cli/commands/Package.scala | 2 +- .../main/scala/scala/cli/commands/Repl.scala | 5 +-- .../main/scala/scala/cli/commands/Run.scala | 5 +-- .../scala/cli/commands/ScalaCommand.scala | 5 +-- .../scala/scala/cli/commands/SetupIde.scala | 2 +- .../main/scala/scala/cli/commands/Test.scala | 4 +-- .../scala/cli/commands/bloop/Bloop.scala | 2 +- .../scala/cli/commands/publish/Publish.scala | 6 ++-- .../cli/commands/publish/PublishLocal.scala | 4 +-- .../cli/commands/util/FmtOptionsUtil.scala | 2 +- .../commands/util/PackageOptionsUtil.scala | 6 ++-- .../cli/commands/util/SharedOptionsUtil.scala | 35 +++++++++++++------ .../build/errors/AmbiguousPlatformError.scala | 5 +++ .../cli/integration/RunTestDefinitions.scala | 18 ++++++++++ website/docs/commands/run.md | 21 +++++++++++ website/docs/reference/cli-options.md | 4 +++ .../reference/scala-command/cli-options.md | 4 +++ 25 files changed, 119 insertions(+), 45 deletions(-) create mode 100644 modules/core/src/main/scala/scala/build/errors/AmbiguousPlatformError.scala diff --git a/modules/cli-options/src/main/scala/scala/cli/commands/SharedOptions.scala b/modules/cli-options/src/main/scala/scala/cli/commands/SharedOptions.scala index bba1ef8beb..68c4851db6 100644 --- a/modules/cli-options/src/main/scala/scala/cli/commands/SharedOptions.scala +++ b/modules/cli-options/src/main/scala/scala/cli/commands/SharedOptions.scala @@ -84,6 +84,10 @@ final case class SharedOptions( @Name("resourceDir") resourceDirs: List[String] = Nil, + @HelpMessage("Specify platform") + @ValueDescription("scala-js|scala-native|jvm") + platform: Option[String] = None, + @Group("Scala") @Hidden scalaLibrary: Option[Boolean] = None, diff --git a/modules/cli/src/main/scala/scala/cli/commands/Bsp.scala b/modules/cli/src/main/scala/scala/cli/commands/Bsp.scala index a7d94dd130..f50be6ab24 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Bsp.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Bsp.scala @@ -61,7 +61,7 @@ object Bsp extends ScalaCommand[BspOptions] { val sharedOptions = getSharedOptions() BspReloadableOptions( buildOptions = buildOptions(sharedOptions), - bloopRifleConfig = sharedOptions.bloopRifleConfig(), + bloopRifleConfig = sharedOptions.bloopRifleConfig().orExit(sharedOptions.logger), logger = sharedOptions.logging.logger, verbosity = sharedOptions.logging.verbosity ) @@ -96,7 +96,8 @@ object Bsp extends ScalaCommand[BspOptions] { } private def buildOptions(sharedOptions: SharedOptions): BuildOptions = { - val baseOptions = sharedOptions.buildOptions() + val logger = sharedOptions.logger + val baseOptions = sharedOptions.buildOptions().orExit(logger) baseOptions.copy( classPathOptions = baseOptions.classPathOptions.copy( fetchSources = baseOptions.classPathOptions.fetchSources.orElse(Some(true)) diff --git a/modules/cli/src/main/scala/scala/cli/commands/Compile.scala b/modules/cli/src/main/scala/scala/cli/commands/Compile.scala index d063e5aed2..d49898c7b6 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Compile.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Compile.scala @@ -20,8 +20,8 @@ object Compile extends ScalaCommand[CompileOptions] { def run(options: CompileOptions, args: RemainingArgs): Unit = { maybePrintGroupHelp(options) - maybePrintSimpleScalacOutput(options, options.shared.buildOptions()) val logger = options.shared.logger + maybePrintSimpleScalacOutput(options, options.shared.buildOptions().orExit(logger)) CurrentParams.verbosity = options.shared.logging.verbosity val inputs = options.shared.inputs(args.all).orExit(logger) CurrentParams.workspaceOpt = Some(inputs.workspace) @@ -76,10 +76,10 @@ object Compile extends ScalaCommand[CompileOptions] { } } - val buildOptions = options.shared.buildOptions() + val buildOptions = options.shared.buildOptions().orExit(logger) val threads = BuildThreads.create() - val compilerMaker = options.shared.compilerMaker(threads) + val compilerMaker = options.shared.compilerMaker(threads).orExit(logger) val configDb = ConfigDb.open(options.shared.directories.directories) .orExit(logger) val actionableDiagnostics = diff --git a/modules/cli/src/main/scala/scala/cli/commands/DependencyUpdate.scala b/modules/cli/src/main/scala/scala/cli/commands/DependencyUpdate.scala index 8a990c210f..abc8d09e96 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/DependencyUpdate.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/DependencyUpdate.scala @@ -21,7 +21,7 @@ object DependencyUpdate extends ScalaCommand[DependencyUpdateOptions] { val logger = options.shared.logger val inputs = options.shared.inputs(args.all).orExit(logger) - val buildOptions = options.shared.buildOptions() + val buildOptions = options.shared.buildOptions().orExit(logger) val (crossSources, _) = CrossSources.forInputs( diff --git a/modules/cli/src/main/scala/scala/cli/commands/Doc.scala b/modules/cli/src/main/scala/scala/cli/commands/Doc.scala index 83eab63131..7ffa74662a 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Doc.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Doc.scala @@ -27,10 +27,11 @@ object Doc extends ScalaCommand[DocOptions] { val inputs = options.shared.inputs(args.remaining).orExit(logger) CurrentParams.workspaceOpt = Some(inputs.workspace) - val initialBuildOptions = options.shared.buildOptions(enableJmh = false, jmhVersion = None) - val threads = BuildThreads.create() + val initialBuildOptions = + options.shared.buildOptions(enableJmh = false, jmhVersion = None).orExit(logger) + val threads = BuildThreads.create() - val maker = options.shared.compilerMaker(threads) + val maker = options.shared.compilerMaker(threads).orExit(logger) val compilerMaker = ScalaCompilerMaker.IgnoreScala2(maker) val docCompilerMakerOpt = Some(SimpleScalaCompilerMaker("java", Nil, scaladoc = true)) diff --git a/modules/cli/src/main/scala/scala/cli/commands/Export.scala b/modules/cli/src/main/scala/scala/cli/commands/Export.scala index 9d68207790..7c84f6249e 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Export.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Export.scala @@ -102,7 +102,7 @@ object Export extends ScalaCommand[ExportOptions] { val inputs = options.shared.inputs(args.all).orExit(logger) CurrentParams.workspaceOpt = Some(inputs.workspace) val baseOptions = - options.shared.buildOptions() + options.shared.buildOptions().orExit(logger) .copy(mainClass = options.mainClass.mainClass.filter(_.nonEmpty)) val (sourcesMain, optionsMain0) = diff --git a/modules/cli/src/main/scala/scala/cli/commands/Fmt.scala b/modules/cli/src/main/scala/scala/cli/commands/Fmt.scala index 6b25d1d410..4ca4eab9c0 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Fmt.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Fmt.scala @@ -39,8 +39,8 @@ object Fmt extends ScalaCommand[FmtOptions] { } CurrentParams.workspaceOpt = Some(workspace) val (versionMaybe, dialectMaybe, pathMaybe) = readVersionAndDialect(workspace, options, logger) - val cache = options.shared.buildOptions().archiveCache - val buildOptions = options.buildOptions + val cache = options.shared.buildOptions().orExit(logger).archiveCache + val buildOptions = options.buildOptions if (sourceFiles.isEmpty) logger.debug("No source files, not formatting anything") diff --git a/modules/cli/src/main/scala/scala/cli/commands/Metabrowse.scala b/modules/cli/src/main/scala/scala/cli/commands/Metabrowse.scala index 4e3f02f529..8a25a386a0 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Metabrowse.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Metabrowse.scala @@ -46,7 +46,7 @@ object Metabrowse extends ScalaCommand[MetabrowseOptions] { val inputs = options.shared.inputs(args.all).orExit(logger) CurrentParams.workspaceOpt = Some(inputs.workspace) - val baseOptions = options.shared.buildOptions() + val baseOptions = options.shared.buildOptions().orExit(logger) val initialBuildOptions = baseOptions.copy( classPathOptions = baseOptions.classPathOptions.copy( fetchSources = Some(true) @@ -57,7 +57,7 @@ object Metabrowse extends ScalaCommand[MetabrowseOptions] { ) val threads = BuildThreads.create() - val compilerMaker = options.shared.compilerMaker(threads) + val compilerMaker = options.shared.compilerMaker(threads).orExit(logger) val configDb = ConfigDb.open(options.shared.directories.directories) .orExit(logger) val actionableDiagnostics = diff --git a/modules/cli/src/main/scala/scala/cli/commands/Package.scala b/modules/cli/src/main/scala/scala/cli/commands/Package.scala index 93e5ffb975..4892f332b6 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Package.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Package.scala @@ -58,7 +58,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers { val initialBuildOptions = buildOptions(options) val threads = BuildThreads.create() - val compilerMaker = options.compilerMaker(threads) + val compilerMaker = options.compilerMaker(threads).orExit(logger) val docCompilerMakerOpt = options.docCompilerMakerOpt val cross = options.compileCross.cross.getOrElse(false) diff --git a/modules/cli/src/main/scala/scala/cli/commands/Repl.scala b/modules/cli/src/main/scala/scala/cli/commands/Repl.scala index 72c9db60c6..b015223002 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Repl.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Repl.scala @@ -29,6 +29,7 @@ object Repl extends ScalaCommand[ReplOptions] { import ops.sharedRepl._ val ammoniteVersionOpt = ammoniteVersion.map(_.trim).filter(_.nonEmpty) + val logger = ops.shared.logger val baseOptions = shared.copy(scalaVersion = if ( ammonite.contains(true) && @@ -41,7 +42,7 @@ object Repl extends ScalaCommand[ReplOptions] { Some("3.1.3") } else shared.scalaVersion - ).buildOptions() + ).buildOptions().orExit(logger) baseOptions.copy( javaOptions = baseOptions.javaOptions.copy( javaOpts = @@ -77,7 +78,7 @@ object Repl extends ScalaCommand[ReplOptions] { val threads = BuildThreads.create() - val compilerMaker = options.shared.compilerMaker(threads) + val compilerMaker = options.shared.compilerMaker(threads).orExit(logger) val directories = options.shared.directories.directories diff --git a/modules/cli/src/main/scala/scala/cli/commands/Run.scala b/modules/cli/src/main/scala/scala/cli/commands/Run.scala index c4f3793112..42f9929dd0 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Run.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Run.scala @@ -57,10 +57,11 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers { def buildOptions(options: RunOptions): BuildOptions = { import options.* import options.sharedRun.* + val logger = options.shared.logger val baseOptions = shared.buildOptions( enableJmh = benchmarking.jmh.contains(true), jmhVersion = benchmarking.jmhVersion - ) + ).orExit(logger) baseOptions.copy( mainClass = mainClass.mainClass, javaOptions = baseOptions.javaOptions.copy( @@ -115,7 +116,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers { CurrentParams.workspaceOpt = Some(inputs.workspace) val threads = BuildThreads.create() - val compilerMaker = options.shared.compilerMaker(threads) + val compilerMaker = options.shared.compilerMaker(threads).orExit(logger) def maybeRun( build: Build.Successful, diff --git a/modules/cli/src/main/scala/scala/cli/commands/ScalaCommand.scala b/modules/cli/src/main/scala/scala/cli/commands/ScalaCommand.scala index 4f4f1822bb..b71848f472 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/ScalaCommand.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/ScalaCommand.scala @@ -87,8 +87,9 @@ abstract class ScalaCommand[T](implicit myParser: Parser[T], help: Help[T]) val candidates = arg.name.name match { case "dependency" => state.flatMap(sharedOptions).toList.flatMap { sharedOptions => - val cache = sharedOptions.coursierCache - val sv = sharedOptions.buildOptions() + val logger = sharedOptions.logger + val cache = sharedOptions.coursierCache + val sv = sharedOptions.buildOptions().orExit(logger) .scalaParams .toOption .flatten diff --git a/modules/cli/src/main/scala/scala/cli/commands/SetupIde.scala b/modules/cli/src/main/scala/scala/cli/commands/SetupIde.scala index d093f1dc46..e6b4333c30 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/SetupIde.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/SetupIde.scala @@ -87,7 +87,7 @@ object SetupIde extends ScalaCommand[SetupIdeOptions] { } private def buildOptions(opts: SetupIdeOptions): BuildOptions = - opts.shared.buildOptions() + opts.shared.buildOptions().orExit(opts.shared.logger) private def writeBspConfiguration( options: SetupIdeOptions, diff --git a/modules/cli/src/main/scala/scala/cli/commands/Test.scala b/modules/cli/src/main/scala/scala/cli/commands/Test.scala index 4aa1666f4f..843843f6c8 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Test.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Test.scala @@ -25,7 +25,7 @@ object Test extends ScalaCommand[TestOptions] { def buildOptions(opts: TestOptions): BuildOptions = { import opts._ - val baseOptions = shared.buildOptions() + val baseOptions = shared.buildOptions().orExit(opts.shared.logger) baseOptions.copy( javaOptions = baseOptions.javaOptions.copy( javaOpts = @@ -63,7 +63,7 @@ object Test extends ScalaCommand[TestOptions] { val threads = BuildThreads.create() - val compilerMaker = options.shared.compilerMaker(threads) + val compilerMaker = options.shared.compilerMaker(threads).orExit(logger) val cross = options.compileCross.cross.getOrElse(false) val configDb = ConfigDb.open(options.shared.directories.directories) diff --git a/modules/cli/src/main/scala/scala/cli/commands/bloop/Bloop.scala b/modules/cli/src/main/scala/scala/cli/commands/bloop/Bloop.scala index be16e17dbb..042a2ed4f2 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/bloop/Bloop.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/bloop/Bloop.scala @@ -34,7 +34,7 @@ object Bloop extends ScalaCommand[BloopOptions] { jvm = opts.jvm, coursier = opts.coursier ) - val options = sharedOptions.buildOptions(false, None) + val options = sharedOptions.buildOptions(false, None).orExit(opts.logging.logger) lazy val defaultJvmCmd = sharedOptions.downloadJvm(OsLibc.baseDefaultJvm(OsLibc.jvmIndexOs, "17"), options) val javaCmd = opts.compilationServer.bloopJvm diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala index 1347e62afa..b293e3edf8 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala @@ -72,7 +72,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers { mainClass: MainClassOptions, ivy2LocalLike: Option[Boolean] ): Either[BuildException, BuildOptions] = either { - val baseOptions = shared.buildOptions() + val baseOptions = shared.buildOptions().orExit(shared.logger) val contextualOptions = PublishContextualOptions( repository = publishRepo.publishRepository.filter(_.trim.nonEmpty), repositoryIsIvy2LocalLike = ivy2LocalLike, @@ -189,8 +189,8 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers { ).orExit(logger) val threads = BuildThreads.create() - val compilerMaker = options.shared.compilerMaker(threads) - val docCompilerMaker = options.shared.compilerMaker(threads, scaladoc = true) + val compilerMaker = options.shared.compilerMaker(threads).orExit(logger) + val docCompilerMaker = options.shared.compilerMaker(threads, scaladoc = true).orExit(logger) val cross = options.compileCross.cross.getOrElse(false) diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishLocal.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishLocal.scala index 95d9084e99..f4eae0115e 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishLocal.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishLocal.scala @@ -40,8 +40,8 @@ object PublishLocal extends ScalaCommand[PublishLocalOptions] { ).orExit(logger) val threads = BuildThreads.create() - val compilerMaker = options.shared.compilerMaker(threads) - val docCompilerMaker = options.shared.compilerMaker(threads, scaladoc = true) + val compilerMaker = options.shared.compilerMaker(threads).orExit(logger) + val docCompilerMaker = options.shared.compilerMaker(threads, scaladoc = true).orExit(logger) val cross = options.compileCross.cross.getOrElse(false) diff --git a/modules/cli/src/main/scala/scala/cli/commands/util/FmtOptionsUtil.scala b/modules/cli/src/main/scala/scala/cli/commands/util/FmtOptionsUtil.scala index dabab3cd5f..0ca68954df 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/util/FmtOptionsUtil.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/util/FmtOptionsUtil.scala @@ -26,7 +26,7 @@ object FmtOptionsUtil { (url, !tag0.startsWith("v")) } - def buildOptions: BuildOptions = shared.buildOptions() + def buildOptions: BuildOptions = shared.buildOptions().orExit(v.shared.logger) def scalafmtCliOptions: List[String] = scalafmtArg ::: diff --git a/modules/cli/src/main/scala/scala/cli/commands/util/PackageOptionsUtil.scala b/modules/cli/src/main/scala/scala/cli/commands/util/PackageOptionsUtil.scala index 4c6dd5b2de..46415df4ed 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/util/PackageOptionsUtil.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/util/PackageOptionsUtil.scala @@ -48,7 +48,7 @@ object PackageOptionsUtil { .left.map(CompositeBuildException(_)) def baseBuildOptions: BuildOptions = { - val baseOptions = shared.buildOptions() + val baseOptions = shared.buildOptions().orExit(v.shared.logger) baseOptions.copy( mainClass = mainClass.mainClass.filter(_.nonEmpty), notForBloopOptions = baseOptions.notForBloopOptions.copy( @@ -120,8 +120,8 @@ object PackageOptionsUtil { ) } - def compilerMaker(threads: BuildThreads): ScalaCompilerMaker = { - val maker = shared.compilerMaker(threads) + def compilerMaker(threads: BuildThreads): Either[BuildException, ScalaCompilerMaker] = either { + val maker = value(shared.compilerMaker(threads)) if (forcedPackageTypeOpt.contains(PackageType.DocJar)) ScalaCompilerMaker.IgnoreScala2(maker) else diff --git a/modules/cli/src/main/scala/scala/cli/commands/util/SharedOptionsUtil.scala b/modules/cli/src/main/scala/scala/cli/commands/util/SharedOptionsUtil.scala index 38321dd188..6a555a1f24 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/util/SharedOptionsUtil.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/util/SharedOptionsUtil.scala @@ -9,10 +9,11 @@ import dependency.parser.DependencyParser import java.io.{File, InputStream} +import scala.build.EitherCps.{either, value} import scala.build.* import scala.build.blooprifle.BloopRifleConfig import scala.build.compiler.{BloopCompilerMaker, ScalaCompilerMaker, SimpleScalaCompilerMaker} -import scala.build.errors.BuildException +import scala.build.errors.{AmbiguousPlatformError, BuildException} import scala.build.interactive.Interactive import scala.build.interactive.Interactive.{InteractiveAsk, InteractiveNop} import scala.build.internal.CsLoggerUtil.* @@ -155,11 +156,20 @@ object SharedOptionsUtil extends CommandHelpers { enableJmh: Boolean = false, jmhVersion: Option[String] = None, ignoreErrors: Boolean = false - ): bo.BuildOptions = { - val platformOpt = - if (js.js) Some(Platform.JS) - else if (native.native) Some(Platform.Native) - else None + ): Either[BuildException, bo.BuildOptions] = either { + val parsedPlatform = platform.map(Platform.normalize).flatMap(Platform.parse) + val platformOpt = value { + (parsedPlatform, js.js, native.native) match { + case (Some(p: Platform.JS.type), true, false) => Right(Some(p)) + case (Some(p: Platform.Native.type), false, true) => Right(Some(p)) + case (Some(p), _, _) if native.native || js.js => Left(new AmbiguousPlatformError) + case (Some(p), _, _) => Right(Some(p)) + case (None, true, true) => Left(new AmbiguousPlatformError) + case (None, true, false) => Right(Some(Platform.JS)) + case (None, false, true) => Right(Some(Platform.Native)) + case (None, false, false) => Right(None) + } + } bo.BuildOptions( scalaOptions = bo.ScalaOptions( scalaVersion = scalaVersion @@ -292,9 +302,8 @@ object SharedOptionsUtil extends CommandHelpers { javaCmd } - def bloopRifleConfig(): BloopRifleConfig = { - - val options = buildOptions(false, None) + def bloopRifleConfig(): Either[BuildException, BloopRifleConfig] = either { + val options = value(buildOptions(false, None)) lazy val defaultJvmCmd = downloadJvm(OsLibc.baseDefaultJvm(OsLibc.jvmIndexOs, "17"), options) val javaCmd = compilationServer.bloopJvm.map(downloadJvm(_, options)).orElse { @@ -315,17 +324,21 @@ object SharedOptionsUtil extends CommandHelpers { ) } - def compilerMaker(threads: BuildThreads, scaladoc: Boolean = false): ScalaCompilerMaker = + def compilerMaker( + threads: BuildThreads, + scaladoc: Boolean = false + ): Either[BuildException, ScalaCompilerMaker] = either { if (scaladoc) SimpleScalaCompilerMaker("java", Nil, scaladoc = true) else if (compilationServer.server.getOrElse(true)) new BloopCompilerMaker( - bloopRifleConfig(), + value(bloopRifleConfig()), threads.bloop, strictBloopJsonCheckOrDefault ) else SimpleScalaCompilerMaker("java", Nil) + } def coursierCache = cached(v)(coursier.coursierCache(logging.logger.coursierLogger(""))) diff --git a/modules/core/src/main/scala/scala/build/errors/AmbiguousPlatformError.scala b/modules/core/src/main/scala/scala/build/errors/AmbiguousPlatformError.scala new file mode 100644 index 0000000000..2d458a1607 --- /dev/null +++ b/modules/core/src/main/scala/scala/build/errors/AmbiguousPlatformError.scala @@ -0,0 +1,5 @@ +package scala.build.errors + +final class AmbiguousPlatformError extends BuildException( + "Ambiguous platform: more than one type of platform has been passed." + ) diff --git a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala index 44073a3e62..4ae3d2387c 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala @@ -206,6 +206,24 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String]) } } + test("simple script JS via platform option") { + val message = "Hello" + val inputs = TestInputs( + os.rel / "simple.sc" -> + s"""//> using platform "scala-native" + |import scala.scalajs.js + |val console = js.Dynamic.global.console + |val msg = "$message" + |console.log(msg) + |""".stripMargin + ) + inputs.fromRoot { root => + val output = + os.proc(TestUtil.cli, extraOptions, ".", "--platform", "js").call(cwd = root).out.trim() + expect(output == message) + } + } + def platformNl: String = if (Properties.isWin) "\\r\\n" else "\\n" def simpleNativeTests(): Unit = { diff --git a/website/docs/commands/run.md b/website/docs/commands/run.md index 21b33fc6c3..57d79e072e 100644 --- a/website/docs/commands/run.md +++ b/website/docs/commands/run.md @@ -135,6 +135,12 @@ Note that this requires `node` to be [installed](/install#scala-js) on your syst scala-cli Hello.scala --js ``` +It is also possible to achieve it using `--platform` option: + +```bash +scala-cli Hello.scala --platform js +``` + See our dedicated [Scala.js guide](../guides/scala-js.md) for more information. ## Scala Native @@ -146,8 +152,23 @@ Note that the [Scala Native requirements](https://scala-native.readthedocs.io/en scala-cli Hello.scala --native -S 2.13.6 ``` +It is also possible to achieve it using `--platform` option: + +```bash +scala-cli Hello.scala --platform native +``` + We have a dedicated [Scala Native guide](../guides/scala-native.md) as well. +## Platform + +The `--platform` option can be used to choose the platform, which should be used to compile and run application. Available platforms are: +* JVM (`jvm`) +* Scala.js (`scala.js` | `scala-js` | `scalajs` | `js`) +* Scala Native (`scala-native` | `scalanative` | `native`) + +Passing the `--platform` along with `--js` or `--native` is not recommended. If two different types of platform are passed, Scala CLI throws an error. + ## Scala Scripts Scala CLI can also compile and run Scala scripts: diff --git a/website/docs/reference/cli-options.md b/website/docs/reference/cli-options.md index a987493b16..f9d4688475 100644 --- a/website/docs/reference/cli-options.md +++ b/website/docs/reference/cli-options.md @@ -1260,6 +1260,10 @@ Aliases: `--resource-dir` Add a resource directory +### `--platform` + +Specify platform + ### `--scala-library` [Internal] diff --git a/website/docs/reference/scala-command/cli-options.md b/website/docs/reference/scala-command/cli-options.md index 4799915c3b..f506bf2aa3 100644 --- a/website/docs/reference/scala-command/cli-options.md +++ b/website/docs/reference/scala-command/cli-options.md @@ -670,6 +670,10 @@ Aliases: `--resource-dir` Add a resource directory +### `--platform` + +Specify platform + ### `--scala-library` [Internal]