Skip to content

Commit 05f127a

Browse files
Split ScalaCli main logic
1 parent 2e1b5b3 commit 05f127a

File tree

9 files changed

+120
-94
lines changed

9 files changed

+120
-94
lines changed

modules/cli/src/main/scala/scala/cli/ScalaCli.scala

Lines changed: 5 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,22 @@
11
package scala.cli
22

3-
import caseapp.core.app.CommandsEntryPoint
4-
import caseapp.core.help.{Help, RuntimeCommandsHelp}
53
import sun.misc.{Signal, SignalHandler}
64

75
import java.io.{ByteArrayOutputStream, PrintStream}
86
import java.nio.charset.StandardCharsets
9-
import java.nio.file.InvalidPathException
107

118
import scala.build.internal.Constants
12-
import scala.cli.commands._
139
import scala.cli.internal.Argv0
1410
import scala.cli.launcher.{LauncherCli, LauncherOptions}
1511
import scala.util.Properties
1612

17-
object ScalaCli extends CommandsEntryPoint {
18-
19-
def actualDefaultCommand = Default
20-
21-
val commands: Seq[ScalaCommand[_]] = Seq(
22-
About,
23-
AddPath,
24-
BloopExit,
25-
BloopStart,
26-
Bsp,
27-
Clean,
28-
Compile,
29-
Directories,
30-
Export,
31-
Fmt,
32-
HelpCmd,
33-
InstallCompletions,
34-
InstallHome,
35-
Metabrowse,
36-
Repl,
37-
Package,
38-
Run,
39-
SetupIde,
40-
Shebang,
41-
Test,
42-
Update,
43-
Version
44-
)
45-
46-
lazy val progName = (new Argv0).get("scala-cli")
47-
override def description =
48-
"Scala CLI is a command-line tool to interact with the Scala language. It lets you compile, run, test, and package your Scala code."
49-
override def summaryDesc =
50-
"""|See 'scala-cli <command> --help' to read about a specific subcommand. To see full help run 'scala-cli <command> --help-full'.
51-
|To run another Scala CLI version, specify it with '--cli-version' before any other argument, like 'scala-cli --cli-version <version> args'.""".stripMargin
52-
final override def defaultCommand = Some(actualDefaultCommand)
53-
54-
// FIXME Report this in case-app default NameFormatter
55-
override lazy val help: RuntimeCommandsHelp = {
56-
val parent = super.help
57-
parent.withDefaultHelp(Help[Unit]())
58-
}
59-
60-
override def enableCompleteCommand = true
61-
override def enableCompletionsCommand = true
13+
object ScalaCli {
6214

63-
override def helpFormat = actualDefaultCommand.helpFormat
15+
val progName = (new Argv0).get("scala-cli")
6416

6517
private def isGraalvmNativeImage: Boolean =
6618
sys.props.contains("org.graalvm.nativeimage.imagecode")
6719

68-
private def isShebangFile(arg: String): Boolean = {
69-
val pathOpt =
70-
try Some(os.Path(arg, os.pwd))
71-
catch {
72-
case _: InvalidPathException => None
73-
}
74-
pathOpt.filter(os.isFile(_)).filter(_.toIO.canRead).exists { path =>
75-
val content = os.read(path) // FIXME Charset?
76-
content.startsWith(s"#!/usr/bin/env $progName" + System.lineSeparator())
77-
}
78-
}
79-
8020
private def partitionArgs(args: Array[String]): (Array[String], Array[String]) = {
8121
val systemProps = args.takeWhile(_.startsWith("-D"))
8222
(systemProps, args.drop(systemProps.size))
@@ -122,7 +62,7 @@ object ScalaCli extends CommandsEntryPoint {
12262
.takeWhile(_.isDigit)
12363
.toInt
12464

125-
override def main(args: Array[String]): Unit = {
65+
def main(args: Array[String]): Unit = {
12666
try main0(args)
12767
catch {
12868
case e: Throwable if !isCI =>
@@ -192,19 +132,7 @@ object ScalaCli extends CommandsEntryPoint {
192132
// Enable ANSI output in Windows terminal
193133
coursier.jniutils.WindowsAnsiTerminal.enableAnsiOutput()
194134

195-
// quick hack, until the raw args are kept in caseapp.RemainingArgs by case-app
196-
actualDefaultCommand.anyArgs = scalaCliArgs.nonEmpty
197-
198-
commands.foreach {
199-
case c: NeedsArgvCommand => c.setArgv(progName +: scalaCliArgs)
200-
case _ =>
201-
}
202-
203-
val processedArgs =
204-
if (scalaCliArgs.lengthCompare(1) > 0 && isShebangFile(scalaCliArgs(0)))
205-
Array(scalaCliArgs(0), "--") ++ scalaCliArgs.tail
206-
else
207-
scalaCliArgs
208-
super.main(processedArgs)
135+
new ScalaCliCommands(progName)
136+
.main(scalaCliArgs)
209137
}
210138
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package scala.cli
2+
3+
import caseapp.core.app.CommandsEntryPoint
4+
import caseapp.core.help.{Help, RuntimeCommandsHelp}
5+
6+
import java.nio.file.InvalidPathException
7+
8+
import scala.cli.commands._
9+
10+
class ScalaCliCommands(val progName: String) extends CommandsEntryPoint {
11+
12+
lazy val actualDefaultCommand: DefaultBase = new Default(help)
13+
14+
def commands = Seq[ScalaCommand[_]](
15+
About,
16+
AddPath,
17+
BloopExit,
18+
BloopStart,
19+
Bsp,
20+
Clean,
21+
Compile,
22+
Directories,
23+
Export,
24+
Fmt,
25+
new HelpCmd(help),
26+
InstallCompletions,
27+
InstallHome,
28+
Metabrowse,
29+
Repl,
30+
Package,
31+
Run,
32+
SetupIde,
33+
Shebang,
34+
Test,
35+
Update,
36+
Version
37+
)
38+
39+
override def description =
40+
"Scala CLI is a command-line tool to interact with the Scala language. It lets you compile, run, test, and package your Scala code."
41+
override def summaryDesc =
42+
"""|See 'scala-cli <command> --help' to read about a specific subcommand. To see full help run 'scala-cli <command> --help-full'.
43+
|To run another Scala CLI version, specify it with '--cli-version' before any other argument, like 'scala-cli --cli-version <version> args'.""".stripMargin
44+
final override def defaultCommand = Some(actualDefaultCommand)
45+
46+
// FIXME Report this in case-app default NameFormatter
47+
override lazy val help: RuntimeCommandsHelp = {
48+
val parent = super.help
49+
parent.withDefaultHelp(Help[Unit]())
50+
}
51+
52+
override def enableCompleteCommand = true
53+
override def enableCompletionsCommand = true
54+
55+
override def helpFormat = ScalaCliHelp.helpFormat
56+
57+
private def isShebangFile(arg: String): Boolean = {
58+
val pathOpt =
59+
try Some(os.Path(arg, os.pwd))
60+
catch {
61+
case _: InvalidPathException => None
62+
}
63+
pathOpt.filter(os.isFile(_)).filter(_.toIO.canRead).exists { path =>
64+
val content = os.read(path) // FIXME Charset?
65+
content.startsWith(s"#!/usr/bin/env $progName" + System.lineSeparator())
66+
}
67+
}
68+
69+
override def main(args: Array[String]): Unit = {
70+
71+
// quick hack, until the raw args are kept in caseapp.RemainingArgs by case-app
72+
actualDefaultCommand.anyArgs = args.nonEmpty
73+
74+
commands.foreach {
75+
case c: NeedsArgvCommand => c.setArgv(progName +: args)
76+
case _ =>
77+
}
78+
79+
val processedArgs =
80+
if (args.lengthCompare(1) > 0 && isShebangFile(args(0)))
81+
Array(args(0), "--") ++ args.tail
82+
else
83+
args
84+
super.main(processedArgs)
85+
}
86+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package scala.cli
2+
3+
import caseapp.core.help.HelpFormat
4+
5+
object ScalaCliHelp {
6+
val helpFormat = HelpFormat.default()
7+
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package scala.cli.commands
22

3-
import scala.cli.ScalaCli
3+
import caseapp.core.help.RuntimeCommandsHelp
4+
5+
import scala.cli.ScalaCliHelp
46

57
// FIXME scalafmt formats that really weirdly, need to investigate why
68
// format: off
7-
object Default extends DefaultBase(
8-
ScalaCli.help.help(ScalaCli.helpFormat),
9-
ScalaCli.help.help(ScalaCli.helpFormat, showHidden = true)
9+
class Default(help: => RuntimeCommandsHelp) extends DefaultBase(
10+
help.help(ScalaCliHelp.helpFormat),
11+
help.help(ScalaCliHelp.helpFormat, showHidden = true)
1012
)
1113
// format: on
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package scala.cli.commands
22

33
import caseapp._
4+
import caseapp.core.help.RuntimeCommandsHelp
45

5-
import scala.cli.ScalaCli
6+
import scala.cli.ScalaCliHelp
67

7-
object HelpCmd extends ScalaCommand[HelpOptions] {
8+
class HelpCmd(actualHelp: => RuntimeCommandsHelp) extends ScalaCommand[HelpOptions] {
89
override def names = List(List("help"))
910

1011
def run(options: HelpOptions, args: RemainingArgs) =
11-
println(ScalaCli.help.help(ScalaCli.helpFormat))
12+
println(actualHelp.help(ScalaCliHelp.helpFormat))
1213
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import caseapp._
44
import caseapp.core.help.Help
55
import upickle.default.{ReadWriter, macroRW}
66

7-
import scala.cli.ScalaCli
7+
import scala.cli.ScalaCliHelp
88

99
@HelpMessage("Print help message")
1010
case class HelpGroupOptions(
@@ -15,8 +15,8 @@ case class HelpGroupOptions(
1515
) {
1616

1717
private def printHelpWithGroup(help: Help[_], group: String) = {
18-
println(help.help(ScalaCli.helpFormat.withHiddenGroups(
19-
ScalaCli.helpFormat.hiddenGroups.map(_.filterNot(_ == group))
18+
println(help.help(ScalaCliHelp.helpFormat.withHiddenGroups(
19+
ScalaCliHelp.helpFormat.hiddenGroups.map(_.filterNot(_ == group))
2020
)))
2121
sys.exit(0)
2222
}

modules/cli/src/test/scala/cli/tests/HelpCheck.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package cli.tests
22

3-
import scala.cli.ScalaCli
3+
import scala.cli.ScalaCliCommands
44

55
class HelpCheck extends munit.FunSuite {
66

77
test("help message should be shorter then 80 lines") {
8-
val helpMessage = ScalaCli.help.help(ScalaCli.helpFormat)
8+
val scalaCli = new ScalaCliCommands("scala-cli")
9+
val helpMessage = scalaCli.help.help(scalaCli.helpFormat)
910

1011
val lines = helpMessage.split("\r\n|\r|\n").length
1112
assert(lines <= 80)

modules/cli/src/test/scala/cli/tests/OptionsCheck.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package scala.cli.tests
22

3-
import scala.cli.ScalaCli
3+
import scala.cli.ScalaCliCommands
44

55
class OptionsCheck extends munit.FunSuite {
66

7-
for (command <- ScalaCli.commands)
7+
for (command <- (new ScalaCliCommands("scala-cli")).commands)
88
test(s"No duplicated options in ${command.names.head.mkString(" ")}") {
99
command.ensureNoDuplicates()
1010
}

modules/generate-reference-doc/src/main/scala/scala/cli/doc/GenerateReferenceDoc.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import scala.build.preprocessing.directives.{
1414
RequireDirectiveHandler,
1515
UsingDirectiveHandler
1616
}
17-
import scala.cli.ScalaCli
17+
import scala.cli.ScalaCliCommands
1818

1919
object GenerateReferenceDoc extends CaseApp[Options] {
2020

@@ -283,9 +283,10 @@ object GenerateReferenceDoc extends CaseApp[Options] {
283283

284284
def run(options: Options, args: RemainingArgs): Unit = {
285285

286-
val commands = ScalaCli.commands
286+
val scalaCli = new ScalaCliCommands("scala-cli")
287+
val commands = scalaCli.commands
287288
val allArgs = commands.flatMap(_.finalHelp.args)
288-
val nameFormatter = ScalaCli.actualDefaultCommand.nameFormatter
289+
val nameFormatter = scalaCli.actualDefaultCommand.nameFormatter
289290

290291
val cliOptionsContent0 = cliOptionsContent(commands, allArgs, nameFormatter)
291292
val commandsContent0 = commandsContent(commands)

0 commit comments

Comments
 (0)