Format
Scala CLI supports formatting your code using Scalafmt:
scala-cli fmt
Under the hood, scala-cli
downloads and runs Scalafmt on your code.
If you’re setting up a continuous integration (CI) server, scala-cli
also has you covered.
You can check formatting correctness using a --check
flag:
scala-cli fmt --check
Scalafmt version and dialect
Scala CLI fmt
command supports passing the scalafmt
version and dialect directly from the command line, using the --scalafmt-dialect
and --scalafmt-version
options respectively:
scala-cli fmt --scalafmt-dialect scala3 --scalafmt-version 3.5.8
You can skip passing either of those, which will make Scala CLI infer a default value:
- If a
.scalafmt.conf
file is present in the workspace and it has the field defined, the value will be read from there, unless explicitly specified with Scala CLI options. - Otherwise, the default
scalafmt
version will be the latest one used by your Scala CLI version (so it is subject to change when updating Scala CLI). The default dialect will be inferred based on the Scala version (defined explicitly by-S
option, or default version if the option is not passed).
It is possible to pass the configuration as a string directly from the command line, using --scalafmt-conf-str
option. If the configuration is passed this way, Scala CLI will behave exactly the same as if it found the specified configuration in the .scalafmt.conf
file in the workspace.
Example 1
version = "3.5.8"
runner.dialect = scala212
scala-cli fmt --scalafmt-dialect scala213
For the setup above, fmt
will use:
version="3.5.8"
from the filedialect=scala213
, because passed--scalafmt-dialect
option overrides dialect found in the file
Example 2
version = "2.7.5"
scala-cli fmt --scalafmt-version 3.5.8
For the setup above, fmt
will use:
version="3.5.8"
, because passed--scalafmt-version
option overrides version from the filedialect=scala3
, because dialect is neither passed as an option nor is it present in the configuration file, so it is inferred based on the Scala version; the Scala version wasn't explicitly specified in the command either, so it falls back to the default Scala version - the latest one, thus the resulting dialect isscala3
.
Scalafmt options
It is possible to pass native scalafmt
options with the -F
(short for --scalafmt-arg
), for example:
scala-cli fmt -F --version
scalafmt 3.5.8
For the available options please refer to scalafmt
help, which can be viewed with the --scalafmt-help
option (which
is just an alias for -F --help
):
scala-cli fmt --scalafmt-help
scalafmt 3.5.8
Usage: scalafmt [options] [<file>...]
-h, --help prints this usage text
-v, --version print version
(...)
Excluding sources
Because of the way Scala CLI invokes scalafmt
under the hood, sources are always being passed to it explicitly. This
in turn means that regardless of how the sources were passed, scalafmt
exclusion paths (the project.excludePaths
)
would be ignored. In order to prevent that from happening, the --respect-project-filters
option is set to true
by
default.
version = "3.5.8"
runner.dialect = scala3
project {
includePaths = [
"glob:**.scala",
"regex:.*\\.sc"
]
excludePaths = [
"glob:**/should/not/format/**.scala"
]
}
scala-cli fmt . --check
All files are formatted with scalafmt :)
You can explicitly set it to false if you want to disregard any filters configured in the project.excludePaths
setting
in your .scalafmt.conf
for any reason.
scala-cli fmt . --check --respect-project-filters=false
--- a/.../should/not/format/ShouldNotFormat.scala
+++ b/.../should/not/format/ShouldNotFormat.scala
@@ -1,3 +1,3 @@
class ShouldNotFormat {
- println()
+ println()
}
How .scalafmt.conf
file is generated
The Scala CLI fmt
command runs scalafmt
under the hood, which normally requires .scalafmt.conf
configuration file with explicitly specified version and dialect fields. The way it is handled by Scala CLI is as follows:
At the beginning fmt
looks for the configuration inside the file specified in the --scalafmt-conf
option. If the option is not passed or the file doesn't exist, fmt
looks for the existing configuration file inside current workspace directory. If the file is still not found, fmt
looks for it inside git root directory. There are 3 possible cases:
- Configuration file with the specified version and dialect is found.
- Configuration file is found, but it doesn't have specified version or dialect.
- Configuration file is not found.
- In the first case
fmt
uses the found.scalafmt.conf
file to runscalafmt
. - In the second case
fmt
creates a.scalafmt.conf
file inside the.scala-build
directory. Content of the previously found file is copied into the newly created file, missing parameters are inferred and written into the same file. Created file is used to runscalafmt
. - In the third case
fmt
creates a.scalafmt.conf
file inside the.scala-build
directory, writes inferred version and dialect into it and uses it to runscalafmt
.
If the --save-scalafmt-conf
option is passed, then fmt
command behaves as follows:
- In the first case
fmt
uses the found.scalafmt.conf
file to runscalafmt
. - In the second case
fmt
infers missing parameters, writes them directly into the previously found file and then uses this file to runscalafmt
. - In the third case
fmt
creates a.scalafmt.conf
file in the current workspace directory, writes inferred version and dialect into it and uses it to runscalafmt
.
If the configuration is passed in the --scalafmt-conf-str
option, Scala CLI will behave exactly the same as if it found the specified configuration in a .scalafmt.conf
file in the workspace.