Skip to content

Commit a4cb009

Browse files
authored
Merge pull request #1262 from lwronski/version
Add version of Scala to the output of version command
2 parents 69a4545 + 1775999 commit a4cb009

File tree

12 files changed

+117
-25
lines changed

12 files changed

+117
-25
lines changed

modules/cli-options/src/main/scala/scala/cli/commands/VersionOptions.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ import caseapp._
66
@HelpMessage("Print `scala-cli` version")
77
final case class VersionOptions(
88
@Recurse
9-
verbosity: VerbosityOptions = VerbosityOptions()
9+
verbosity: VerbosityOptions = VerbosityOptions(),
10+
@HelpMessage("Show only plain scala-cli version")
11+
@Name("cli")
12+
cliVersion: Boolean = false,
13+
@HelpMessage("Show only plain scala version")
14+
@Name("scala")
15+
scalaVersion: Boolean = false
1016
)
1117
// format: on
1218

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package scala.cli.internal;
2+
3+
import com.oracle.svm.core.annotate.Substitute;
4+
import com.oracle.svm.core.annotate.TargetClass;
5+
import org.graalvm.nativeimage.Platform;
6+
import org.graalvm.nativeimage.Platforms;
7+
8+
import java.nio.file.Path;
9+
10+
@TargetClass(className = "scala.cli.internal.Argv0")
11+
@Platforms({Platform.WINDOWS.class})
12+
final class Argv0SubstWindows {
13+
14+
@Substitute
15+
String get(String defaultValue) {
16+
return coursier.jniutils.ModuleFileName.get();
17+
}
18+
19+
}

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@ import scala.util.Properties
1616

1717
object ScalaCli {
1818

19+
if (Properties.isWin && isGraalvmNativeImage)
20+
// have to be initialized before running (new Argv0).get because Argv0SubstWindows uses csjniutils library
21+
// The DLL loaded by LoadWindowsLibrary is statically linke/d in
22+
// the Scala CLI native image, no need to manually load it.
23+
coursier.jniutils.LoadWindowsLibrary.assumeInitialized()
24+
1925
val progName = (new Argv0).get("scala-cli")
2026

21-
private def checkName(name: String) =
22-
progName == name ||
23-
progName.endsWith(s"/$name") ||
24-
progName.endsWith(File.separator + name)
27+
private def checkName(name: String) = {
28+
val baseProgName = if (Properties.isWin) progName.stripSuffix(".exe") else progName
29+
baseProgName == name ||
30+
baseProgName.endsWith(s"/$name") ||
31+
baseProgName.endsWith(File.separator + name)
32+
}
2533

2634
private var isSipScala = checkName("scala") || checkName("scala-cli-sip")
2735

@@ -171,11 +179,6 @@ object ScalaCli {
171179
if (!Properties.isWin && isGraalvmNativeImage)
172180
ignoreSigpipe()
173181

174-
if (Properties.isWin && isGraalvmNativeImage)
175-
// The DLL loaded by LoadWindowsLibrary is statically linked in
176-
// the Scala CLI native image, no need to manually load it.
177-
coursier.jniutils.LoadWindowsLibrary.assumeInitialized()
178-
179182
if (Properties.isWin && System.console() != null && coursier.paths.Util.useJni())
180183
// Enable ANSI output in Windows terminal
181184
coursier.jniutils.WindowsAnsiTerminal.enableAnsiOutput()

modules/cli/src/main/scala/scala/cli/ScalaCliCommands.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ScalaCliCommands(
1818
isSipScala: Boolean
1919
) extends CommandsEntryPoint {
2020

21-
lazy val actualDefaultCommand = new Default(help)
21+
lazy val actualDefaultCommand = new Default(help, isSipScala)
2222

2323
// for debugging purposes - allows to run the scala-cli-signing binary from the Scala CLI JVM launcher
2424
private lazy val pgpUseBinaryCommands =
@@ -64,7 +64,7 @@ class ScalaCliCommands(
6464
Uninstall,
6565
UninstallCompletions,
6666
Update,
67-
Version
67+
new Version(isSipScala = isSipScala)
6868
) ++ (if (pgpUseBinaryCommands) Nil else pgpCommands.allScalaCommands.toSeq) ++
6969
(if (pgpUseBinaryCommands) pgpBinaryCommands.allScalaCommands.toSeq else Nil)
7070

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@ class About(isSipScala: Boolean) extends ScalaCommand[AboutOptions] {
1111

1212
def run(options: AboutOptions, args: RemainingArgs): Unit = {
1313
CurrentParams.verbosity = options.verbosity.verbosity
14-
val version = Constants.version
15-
val detailedVersionOpt = Constants.detailedVersion.filter(_ != version)
16-
val appName =
17-
if (isSipScala) "Scala command"
18-
else "Scala CLI"
19-
println(s"$appName version $version" + detailedVersionOpt.fold("")(" (" + _ + ")"))
14+
println(Version.versionInfo(isSipScala))
2015
val newestScalaCliVersion = Update.newestScalaCliVersion(options.ghToken.map(_.get()))
2116
val isOutdated = CommandUtils.isOutOfDateVersion(
2217
newestScalaCliVersion,

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import scala.build.internal.Constants
77
import scala.cli.{CurrentParams, ScalaCliHelp}
88

99
class Default(
10-
actualHelp: => RuntimeCommandsHelp
10+
actualHelp: => RuntimeCommandsHelp,
11+
isSipScala: Boolean
1112
) extends ScalaCommand[DefaultOptions] {
1213

1314
private def defaultHelp: String = actualHelp.help(ScalaCliHelp.helpFormat)
@@ -30,7 +31,7 @@ class Default(
3031
def run(options: DefaultOptions, args: RemainingArgs): Unit = {
3132
CurrentParams.verbosity = options.runOptions.shared.logging.verbosity
3233
if (options.version)
33-
println(Constants.version)
34+
println(Version.versionInfo(isSipScala))
3435
else if (anyArgs)
3536
Run.run(
3637
options.runOptions,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ object InstallHome extends ScalaCommand[InstallHomeOptions] {
5151
val newScalaCliBinPath = os.Path(options.scalaCliBinaryPath, os.pwd)
5252

5353
val newVersion: String =
54-
os.proc(newScalaCliBinPath, "version").call(cwd = os.pwd).out.text().trim
54+
os.proc(newScalaCliBinPath, "version", "--cli-version").call(cwd = os.pwd).out.text().trim
5555

5656
// Backward compatibility - previous versions not have the `--version` parameter
5757
val oldVersion: String =
5858
if (os.isFile(destBinPath)) {
59-
val res = os.proc(destBinPath, "version").call(cwd = os.pwd, check = false)
59+
val res = os.proc(destBinPath, "version", "--cli-version").call(cwd = os.pwd, check = false)
6060
if (res.exitCode == 0)
6161
res.out.text().trim
6262
else

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ object Update extends ScalaCommand[UpdateOptions] {
9595
}
9696

9797
private def getCurrentVersion(scalaCliBinPath: os.Path): String = {
98-
val res = os.proc(scalaCliBinPath, "version").call(cwd = os.pwd, check = false)
98+
val res = os.proc(scalaCliBinPath, "version", "--cli-version").call(cwd = os.pwd, check = false)
9999
if (res.exitCode == 0)
100100
res.out.text().trim
101101
else

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,26 @@ import caseapp._
55
import scala.build.internal.Constants
66
import scala.cli.CurrentParams
77

8-
object Version extends ScalaCommand[VersionOptions] {
8+
class Version(isSipScala: Boolean) extends ScalaCommand[VersionOptions] {
99
override def group = "Miscellaneous"
1010
def run(options: VersionOptions, args: RemainingArgs): Unit = {
1111
CurrentParams.verbosity = options.verbosity.verbosity
12-
println(Constants.version)
12+
if (options.cliVersion)
13+
println(Constants.version)
14+
else if (options.scalaVersion)
15+
println(Constants.defaultScalaVersion)
16+
else
17+
println(Version.versionInfo(isSipScala))
1318
}
1419
}
20+
21+
object Version {
22+
def versionInfo(isSipScala: Boolean) =
23+
val version = Constants.version
24+
val detailedVersionOpt = Constants.detailedVersion.filter(_ != version).fold("")(" (" + _ + ")")
25+
val appName =
26+
if (isSipScala) "Scala code runner"
27+
else "Scala CLI"
28+
s"""$appName version: $version$detailedVersionOpt
29+
|Scala version (default): ${Constants.defaultScalaVersion}""".stripMargin
30+
}

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,35 @@ class SipScalaTests extends ScalaCliSuite {
3939
noDirectoriesCommandTest("scala-cli-sip")
4040
}
4141
}
42+
43+
def runVersionCommand(binaryName: String) =
44+
TestInputs.empty.fromRoot { root =>
45+
val cliPath = os.Path(TestUtil.cliPath, os.pwd)
46+
val ext = if (Properties.isWin) ".exe" else ""
47+
val newCliPath = root / s"$binaryName$ext"
48+
os.copy(cliPath, newCliPath)
49+
50+
for { versionOption <- Seq("version", "-version", "--version") } {
51+
val version = os.proc(newCliPath, versionOption).call(check = false)
52+
assert(
53+
version.exitCode == 0,
54+
clues(version, version.out.text(), version.err.text(), version.exitCode)
55+
)
56+
val expectedLauncherVersion =
57+
if (binaryName == "scala") "Scala code runner version:"
58+
else "Scala CLI version:"
59+
expect(version.out.text().contains(expectedLauncherVersion))
60+
expect(version.out.text().contains(s"Scala version (default): ${Constants.defaultScala}"))
61+
}
62+
}
63+
64+
if (TestUtil.isNativeCli) {
65+
test("version command print detailed info run as scala") {
66+
runVersionCommand("scala")
67+
}
68+
69+
test("version command print detailed info run as scala-cli") {
70+
runVersionCommand("scala-cli")
71+
}
72+
}
4273
}

0 commit comments

Comments
 (0)