Basics
Scala CLI is a command line tool that executes a given command on the inputs it’s provided with, using a given configuration to produce a result.
The most important commands are:
- compile compiles your code (excluding tests)
- run runs your code using the provided arguments (it’s also used when no other command is provided)
- test compiles and runs the tests defined in your code
- package packages your code into a jar or other format
- repl / console runs the interactive Scala shell
- fmt formats your code
When Scala CLI is run without any commands, it defaults to the run command, so scala-cli a.scala runs your a.scala file.
Input formats
The scala-cli CLI commands accept input in a number of ways, most notably:
- as source files
- as one or several directories that contain source files
- as URLs pointing to sources
- by processing source code via piping or process substitution
Note that all of these input formats can be used alongside each other.
Source files
Scala CLI accepts the following types of source code:
.scalafiles, containing Scala code.scfiles, containing Scala scripts (see more in Scripts guide).javafiles, containing Java code
The following example shows the simplest input format. First, create a source file:
object Hello {
def main(args: Array[String]): Unit =
println("Hello from Scala")
}
The run it by passing it to scala-cli:
scala-cli Hello.scala
# Hello from Scala
You can also split your code into multiple files:
object Messages {
def hello = "Hello from Scala"
}
object Hello {
def main(args: Array[String]): Unit =
println(Messages.hello)
}
and the run them with scala-cli:
scala-cli Hello.scala Messages.scala
# Hello from Scala
Scala CLI compiles only the provided inputs. For example, if we provide only one of the files above:
scala-cli Hello.scala
compilation will fail. scala-cli compiles only the files it’s given.
While this is very convenient for projects with just a few files, passing many files this way can be cumbersome and error-prone. In the case of larger projects, passing whole directories can help.
Directories
scala-cli accepts whole directories as input.
This is convenient when you have many .scala files, and passing them all one-by-one on the command line isn't practical:
object Messages {
def hello = "Hello from Scala"
}
object Hello {
def main(args: Array[String]): Unit =
println(Messages.hello)
}
In this case, you can run all the source code files in my-app by supplying the directory name:
scala-cli my-app
# Hello from Scala
In our experience, scala-cli . is the most used command; it compiles and runs all sources in the current directory.
Scala CLI process all files within the specified directories and all of its subdirectories.
Scala CLI ignores all subdirectories that start with . like .scala-build or .vscode.
Such directories needs to be explicitly provided as inputs.
URLs
Running unverified code from the internet can be very handy for trusted sources, but it can also be really dangerous, since Scala CLI does not provide any sandboxing at this moment.
Make sure that you trust the code that you are about to run.
scala-cli accepts input via URLs pointing at .scala files.
It downloads their content, and runs them:
scala-cli https://gist.github.com/alexarchambault/f972d941bc4a502d70267cfbbc4d6343/raw/2691c01984c9249936a625a42e29a822a357b0f6/Test.scala
# Hello from Scala GitHub Gist
GitHub Gist
scala-cli accepts input via Github Gist’s urls.
It downloads the gist zip archive and runs it:
scala-cli https://gist.github.com/alexarchambault/7b4ec20c4033690dd750ffd601e540ec
# Hello
Zip archive
scala-cli accepts inputs via a zip archive path.
It unpacks the archive and runs it:
object Hello extends App {
println("Hello")
}
unzip -l hello.zip
# Archive: hello.zip
# Length Date Time Name
# --------- ---------- ----- ----
# 49 12-07-2021 00:06 Hello.scala
# --------- -------
# 49 1 file
scala-cli hello.zip
# Hello
Piping
You can also pipe code to scala-cli for execution:
- scripts
echo 'println("Hello")' | scala-cli _.sc
# Hello - Scala code
echo '@main def hello() = println("Hello")' | scala-cli _.scala
# Hello - Java codeMore details in the Piping guide.
echo 'class Hello { public static void main(String args[]) { System.out.println("Hello"); } }' | scala-cli _.java
# Hello
Scala CLI version
scala-cli can also run another Scala CLI version, which can be helpful to test unreleased Scala CLI functionalities.
Running another Scala CLI version might be slower because it uses JVM-based Scala CLI launcher.
To run another Scala CLI version, specify it with --cli-version before any other argument:
scala-cli --cli-version 0.1.3-51-g4d314eee-SNAPSHOT about
# Scala CLI version 0.1.3-51-g4d314eee-SNAPSHOT
To use the latest Scala CLI nightly build, pass nightly to --cli-version parameter:
scala-cli --cli-version nightly about
# Scala CLI version 0.1.3-8-g431cc15f-SNAPSHOT
Process substitution
Lastly, scala-cli also accepts input via shell process substitution:
scala-cli <(echo 'println("Hello")')
# Hello