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:
.scala
files, containing Scala code.sc
files, containing Scala scripts (see more in Scripts guide).java
files, 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