Skip to content

Commit e05753b

Browse files
authored
Add support for jvm using directive (#1539)
1 parent 2135090 commit e05753b

File tree

12 files changed

+99
-11
lines changed

12 files changed

+99
-11
lines changed

modules/build/src/main/scala/scala/build/preprocessing/ScalaPreprocessor.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ case object ScalaPreprocessor extends Preprocessor {
4949
UsingJavacOptionsDirectiveHandler,
5050
UsingJavaOptionsDirectiveHandler,
5151
UsingJavaPropsDirectiveHandler,
52+
UsingJvmDirectiveHandler,
5253
UsingMainClassDirectiveHandler,
5354
UsingOptionDirectiveHandler,
5455
UsingPackagingDirectiveHandler,

modules/cli/src/main/scala/scala/cli/commands/Metabrowse.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.io.File
77

88
import scala.build.internal.{Constants, ExternalBinaryParams, FetchExternalBinary, Runner}
99
import scala.build.options.BuildOptions
10-
import scala.build.{Build, BuildThreads, Logger}
10+
import scala.build.{Build, BuildThreads, Logger, Positioned}
1111
import scala.cli.CurrentParams
1212
import scala.cli.commands.publish.ConfigUtil.*
1313
import scala.cli.commands.util.CommonOps.SharedDirectoriesOptionsOps
@@ -51,7 +51,7 @@ object Metabrowse extends ScalaCommand[MetabrowseOptions] {
5151
fetchSources = Some(true)
5252
),
5353
javaOptions = baseOptions.javaOptions.copy(
54-
jvmIdOpt = baseOptions.javaOptions.jvmIdOpt.orElse(Some("8"))
54+
jvmIdOpt = baseOptions.javaOptions.jvmIdOpt.orElse(Some(Positioned.none("8")))
5555
)
5656
)
5757
}

modules/cli/src/main/scala/scala/cli/commands/Run.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
7171
jvmIdOpt = baseOptions.javaOptions.jvmIdOpt.orElse {
7272
runMode(options) match {
7373
case _: RunMode.Spark | RunMode.HadoopJar =>
74-
Some("8")
74+
Some(Positioned.none("8"))
7575
case RunMode.Default => None
7676
}
7777
}

modules/cli/src/main/scala/scala/cli/commands/util/JvmUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ object JvmUtils {
4848
javaHomeOpt = javaHome.filter(_.nonEmpty).map(v =>
4949
Positioned(Seq(Position.CommandLine("--java-home")), os.Path(v, Os.pwd))
5050
),
51-
jvmIdOpt = jvm.filter(_.nonEmpty),
51+
jvmIdOpt = jvm.filter(_.nonEmpty).map(Positioned.commandLine),
5252
jvmIndexOpt = jvmIndex.filter(_.nonEmpty),
5353
jvmIndexOs = jvmIndexOs.map(_.trim).filter(_.nonEmpty),
5454
jvmIndexArch = jvmIndexArch.map(_.trim).filter(_.nonEmpty),

modules/cli/src/main/scala/scala/cli/launcher/LauncherCli.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ object LauncherCli {
5252

5353
val buildOptions = BuildOptions(
5454
javaOptions = JavaOptions(
55-
jvmIdOpt = Some(OsLibc.baseDefaultJvm(OsLibc.jvmIndexOs, "17"))
55+
jvmIdOpt = Some(OsLibc.baseDefaultJvm(OsLibc.jvmIndexOs, "17")).map(Positioned.none)
5656
)
5757
)
5858

modules/cli/src/main/scala/scala/cli/packaging/NativeImage.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import java.io.File
44

55
import scala.annotation.tailrec
66
import scala.build.internal.{ManifestJar, Runner}
7-
import scala.build.{Build, Logger}
7+
import scala.build.{Build, Logger, Positioned}
88
import scala.cli.errors.GraalVMNativeImageError
99
import scala.cli.graal.{BytecodeProcessor, TempCache}
1010
import scala.cli.internal.CachedBinary
@@ -171,7 +171,7 @@ object NativeImage {
171171
val jvmId = build.options.notForBloopOptions.packageOptions.nativeImageOptions.jvmId
172172
val options = build.options.copy(
173173
javaOptions = build.options.javaOptions.copy(
174-
jvmIdOpt = Some(jvmId)
174+
jvmIdOpt = Some(Positioned.none(jvmId))
175175
)
176176
)
177177

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package scala.build.preprocessing.directives
2+
3+
import scala.build.Logger
4+
import scala.build.errors.BuildException
5+
import scala.build.options.{BuildOptions, JavaOptions, MaybeScalaVersion, ScalaOptions}
6+
import scala.build.preprocessing.directives.UsingMainClassDirectiveHandler.checkIfValuesAreExpected
7+
8+
case object UsingJvmDirectiveHandler extends UsingDirectiveHandler {
9+
def name = "JVM version"
10+
11+
def description = "Use a specific JVM, such as `14`, `adopt:11`, or `graalvm:21`, or `system`"
12+
13+
def usage = "//> using jvm _value_"
14+
15+
override def usageMd = "`//> using jvm` _value_"
16+
17+
override def examples = Seq(
18+
"//> using jvm \"11\"",
19+
"//> using jvm \"adopt:11\"",
20+
"//> using jvm \"graalvm:21\""
21+
)
22+
23+
def keys = Seq("jvm")
24+
25+
override def isRestricted = false
26+
27+
def handleValues(
28+
scopedDirective: ScopedDirective,
29+
logger: Logger
30+
): Either[BuildException, ProcessedUsingDirective] =
31+
checkIfValuesAreExpected(scopedDirective).map { groupedValues =>
32+
val jvmIdOpts = groupedValues.scopedStringValues.map(_.positioned)
33+
val options = BuildOptions(
34+
javaOptions = JavaOptions(
35+
jvmIdOpt = jvmIdOpts.headOption
36+
)
37+
)
38+
ProcessedDirective(Some(options), Seq.empty)
39+
}
40+
41+
override def getValueNumberBounds(key: String) = UsingDirectiveValueNumberBounds(1, 1)
42+
43+
}

modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,10 +607,23 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
607607

608608
test("Runs with JVM 8") {
609609
val inputs =
610-
TestInputs(os.rel / "run.scala" -> """object Main extends App { println("hello")}""")
610+
TestInputs(
611+
os.rel / "run.scala" -> """object Main extends App { println(System.getProperty("java.version"))}"""
612+
)
611613
inputs.fromRoot { root =>
612614
val p = os.proc(TestUtil.cli, "run.scala", "--jvm", "8").call(cwd = root)
613-
expect(p.out.trim() == "hello")
615+
expect(p.out.trim().startsWith("1.8"))
616+
}
617+
}
618+
619+
test("Runs with JVM 8 with using directive") {
620+
val inputs =
621+
TestInputs(os.rel / "run.scala" ->
622+
"""//> using jvm "8"
623+
|object Main extends App { println(System.getProperty("java.version"))}""".stripMargin)
624+
inputs.fromRoot { root =>
625+
val p = os.proc(TestUtil.cli, "run.scala").call(cwd = root)
626+
expect(p.out.trim().startsWith("1.8"))
614627
}
615628
}
616629

modules/options/src/main/scala/scala/build/options/JavaOptions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import scala.util.control.NonFatal
1919
*/
2020
final case class JavaOptions(
2121
javaHomeOpt: Option[Positioned[os.Path]] = None,
22-
jvmIdOpt: Option[String] = None,
22+
jvmIdOpt: Option[Positioned[String]] = None,
2323
jvmIndexOpt: Option[String] = None,
2424
jvmIndexOs: Option[String] = None,
2525
jvmIndexArch: Option[String] = None,
@@ -74,7 +74,7 @@ final case class JavaOptions(
7474
else None
7575
}
7676
.orElse {
77-
jvmIdOpt.map { jvmId =>
77+
jvmIdOpt.map(_.value).map { jvmId =>
7878
implicit val ec: ExecutionContextExecutorService = cache.ec
7979
cache.logger.use {
8080
val enforceLiberica =

website/docs/commands/run.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ scala-cli Hello.scala hi.sc --main-class hi_sc
6060
scala-cli Hello.scala --jvm adopt:14
6161
```
6262

63+
You can also specify custom JVM with the using directive `//> using jvm`:
64+
```scala
65+
//> using jvm "adopt:14"
66+
```
67+
6368
JVMs are [managed by coursier](https://get-coursier.io/docs/cli-java#managed-jvms), and are read from the [coursier JVM index](https://github.com/coursier/jvm-index).
6469
(New JVM versions are automatically checked daily, and updates for those are - manually - merged
6570
swiftly.)

0 commit comments

Comments
 (0)