Skip to content

v1.18.0

Latest

Choose a tag to compare

@Gedochao Gedochao released this 06 Oct 13:07
· 9 commits to main since this release
65126b8

This release is the biggest internal overhaul of Scala CLI in a while. Scala CLI itself is now built with Scala 3 Next, rather than the 3.3 LTS. At the time of this release that means Scala 3.9.0, with the main modules additionally cross-compiled and tested against the Scala 3.10 RCs (currently 3.10.0-RC3).

From now on, Scala CLI will keep being built with the latest Scala Next version, except for the few modules which are locked to an LTS series, as they're consumed by other tools or loaded on the user's class path:

Module Scala version Why
most modules Scala 3 Next (currently 3.9.0) they're only ever used internally, by Scala CLI itself
runner, test-runner 3.3 LTS (with -Yfuture-lazy-vals) they're loaded on the user's class path, so they stay at 3.3 until it reaches its EOL
specification-level 3.3 LTS (with -Yfuture-lazy-vals) it's a dependency for other tools, so it stays at 3.3 until it reaches its EOL
config 3.3 LTS (with -Yfuture-lazy-vals) it's a dependency of other tools (i.e. coursier); it will be bumped to 3.9 LTS in Scala CLI 1.19

The modules which stayed at Scala 3.3 LTS are now compiled with the -Yfuture-lazy-vals compiler option (and an explicit bytecode target: Java 11 for runner and test-runner, Java 17 for the rest). This makes their lazy vals use the newer implementation, which doesn't rely on sun.misc.Unsafe, unlike the legacy one. As a result, they can be used on JDK 24+ without issues, such as the sun.misc.Unsafe deprecation warnings (which will become errors on future JDKs).

//> using jvm 25
object LazyHello:
  lazy val greeting: String = s"Hello from JDK ${Runtime.version.feature}!"
  def main(args: Array[String]): Unit = println(greeting)
scala-cli run jdk-demo
# Hello from JDK 25!

Other noteworthy changes tied to this:

  • The JVM launcher of Scala CLI now requires Java 17 or newer. Support for launching Scala CLI with JDK 11 to 16
    (which used to be handled by downloading JDK 17 and re-launching the CLI with it) has been dropped. Note that this
    only concerns the JVM running Scala CLI itself: the native launchers are not affected, and your code can still be
    compiled for and run with older JVMs (i.e. with --jvm 11 or --jvm 8).
  • The using directives parser now lives in the Scala 3 compiler repository. Scala CLI's own directives-parser
    module has been replaced with the org.scala-lang::scala3-directives-parser artifact, so the //> using directive
    syntax is now parsed by the very same code that's maintained alongside the compiler.
  • The sources have been migrated to newer Scala 3 syntax, where applicable.
  • scala-cli-signing,
    java-class-name and
    scala-js-cli have also been re-built with Scala 3.9 for the purpose
    of this release.

Added by @Gedochao in #4466, #4489 and #4508

Documentation website redesign

The Scala CLI website has been redesigned - now with a refreshed home page, installation page and documentation layout, as well as a better search experience.

Added by @cyp3rius in #4522

fix sub-command improvements

The fix sub-command received a number of improvements in this release.

Deprecated comma separators get removed from using directives

A new built-in rule removes the deprecated comma separators from using directives (it can be turned off with --enable-comma-separators-removal=false).

Directive aliases are retained

fix used to rewrite the directives it moved to project.scala with their canonical names (i.e. //> using dep would become //> using dependency). The aliases are now retained.

--check works for built-in rules, and reports what fails

--check used to only be supported by the scalafix rules. It now works for built-in rules as well, printing a diff of what would have been changed, rather than changing anything.

//> using dep com.lihaoyi::os-lib:0.11.4, com.lihaoyi::pprint:0.9.0
object Main extends App:
  pprint.pprintln(os.pwd.last)
//> using dep com.lihaoyi::upickle:4.1.0
object Utils
scala-cli fix fix-demo --power --check
Running built-in rules...
--- project.scala
+++ <expected fix>
@@ -1,1 +1,2 @@
-
+// Main
+//> using dep com.lihaoyi::os-lib:0.11.4 com.lihaoyi::pprint:0.9.0 com.lihaoyi::upickle:4.1.0
--- Main.scala
+++ <expected fix>
@@ -1,3 +1,2 @@
-//> using dep com.lihaoyi::os-lib:0.11.4, com.lihaoyi::pprint:0.9.0
 object Main extends App:
   pprint.pprintln(os.pwd.last)
--- Utils.scala
+++ <expected fix>
@@ -1,2 +1,1 @@
-//> using dep com.lihaoyi::upickle:4.1.0
 object Utils
built-in rules failed.

Running without --check applies the changes: the commas get removed and the dep alias is kept.

scala-cli fix fix-demo --power
cat fix-demo/project.scala
# // Main
# //> using dep com.lihaoyi::os-lib:0.11.4 com.lihaoyi::pprint:0.9.0 com.lihaoyi::upickle:4.1.0

Pass a custom scalafix version with --scalafix-version, excluded sources are respected

The scalafix version used under the hood can now be overridden with the --scalafix-version option. Additionally, scalafix rules are now only run on the project's sources, so they respect the //> using exclude directive (rather than scanning the whole directory).

rules = [
  DisableSyntax
]
DisableSyntax.noVars = true
//> using exclude legacy
object Counter:
  val count = 0
object Legacy:
  var count = 0 // excluded, so not linted
scala-cli fix lint-demo --power --enable-built-in=false --scalafix-version 0.14.8 --check

Added by @warcholjakub in #4486, #4491, #4492, #4501, #4503 and #4504

Better support for virtual Java inputs

Scala CLI uses java-class-name to figure out the name of the public class of Java sources which don't come from a file (and so don't have a file name): Java snippets passed with --java-snippet, Java sources piped through standard input and Java code blocks in Markdown inputs.
Bumping it to 0.2.0 fixes a number of issues with those:

  • public enums and records with primitive components used to crash java-class-name;
  • package-private classes used to be treated as public in sources with a package clause;
  • JEP 512 compact source files (with unnamed top-level main methods) are now
    better supported.
echo 'public enum Color { RED, GREEN; public static void main(String[] args) { System.out.println(GREEN); } }' | scala-cli run _.java
# GREEN
scala-cli run --java-snippet 'public record Point(int x, int y) { public static void main(String[] args) { System.out.println(new Point(1, 2)); } }'
# Point[x=1, y=2]
scala-cli run --java-snippet 'package demo;
class Helper { static String greet() { return "Hello from a package-private helper!"; } }
public class Main { public static void main(String[] args) { System.out.println(Helper.greet()); } }'
# Hello from a package-private helper!
scala-cli run --jvm 25 --java-snippet 'void main() { System.out.println("Hello from a JEP 512 compact source snippet!"); }'
# Hello from a JEP 512 compact source snippet!

Fixed by @Gedochao in #4521

Features

Fixes

Compatibility

Documentation

Build and internal changes

Updates

New Contributors

Full Changelog: v1.17.1...v1.18.0