Skip to content

Commit

Permalink
Merge pull request #1262 from lwronski/version
Browse files Browse the repository at this point in the history
Add version of Scala to the output of version command
  • Loading branch information
lwronski authored Aug 22, 2022
2 parents 69a4545 + 1775999 commit a4cb009
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import caseapp._
@HelpMessage("Print `scala-cli` version")
final case class VersionOptions(
@Recurse
verbosity: VerbosityOptions = VerbosityOptions()
verbosity: VerbosityOptions = VerbosityOptions(),
@HelpMessage("Show only plain scala-cli version")
@Name("cli")
cliVersion: Boolean = false,
@HelpMessage("Show only plain scala version")
@Name("scala")
scalaVersion: Boolean = false
)
// format: on

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package scala.cli.internal;

import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import java.nio.file.Path;

@TargetClass(className = "scala.cli.internal.Argv0")
@Platforms({Platform.WINDOWS.class})
final class Argv0SubstWindows {

@Substitute
String get(String defaultValue) {
return coursier.jniutils.ModuleFileName.get();
}

}
21 changes: 12 additions & 9 deletions modules/cli/src/main/scala/scala/cli/ScalaCli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@ import scala.util.Properties

object ScalaCli {

if (Properties.isWin && isGraalvmNativeImage)
// have to be initialized before running (new Argv0).get because Argv0SubstWindows uses csjniutils library
// The DLL loaded by LoadWindowsLibrary is statically linke/d in
// the Scala CLI native image, no need to manually load it.
coursier.jniutils.LoadWindowsLibrary.assumeInitialized()

val progName = (new Argv0).get("scala-cli")

private def checkName(name: String) =
progName == name ||
progName.endsWith(s"/$name") ||
progName.endsWith(File.separator + name)
private def checkName(name: String) = {
val baseProgName = if (Properties.isWin) progName.stripSuffix(".exe") else progName
baseProgName == name ||
baseProgName.endsWith(s"/$name") ||
baseProgName.endsWith(File.separator + name)
}

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

Expand Down Expand Up @@ -171,11 +179,6 @@ object ScalaCli {
if (!Properties.isWin && isGraalvmNativeImage)
ignoreSigpipe()

if (Properties.isWin && isGraalvmNativeImage)
// The DLL loaded by LoadWindowsLibrary is statically linked in
// the Scala CLI native image, no need to manually load it.
coursier.jniutils.LoadWindowsLibrary.assumeInitialized()

if (Properties.isWin && System.console() != null && coursier.paths.Util.useJni())
// Enable ANSI output in Windows terminal
coursier.jniutils.WindowsAnsiTerminal.enableAnsiOutput()
Expand Down
4 changes: 2 additions & 2 deletions modules/cli/src/main/scala/scala/cli/ScalaCliCommands.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ScalaCliCommands(
isSipScala: Boolean
) extends CommandsEntryPoint {

lazy val actualDefaultCommand = new Default(help)
lazy val actualDefaultCommand = new Default(help, isSipScala)

// for debugging purposes - allows to run the scala-cli-signing binary from the Scala CLI JVM launcher
private lazy val pgpUseBinaryCommands =
Expand Down Expand Up @@ -64,7 +64,7 @@ class ScalaCliCommands(
Uninstall,
UninstallCompletions,
Update,
Version
new Version(isSipScala = isSipScala)
) ++ (if (pgpUseBinaryCommands) Nil else pgpCommands.allScalaCommands.toSeq) ++
(if (pgpUseBinaryCommands) pgpBinaryCommands.allScalaCommands.toSeq else Nil)

Expand Down
7 changes: 1 addition & 6 deletions modules/cli/src/main/scala/scala/cli/commands/About.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ class About(isSipScala: Boolean) extends ScalaCommand[AboutOptions] {

def run(options: AboutOptions, args: RemainingArgs): Unit = {
CurrentParams.verbosity = options.verbosity.verbosity
val version = Constants.version
val detailedVersionOpt = Constants.detailedVersion.filter(_ != version)
val appName =
if (isSipScala) "Scala command"
else "Scala CLI"
println(s"$appName version $version" + detailedVersionOpt.fold("")(" (" + _ + ")"))
println(Version.versionInfo(isSipScala))
val newestScalaCliVersion = Update.newestScalaCliVersion(options.ghToken.map(_.get()))
val isOutdated = CommandUtils.isOutOfDateVersion(
newestScalaCliVersion,
Expand Down
5 changes: 3 additions & 2 deletions modules/cli/src/main/scala/scala/cli/commands/Default.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import scala.build.internal.Constants
import scala.cli.{CurrentParams, ScalaCliHelp}

class Default(
actualHelp: => RuntimeCommandsHelp
actualHelp: => RuntimeCommandsHelp,
isSipScala: Boolean
) extends ScalaCommand[DefaultOptions] {

private def defaultHelp: String = actualHelp.help(ScalaCliHelp.helpFormat)
Expand All @@ -30,7 +31,7 @@ class Default(
def run(options: DefaultOptions, args: RemainingArgs): Unit = {
CurrentParams.verbosity = options.runOptions.shared.logging.verbosity
if (options.version)
println(Constants.version)
println(Version.versionInfo(isSipScala))
else if (anyArgs)
Run.run(
options.runOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ object InstallHome extends ScalaCommand[InstallHomeOptions] {
val newScalaCliBinPath = os.Path(options.scalaCliBinaryPath, os.pwd)

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

// Backward compatibility - previous versions not have the `--version` parameter
val oldVersion: String =
if (os.isFile(destBinPath)) {
val res = os.proc(destBinPath, "version").call(cwd = os.pwd, check = false)
val res = os.proc(destBinPath, "version", "--cli-version").call(cwd = os.pwd, check = false)
if (res.exitCode == 0)
res.out.text().trim
else
Expand Down
2 changes: 1 addition & 1 deletion modules/cli/src/main/scala/scala/cli/commands/Update.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ object Update extends ScalaCommand[UpdateOptions] {
}

private def getCurrentVersion(scalaCliBinPath: os.Path): String = {
val res = os.proc(scalaCliBinPath, "version").call(cwd = os.pwd, check = false)
val res = os.proc(scalaCliBinPath, "version", "--cli-version").call(cwd = os.pwd, check = false)
if (res.exitCode == 0)
res.out.text().trim
else
Expand Down
20 changes: 18 additions & 2 deletions modules/cli/src/main/scala/scala/cli/commands/Version.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@ import caseapp._
import scala.build.internal.Constants
import scala.cli.CurrentParams

object Version extends ScalaCommand[VersionOptions] {
class Version(isSipScala: Boolean) extends ScalaCommand[VersionOptions] {
override def group = "Miscellaneous"
def run(options: VersionOptions, args: RemainingArgs): Unit = {
CurrentParams.verbosity = options.verbosity.verbosity
println(Constants.version)
if (options.cliVersion)
println(Constants.version)
else if (options.scalaVersion)
println(Constants.defaultScalaVersion)
else
println(Version.versionInfo(isSipScala))
}
}

object Version {
def versionInfo(isSipScala: Boolean) =
val version = Constants.version
val detailedVersionOpt = Constants.detailedVersion.filter(_ != version).fold("")(" (" + _ + ")")
val appName =
if (isSipScala) "Scala code runner"
else "Scala CLI"
s"""$appName version: $version$detailedVersionOpt
|Scala version (default): ${Constants.defaultScalaVersion}""".stripMargin
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,35 @@ class SipScalaTests extends ScalaCliSuite {
noDirectoriesCommandTest("scala-cli-sip")
}
}

def runVersionCommand(binaryName: String) =
TestInputs.empty.fromRoot { root =>
val cliPath = os.Path(TestUtil.cliPath, os.pwd)
val ext = if (Properties.isWin) ".exe" else ""
val newCliPath = root / s"$binaryName$ext"
os.copy(cliPath, newCliPath)

for { versionOption <- Seq("version", "-version", "--version") } {
val version = os.proc(newCliPath, versionOption).call(check = false)
assert(
version.exitCode == 0,
clues(version, version.out.text(), version.err.text(), version.exitCode)
)
val expectedLauncherVersion =
if (binaryName == "scala") "Scala code runner version:"
else "Scala CLI version:"
expect(version.out.text().contains(expectedLauncherVersion))
expect(version.out.text().contains(s"Scala version (default): ${Constants.defaultScala}"))
}
}

if (TestUtil.isNativeCli) {
test("version command print detailed info run as scala") {
runVersionCommand("scala")
}

test("version command print detailed info run as scala-cli") {
runVersionCommand("scala-cli")
}
}
}
20 changes: 20 additions & 0 deletions website/docs/reference/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -1976,6 +1976,26 @@ Interactive mode

Enable actionable diagnostics

## Version options

Available in commands:
- [`version`](./commands.md#version)


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

#### `--cli-version`

Aliases: `--cli`

Show only plain scala-cli version

#### `--scala-version`

Aliases: `--scala`

Show only plain scala version

## Watch options

Available in commands:
Expand Down
1 change: 1 addition & 0 deletions website/docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ Print `scala-cli` version
Accepts options:
- [verbosity](./cli-options.md#verbosity-options)
- [version](./cli-options.md#version-options)
## Hidden commands
Expand Down

0 comments on commit a4cb009

Please sign in to comment.