Skip to content

Commit

Permalink
Add support for passing java properties without --java-prop (#1739)
Browse files Browse the repository at this point in the history
  • Loading branch information
lwronski authored Jan 2, 2023
1 parent e368529 commit fb207c1
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package scala.cli.commands.shared

import caseapp.*
import caseapp.core.Scala3Helpers.*
import caseapp.core.parser.{Argument, NilParser, StandardArgument}
import caseapp.core.util.Formatter
import caseapp.core.{Arg, Error}
import com.github.plokhotnyuk.jsoniter_scala.core.*
import com.github.plokhotnyuk.jsoniter_scala.macros.*

import scala.cli.commands.tags

// format: off
final case class JavaPropOptions(
@Group("Java")
@HelpMessage("Set java properties")
@ValueDescription("key=value|key")
@Tag(tags.must)
javaProp: List[String] = Nil
)
// format: on

object JavaPropOptions {

private val javaPropOptionsArg = Arg("javaPropOption").copy(
extraNames = Seq(Name("java-prop")),
valueDescription = Some(ValueDescription("key=value|key")),
helpMessage = Some(HelpMessage(
"Add java properties. Note that options equal `-Dproperty=value` are assumed to be java properties and don't require to be passed after `--java-prop`."
)),
group = Some(Group("Java")),
origin = Some("JavaPropOptions")
)

private val javaPropOptionsArgument: Argument[List[String]] =
new Argument[List[String]] {

val underlying: StandardArgument[List[String]] = StandardArgument(javaPropOptionsArg)

val arg: Arg = javaPropOptionsArg

def withDefaultOrigin(origin: String): Argument[List[String]] = this
def init: Option[List[String]] = Some(Nil)
def step(
args: List[String],
index: Int,
acc: Option[List[String]],
formatter: Formatter[Name]
): Either[(Error, List[String]), Option[(Option[List[String]], List[String])]] =
args match {
case s"-D${prop}" :: t =>
Right(Some((Some(prop :: acc.getOrElse(Nil)), t)))
case _ => underlying.step(args, index, acc, formatter)
}
def get(acc: Option[List[String]], formatter: Formatter[Name]): Either[Error, List[String]] =
Right(acc.getOrElse(Nil))
}

implicit lazy val parser: Parser[JavaPropOptions] = {
val baseParser =
javaPropOptionsArgument ::
NilParser
baseParser.to[JavaPropOptions]
}
implicit lazy val help: Help[JavaPropOptions] = Help.derive
implicit lazy val jsonCodec: JsonValueCodec[JavaPropOptions] = JsonCodecMaker.make
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,12 @@ final case class SharedJavaOptions(
@Tag(tags.must)
@Name("J")
javaOpt: List[String] = Nil,
@Group("Java")
@HelpMessage("Set Java properties")
@ValueDescription("key=value|key")
@Tag(tags.must)
javaProp: List[String] = Nil
@Recurse
javaProperties: JavaPropOptions = JavaPropOptions(),
) {
// format: on
def allJavaOpts: Seq[String] =
javaOpt ++ javaProp.filter(_.nonEmpty).map(_.split("=", 2)).map {
javaOpt ++ javaProperties.javaProp.filter(_.nonEmpty).map(_.split("=", 2)).map {
case Array(k) => s"-D$k"
case Array(k, v) => s"-D$k=$v"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,21 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
}
}

test("java style -Dproperty=value system properties") {
val inputs = TestInputs(
os.rel / "Hello.scala" ->
"""object Hello extends App {
| print(System.getProperty("foo"))
|}""".stripMargin
)
inputs.fromRoot { root =>
val res = os.proc(TestUtil.cli, "Hello.scala", "-Dfoo=bar").call(
cwd = root
)
expect(res.out.trim() == "bar")
}
}

test("add to class path sources from using directive") {
val fileName = "Hello.scala"
val (hello, world) = ("Hello", "World")
Expand Down
6 changes: 6 additions & 0 deletions website/docs/commands/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ You can also add java options with the using directive `//> using javaOpt`:
//> using javaOpt "-Xmx1g", "-Dfoo=bar"
```

Additionally, java properties can be passed to `scala-cli` without `--java-prop`:

```bash
scala-cli Hello.scala -Dfoo=bar
```

### JAR

`scala-cli` lets you run JAR files just like any other input.
Expand Down
14 changes: 12 additions & 2 deletions website/docs/reference/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,19 @@ Aliases: `-J`

Set Java options, such as `-Xmx1g`

### `--java-prop`
## Java prop options

Set Java properties
Available in commands:

[`package`](./commands.md#package), [`repl` , `console`](./commands.md#repl), [`run`](./commands.md#run), [`shebang`](./commands.md#shebang), [`test`](./commands.md#test)

<!-- Automatically generated, DO NOT EDIT MANUALLY -->

### `--java-prop-option`

Aliases: `--java-prop`

Add java properties. Note that options equal `-Dproperty=value` are assumed to be java properties and don't require to be passed after `--java-prop`.

## Jvm options

Expand Down
10 changes: 5 additions & 5 deletions website/docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ Aliases: `console`

Fire-up a Scala REPL

Accepts option groups: [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [markdown](./cli-options.md#markdown-options), [python](./cli-options.md#python-options), [repl](./cli-options.md#repl-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)
Accepts option groups: [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [java prop](./cli-options.md#java-prop-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [markdown](./cli-options.md#markdown-options), [python](./cli-options.md#python-options), [repl](./cli-options.md#repl-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)

## package

Compile and package Scala code

Accepts option groups: [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [main class](./cli-options.md#main-class-options), [markdown](./cli-options.md#markdown-options), [package](./cli-options.md#package-options), [packager](./cli-options.md#packager-options), [python](./cli-options.md#python-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)
Accepts option groups: [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [java prop](./cli-options.md#java-prop-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [main class](./cli-options.md#main-class-options), [markdown](./cli-options.md#markdown-options), [package](./cli-options.md#package-options), [packager](./cli-options.md#packager-options), [python](./cli-options.md#python-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)

## publish

Expand All @@ -106,7 +106,7 @@ To pass arguments to the application, just add them after `--`, like:
scala-cli MyApp.scala -- first-arg second-arg
```

Accepts option groups: [benchmarking](./cli-options.md#benchmarking-options), [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [main class](./cli-options.md#main-class-options), [markdown](./cli-options.md#markdown-options), [python](./cli-options.md#python-options), [run](./cli-options.md#run-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)
Accepts option groups: [benchmarking](./cli-options.md#benchmarking-options), [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [java prop](./cli-options.md#java-prop-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [main class](./cli-options.md#main-class-options), [markdown](./cli-options.md#markdown-options), [python](./cli-options.md#python-options), [run](./cli-options.md#run-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)

## github secret create

Expand Down Expand Up @@ -154,13 +154,13 @@ println("Hello, world)
Accepts option groups: [benchmarking](./cli-options.md#benchmarking-options), [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [main class](./cli-options.md#main-class-options), [markdown](./cli-options.md#markdown-options), [python](./cli-options.md#python-options), [run](./cli-options.md#run-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)
Accepts option groups: [benchmarking](./cli-options.md#benchmarking-options), [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [java prop](./cli-options.md#java-prop-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [main class](./cli-options.md#main-class-options), [markdown](./cli-options.md#markdown-options), [python](./cli-options.md#python-options), [run](./cli-options.md#run-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)
## test
Compile and test Scala code
Accepts option groups: [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [markdown](./cli-options.md#markdown-options), [python](./cli-options.md#python-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [test](./cli-options.md#test-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)
Accepts option groups: [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [directories](./cli-options.md#directories-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [java](./cli-options.md#java-options), [java prop](./cli-options.md#java-prop-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [markdown](./cli-options.md#markdown-options), [python](./cli-options.md#python-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [test](./cli-options.md#test-options), [verbosity](./cli-options.md#verbosity-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)
## uninstall
Expand Down
16 changes: 13 additions & 3 deletions website/docs/reference/scala-command/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,21 @@ Aliases: `-J`

Set Java options, such as `-Xmx1g`

### `--java-prop`
## Java prop options

`MUST have` per Scala Runner specification
Available in commands:

[`repl` , `console`](./commands.md#repl), [`run`](./commands.md#run), [`shebang`](./commands.md#shebang), [`test`](./commands.md#test)

<!-- Automatically generated, DO NOT EDIT MANUALLY -->

### `--java-prop-option`

Aliases: `--java-prop`

`IMPLEMENTATION specific` per Scala Runner specification

Set Java properties
Add java properties. Note that options equal `-Dproperty=value` are assumed to be java properties and don't require to be passed after `--java-prop`.

## Jvm options

Expand Down
Loading

0 comments on commit fb207c1

Please sign in to comment.