Skip to content

Commit 445c0b8

Browse files
authored
Merge pull request #1774 from Gedochao/legacy-runner-options
Add support for deprecated Scala `2.13.x`-specific `scala` runner options
2 parents 026e507 + abce9e8 commit 445c0b8

File tree

10 files changed

+244
-97
lines changed

10 files changed

+244
-97
lines changed

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import caseapp.core.Error
44
import caseapp.core.help.{Help, HelpCompanion, RuntimeCommandsHelp}
55
import caseapp.core.parser.Parser
66

7-
import scala.cli.commands.default.DefaultOptions
7+
import scala.cli.commands.default.{DefaultOptions, LegacyScalaOptions}
88
import scala.cli.commands.shared.{HasLoggingOptions, ScalaCliHelp}
99
import scala.cli.commands.util.HelpUtils.*
1010
import scala.cli.launcher.LauncherOptions
@@ -18,12 +18,23 @@ abstract class ScalaCommandWithCustomHelp[T <: HasLoggingOptions](
1818
) extends ScalaCommand[T] {
1919
private def launcherHelp: Help[LauncherOptions] = HelpCompanion.deriveHelp[LauncherOptions]
2020

21+
private def legacyScalaHelp: Help[LegacyScalaOptions] =
22+
HelpCompanion.deriveHelp[LegacyScalaOptions]
23+
2124
protected def customHelp(showHidden: Boolean): String = {
22-
val helpString = actualHelp.help(helpFormat, showHidden)
23-
val launcherHelpString = launcherHelp.optionsHelp(helpFormat, showHidden)
25+
val helpString = actualHelp.help(helpFormat, showHidden)
26+
val launcherHelpString = launcherHelp.optionsHelp(helpFormat, showHidden)
27+
val legacyScalaHelpString = legacyScalaHelp.optionsHelp(helpFormat, showHidden)
28+
val legacyScalaHelpStringWithPadding =
29+
if legacyScalaHelpString.nonEmpty then
30+
s"""
31+
|$legacyScalaHelpString
32+
|""".stripMargin
33+
else ""
2434
s"""$helpString
2535
|
26-
|$launcherHelpString""".stripMargin
36+
|$launcherHelpString
37+
|$legacyScalaHelpStringWithPadding""".stripMargin
2738
}
2839

2940
protected def customHelpAsked(showHidden: Boolean): Nothing = {

modules/cli/src/main/scala/scala/cli/commands/default/Default.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ class Default(
2222

2323
private lazy val defaultCommandHelp: String =
2424
s"""
25-
|
2625
|When no subcommand is passed explicitly, an implicit subcommand is used based on context:
2726
| - if the '--version' option is passed, it prints the 'version' subcommand output, unmodified by any other options
2827
| - if any inputs were passed, it defaults to the 'run' subcommand

modules/cli/src/main/scala/scala/cli/commands/default/LegacyScalaOptions.scala

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import caseapp.core.Indexed
55

66
import scala.build.Logger
77
import scala.cli.ScalaCli
8+
import scala.cli.ScalaCli.fullRunnerName
89
import scala.cli.commands.default.LegacyScalaOptions.*
910
import scala.cli.commands.package0.Package
1011
import scala.cli.commands.tags
@@ -13,16 +14,38 @@ import scala.cli.commands.tags
1314
*/
1415
// format: off
1516
case class LegacyScalaOptions(
16-
@Group("Scala")
17+
@Group("Legacy Scala runner")
1718
@HelpMessage(s"Ignored legacy option. Deprecated equivalent of running a subsequent `$PowerString${Package.name}` command.")
1819
@Tag(tags.must)
20+
@Hidden
1921
@Name("-save")
2022
save: Option[Indexed[Boolean]] = None,
21-
@Group("Scala")
23+
@Group("Legacy Scala runner")
2224
@HelpMessage("Ignored legacy option. Deprecated override canceling the `-nosave` option.")
2325
@Tag(tags.must)
26+
@Hidden
2427
@Name("-nosave")
2528
nosave: Option[Indexed[Boolean]] = None,
29+
@Group("Legacy Scala runner")
30+
@HelpMessage("Ignored legacy option. Deprecated override defining how the runner should treat the input. Use the appropriate sub-command instead.")
31+
@Tag(tags.must)
32+
@Hidden
33+
@ValueDescription("object|script|jar|repl|guess")
34+
@Name("-howtorun")
35+
howToRun: Option[Indexed[String]] = None,
36+
@Group("Legacy Scala runner")
37+
@HelpMessage("Ignored legacy option. Deprecated option allowing to preload inputs for the repl or command execution.")
38+
@Tag(tags.must)
39+
@Hidden
40+
@ValueDescription("file")
41+
I: Option[Indexed[List[String]]] = None,
42+
@Group("Legacy Scala runner")
43+
@HelpMessage("Ignored legacy option. Deprecated option allowing to prevent the use of the legacy fsc compilation daemon.")
44+
@Tag(tags.must)
45+
@Hidden
46+
@Name("-nc")
47+
@Name("-nocompdaemon")
48+
noCompilationDaemon: Option[Indexed[Boolean]] = None,
2649
) {
2750
// format: on
2851

@@ -36,9 +59,14 @@ case class LegacyScalaOptions(
3659
progName: String,
3760
logger: Logger
3861
): Array[String] = {
39-
val saveOptionString = save.findArg(args)
40-
val noSaveOptionString = nosave.findArg(args)
41-
val deprecatedArgs = Seq(saveOptionString, noSaveOptionString).flatten
62+
val saveOptionString = save.findArg(args)
63+
val noSaveOptionString = nosave.findArg(args)
64+
val howToRunString = howToRun.findArg(args)
65+
val iString = I.findArg(args)
66+
val noCompilationDaemonString = noCompilationDaemon.findArg(args)
67+
val deprecatedArgs =
68+
Seq(saveOptionString, noSaveOptionString, howToRunString, iString, noCompilationDaemonString)
69+
.flatten
4270
val filteredArgs = args.filterNot(deprecatedArgs.contains)
4371
val filteredArgsString = filteredArgs.mkString(" ")
4472
saveOptionString.foreach { s =>
@@ -55,6 +83,49 @@ case class LegacyScalaOptions(
5583
|A jar file is not saved unless the '$PowerString${Package.name}' sub-command is called.""".stripMargin
5684
)
5785
}
86+
for {
87+
htrString <- howToRunString
88+
htrValue <- howToRun.map(_.value)
89+
} {
90+
logger.message(s"Deprecated option '$htrString' is ignored.".stripMargin)
91+
val passedValueExplanation = htrValue match {
92+
case v @ ("object" | "script" | "jar") =>
93+
s"""$fullRunnerName does not support explicitly forcing an input to be run as '$v'.
94+
|Just make sure your inputs have the correct format and extension.""".stripMargin
95+
case "guess" =>
96+
s"""$fullRunnerName does not support `guess` mode.
97+
|Just make sure your inputs have the correct format and extension.""".stripMargin
98+
case "repl" =>
99+
s"""In order to explicitly run the repl, use the 'repl' sub-command.
100+
| ${Console.BOLD}$progName repl $filteredArgsString${Console.RESET}
101+
|""".stripMargin
102+
case invalid @ _ =>
103+
s"""'$invalid' is not an accepted value for the '$htrString' option.
104+
|$fullRunnerName uses an equivalent of the old 'guess' mode by default at all times.""".stripMargin
105+
}
106+
logger.message(passedValueExplanation)
107+
logger.message(
108+
s"""Instead of the deprecated '$htrString' option, $fullRunnerName now uses a sub-command system.
109+
|To learn more, try viewing the help.
110+
| ${Console.BOLD}$progName -help${Console.RESET}""".stripMargin
111+
)
112+
}
113+
for {
114+
optionName <- iString
115+
optionValues <- I.map(_.value)
116+
exampleReplInputs = optionValues.mkString(" ")
117+
} {
118+
logger.message(s"Deprecated option '$optionName' is ignored.".stripMargin)
119+
logger.message(
120+
s"""To preload the extra files for the repl, try passing them as inputs for the repl sub-command.
121+
| ${Console.BOLD}$progName repl $exampleReplInputs${Console.RESET}
122+
|""".stripMargin
123+
)
124+
}
125+
noCompilationDaemonString.foreach { nc =>
126+
logger.message(s"Deprecated option '$nc' is ignored.")
127+
logger.message("The script runner can no longer be picked as before.")
128+
}
58129
filteredArgs
59130
}
60131
}

modules/cli/src/main/scala/scala/cli/commands/shared/VerbosityOptions.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ final case class VerbosityOptions(
1313
@HelpMessage("Increase verbosity (can be specified multiple times)")
1414
@Tag(tags.implementation)
1515
@Name("v")
16+
@Name("-verbose")
1617
verbose: Int @@ Counter = Tag.of(0),
1718
@Group("Logging")
1819
@HelpMessage("Interactive mode")

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

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package scala.cli.integration
22

33
import com.eed3si9n.expecty.Expecty.expect
44

5-
class DefaultTests extends WithWarmUpScalaCliSuite {
5+
class DefaultTests extends WithWarmUpScalaCliSuite with LegacyScalaRunnerTestDefinitions {
66
override def warmUpExtraTestOptions: Seq[String] = TestUtil.extraOptions
77

88
test("running scala-cli with no args should default to repl") {
@@ -36,17 +36,6 @@ class DefaultTests extends WithWarmUpScalaCliSuite {
3636
}
3737
}
3838

39-
test("default to the run sub-command when a script snippet is passed with -e") {
40-
TestInputs.empty.fromRoot { root =>
41-
val msg = "Hello world"
42-
val quotation = TestUtil.argQuotationMark
43-
val res =
44-
os.proc(TestUtil.cli, "-e", s"println($quotation$msg$quotation)", TestUtil.extraOptions)
45-
.call(cwd = root)
46-
expect(res.out.trim() == msg)
47-
}
48-
}
49-
5039
test("default to the run sub-command when a scala snippet is passed with --execute-scala") {
5140
TestInputs.empty.fromRoot { root =>
5241
val msg = "Hello world"
@@ -99,23 +88,6 @@ class DefaultTests extends WithWarmUpScalaCliSuite {
9988
}
10089
}
10190

102-
test("running scala-cli with a script snippet passed with -e shouldn't allow repl-only options") {
103-
TestInputs.empty.fromRoot { root =>
104-
val replSpecificOption = "--repl-dry-run"
105-
val res =
106-
os.proc(
107-
TestUtil.cli,
108-
"-e",
109-
"println()",
110-
replSpecificOption,
111-
TestUtil.extraOptions
112-
)
113-
.call(cwd = root, mergeErrIntoOut = true, check = false)
114-
expect(res.exitCode == 1)
115-
expect(res.out.lines().endsWith(unrecognizedArgMessage(replSpecificOption)))
116-
}
117-
}
118-
11991
test("default to the run sub-command if -classpath and --main-class are passed") {
12092
val expectedOutput = "Hello"
12193
val mainClassName = "Main"
@@ -183,49 +155,13 @@ class DefaultTests extends WithWarmUpScalaCliSuite {
183155
}
184156
}
185157

186-
test("ensure -save/--save works with the default command") {
187-
val msg = "Hello world"
188-
TestInputs(os.rel / "s.sc" -> s"""println("$msg")""").fromRoot { root =>
189-
val legacySaveOption = "-save"
190-
val res1 =
191-
os.proc(TestUtil.cli, ".", legacySaveOption, TestUtil.extraOptions)
192-
.call(cwd = root, stderr = os.Pipe)
193-
expect(res1.out.trim() == msg)
194-
expect(res1.err.trim().contains(s"Deprecated option '$legacySaveOption' is ignored"))
195-
val doubleDashSaveOption = "--save"
196-
val res2 =
197-
os.proc(TestUtil.cli, ".", doubleDashSaveOption, TestUtil.extraOptions)
198-
.call(cwd = root, stderr = os.Pipe)
199-
expect(res2.out.trim() == msg)
200-
expect(res2.err.trim().contains(s"Deprecated option '$doubleDashSaveOption' is ignored"))
201-
}
202-
}
203-
204-
test("ensure -nosave/--nosave works with the default command") {
205-
val msg = "Hello world"
206-
TestInputs(os.rel / "s.sc" -> s"""println("$msg")""").fromRoot { root =>
207-
val legacyNoSaveOption = "-nosave"
208-
val res1 =
209-
os.proc(TestUtil.cli, ".", legacyNoSaveOption, TestUtil.extraOptions)
210-
.call(cwd = root, stderr = os.Pipe)
211-
expect(res1.out.trim() == msg)
212-
expect(res1.err.trim().contains(s"Deprecated option '$legacyNoSaveOption' is ignored"))
213-
val doubleDashNoSaveOption = "--nosave"
214-
val res2 =
215-
os.proc(TestUtil.cli, ".", doubleDashNoSaveOption, TestUtil.extraOptions)
216-
.call(cwd = root, stderr = os.Pipe)
217-
expect(res2.out.trim() == msg)
218-
expect(res2.err.trim().contains(s"Deprecated option '$doubleDashNoSaveOption' is ignored"))
219-
}
220-
}
221-
222-
private def unrecognizedArgMessage(argName: String) =
158+
protected def unrecognizedArgMessage(argName: String): Vector[String] =
223159
s"""
224160
|Unrecognized argument: $argName
225161
|
226162
|To list all available options, run
227163
| ${Console.BOLD}${TestUtil.detectCliPath} --help${Console.RESET}
228164
|""".stripMargin.trim.linesIterator.toVector
229165

230-
private lazy val replDryRunOutput = "Dry run, not running REPL."
166+
protected lazy val replDryRunOutput = "Dry run, not running REPL."
231167
}

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,46 @@ class HelpTests extends ScalaCliSuite {
2525
test(s"$helpOptionsString output includes launcher options") {
2626
expect(helpOutput.contains("--power"))
2727
}
28+
29+
test(s"$helpOptionsString output does not include legacy scala runner options") {
30+
expect(!helpOutput.contains("Legacy Scala runner options"))
31+
}
2832
}
2933

34+
for (fullHelpOptions <- HelpTests.fullHelpVariants) {
35+
lazy val fullHelp = os.proc(TestUtil.cli, fullHelpOptions).call(check = false)
36+
lazy val fullHelpOutput = fullHelp.out.trim()
37+
val fullHelpOptionsString = fullHelpOptions.mkString(" ")
38+
test(s"$fullHelpOptionsString works correctly") {
39+
assert(
40+
fullHelp.exitCode == 0,
41+
clues(fullHelpOptions, fullHelp.out.text(), fullHelp.err.text(), fullHelp.exitCode)
42+
)
43+
expect(fullHelpOutput.contains("Usage:"))
44+
}
45+
test(s"$fullHelpOptionsString output includes legacy scala runner options") {
46+
expect(fullHelpOutput.contains("Legacy Scala runner options"))
47+
}
48+
}
3049
}
3150

3251
object HelpTests {
3352
val variants =
34-
Seq(Seq("help"), Seq("help", "-help"), Seq("help", "--help"), Seq("-help"), Seq("--help"))
53+
Seq(
54+
Seq("help"),
55+
Seq("help", "-help"),
56+
Seq("help", "--help"),
57+
Seq("-help"),
58+
Seq("--help")
59+
)
60+
val fullHelpVariants =
61+
Seq(
62+
Seq("help", "--full-help"),
63+
Seq("help", "-full-help"),
64+
Seq("help", "--help-full"),
65+
Seq("help", "-help-full"),
66+
Seq("--full-help"),
67+
Seq("-full-help"),
68+
Seq("-help-full")
69+
)
3570
}

0 commit comments

Comments
 (0)