Skip to content

Commit f7ab683

Browse files
Bundle scala cli in scala command (#20351)
fixes #20098 Proposed changes to zip/targz archive: - in the `/bin` directory store an extra launcher for Scala CLI (either JAR, or native per platform). - `/bin/scala[.bat]` is modified to invoke Scala CLI stored in `/bin` - new `/maven2` directory, which stores all the Jars and POM files necessary (in maven repo style) for scala-cli to invoke scala compiler offline (using the `-r` launcher option). - CHOICE: either replace jar files in `/lib` by aliases to the corresponding jar in `/maven2`, OR delete `/lib` and update references from scripts. (Looks like symlinks are not portable, so probably we should encode the classpath in a file, or adjust slightly how we build the toolchain) - add platform specific suffixes to artefacts: - e.g. `scala-3.5.0-x86_64-pc-linux.tar.gz` (for the artefact that bundles the x64 linux launcher) --------- Co-authored-by: Hamza REMMAL <[email protected]>
1 parent dea3d10 commit f7ab683

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1423
-341
lines changed

Diff for: .github/workflows/ci.yaml

+10-4
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ jobs:
141141

142142
- name: Cmd Tests
143143
run: |
144-
./project/scripts/sbt ";dist/pack; scala3-bootstrapped/compile; scala3-bootstrapped/test ;sbt-test/scripted scala2-compat/*; scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test"
144+
./project/scripts/buildScalaBinary
145+
./project/scripts/sbt ";scala3-bootstrapped/compile ;scala3-bootstrapped/test ;sbt-test/scripted scala2-compat/* ;scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test"
145146
./project/scripts/cmdTests
146147
./project/scripts/bootstrappedOnlyCmdTests
147148
@@ -230,7 +231,7 @@ jobs:
230231
shell: cmd
231232

232233
- name: build binary
233-
run: sbt "dist/pack" & bash -version
234+
run: sbt "dist-win-x86_64/pack" & bash -version
234235
shell: cmd
235236

236237
- name: cygwin tests
@@ -269,8 +270,12 @@ jobs:
269270
- name: Git Checkout
270271
uses: actions/checkout@v4
271272

273+
- name: build binary
274+
run: sbt "dist-win-x86_64/pack"
275+
shell: cmd
276+
272277
- name: Test
273-
run: sbt ";dist/pack ;scala3-bootstrapped/compile ;scala3-bootstrapped/test"
278+
run: sbt ";scala3-bootstrapped/compile ;scala3-bootstrapped/test"
274279
shell: cmd
275280

276281
- name: Scala.js Test
@@ -596,7 +601,8 @@ jobs:
596601

597602
- name: Test
598603
run: |
599-
./project/scripts/sbt ";dist/pack ;scala3-bootstrapped/compile ;scala3-bootstrapped/test ;sbt-test/scripted scala2-compat/*"
604+
./project/scripts/buildScalaBinary
605+
./project/scripts/sbt ";scala3-bootstrapped/compile ;scala3-bootstrapped/test ;sbt-test/scripted scala2-compat/*"
600606
./project/scripts/cmdTests
601607
./project/scripts/bootstrappedOnlyCmdTests
602608

Diff for: .github/workflows/launchers.yml

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Test CLI Launchers on all the platforms
2+
on:
3+
pull_request:
4+
workflow_dispatch:
5+
6+
jobs:
7+
linux-x86_64:
8+
name: Deploy and Test on Linux x64 architecture
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
- name: Set up JDK 17
13+
uses: actions/setup-java@v4
14+
with:
15+
java-version: '17'
16+
distribution: 'temurin'
17+
cache: 'sbt'
18+
- name: Build and test launcher command
19+
run: ./project/scripts/native-integration/bashTests
20+
env:
21+
LAUNCHER_EXPECTED_PROJECT: "dist-linux-x86_64"
22+
23+
linux-aarch64:
24+
name: Deploy and Test on Linux ARM64 architecture
25+
runs-on: macos-latest
26+
if: ${{ false }}
27+
steps:
28+
- uses: actions/checkout@v4
29+
- name: Set up JDK 17
30+
uses: actions/setup-java@v4
31+
with:
32+
java-version: '17'
33+
distribution: 'temurin'
34+
cache: 'sbt'
35+
# https://github.com/actions/runner-images/issues/9369
36+
- name: Install sbt
37+
run: brew install sbt
38+
- name: Build and test launcher command
39+
run: ./project/scripts/native-integration/bashTests
40+
env:
41+
LAUNCHER_EXPECTED_PROJECT: "dist-linux-aarch64"
42+
43+
mac-x86_64:
44+
name: Deploy and Test on Mac x64 architecture
45+
runs-on: macos-13
46+
steps:
47+
- uses: actions/checkout@v4
48+
- name: Set up JDK 17
49+
uses: actions/setup-java@v4
50+
with:
51+
java-version: '17'
52+
distribution: 'temurin'
53+
cache: 'sbt'
54+
# https://github.com/actions/runner-images/issues/9369
55+
- name: Install sbt
56+
run: brew install sbt
57+
- name: Build and test launcher command
58+
run: ./project/scripts/native-integration/bashTests
59+
env:
60+
LAUNCHER_EXPECTED_PROJECT: "dist-mac-x86_64"
61+
62+
mac-aarch64:
63+
name: Deploy and Test on Mac ARM64 architecture
64+
runs-on: macos-latest
65+
steps:
66+
- uses: actions/checkout@v4
67+
- name: Set up JDK 17
68+
uses: actions/setup-java@v4
69+
with:
70+
java-version: '17'
71+
distribution: 'temurin'
72+
cache: 'sbt'
73+
# https://github.com/actions/runner-images/issues/9369
74+
- name: Install sbt
75+
run: brew install sbt
76+
- name: Build and test launcher command
77+
run: ./project/scripts/native-integration/bashTests
78+
env:
79+
LAUNCHER_EXPECTED_PROJECT: "dist-mac-aarch64"
80+
81+
win-x86_64:
82+
name: Deploy and Test on Windows x64 architecture
83+
runs-on: windows-latest
84+
steps:
85+
- uses: actions/checkout@v4
86+
- name: Set up JDK 17
87+
uses: actions/setup-java@v4
88+
with:
89+
java-version: '17'
90+
distribution: 'temurin'
91+
cache: 'sbt'
92+
- name: Build the launcher command
93+
run: sbt "dist-win-x86_64/pack"
94+
- name: Run the launcher command tests
95+
run: './project/scripts/native-integration/winTests.bat'
96+
shell: cmd

Diff for: bin/common

+6-3
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@ target="$1"
99

1010
shift # Mutates $@ by deleting the first element ($1)
1111

12+
# set the $DIST_PROJECT and $DIST_DIR variables
13+
source "$ROOT/bin/common-platform"
14+
1215
# Marker file used to obtain the date of latest call to sbt-back
13-
version="$ROOT/dist/target/pack/VERSION"
16+
version="$ROOT/$DIST_DIR/target/pack/VERSION"
1417

1518
# Create the target if absent or if file changed in ROOT/compiler
1619
new_files="$(find "$ROOT/compiler" \( -iname "*.scala" -o -iname "*.java" \) -newer "$version" 2> /dev/null)"
1720

1821
if [ ! -f "$version" ] || [ ! -z "$new_files" ]; then
1922
echo "Building Dotty..."
20-
(cd $ROOT && sbt "dist/pack")
23+
(cd $ROOT && sbt "$DIST_PROJECT/pack")
2124
fi
2225

23-
"$target" "$@"
26+
"$ROOT/$DIST_DIR/target/pack/bin/$target" "$@"

Diff for: bin/common-platform

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env bash
2+
3+
unset cygwin mingw msys darwin
4+
5+
# COLUMNS is used together with command line option '-pageWidth'.
6+
if command -v tput >/dev/null 2>&1; then
7+
export COLUMNS="$(tput -Tdumb cols)"
8+
fi
9+
10+
case "`uname`" in
11+
CYGWIN*) cygwin=true
12+
;;
13+
MINGW*) mingw=true
14+
;;
15+
MSYS*) msys=true
16+
;;
17+
Darwin*) darwin=true
18+
;;
19+
esac
20+
21+
unset DIST_PROJECT DIST_DIR
22+
23+
if [[ ${cygwin-} || ${mingw-} || ${msys-} ]]; then
24+
DIST_PROJECT="dist-win-x86_64"
25+
DIST_DIR="dist/win-x86_64"
26+
else
27+
# OS and arch logic taken from https://github.com/VirtusLab/scala-cli/blob/main/scala-cli.sh
28+
unset arch ARCH_NORM
29+
arch=$(uname -m)
30+
if [[ "$arch" == "aarch64" ]] || [[ "$arch" == "x86_64" ]]; then
31+
ARCH_NORM="$arch"
32+
elif [[ "$arch" == "amd64" ]]; then
33+
ARCH_NORM="x86_64"
34+
elif [[ "$arch" == "arm64" ]]; then
35+
ARCH_NORM="aarch64"
36+
else
37+
ARCH_NORM="unknown"
38+
fi
39+
40+
if [ "$(expr substr $(uname -s) 1 5 2>/dev/null)" == "Linux" ]; then
41+
if [[ "$ARCH_NORM" == "unknown" ]]; then
42+
echo >&2 "unknown Linux CPU architecture, defaulting to JVM launcher"
43+
DIST_PROJECT="dist"
44+
DIST_DIR="dist"
45+
else
46+
DIST_PROJECT="dist-linux-$ARCH_NORM"
47+
DIST_DIR="dist/linux-$ARCH_NORM"
48+
fi
49+
elif [ "$(uname)" == "Darwin" ]; then
50+
if [[ "$ARCH_NORM" == "unknown" ]]; then
51+
echo >&2 "unknown Darwin CPU architecture, defaulting to JVM launcher"
52+
DIST_PROJECT="dist"
53+
DIST_DIR="dist"
54+
else
55+
DIST_PROJECT="dist-mac-$ARCH_NORM"
56+
DIST_DIR="dist/mac-$ARCH_NORM"
57+
fi
58+
else
59+
echo >&2 "unknown OS, defaulting to JVM launcher"
60+
DIST_PROJECT="dist"
61+
DIST_DIR="dist"
62+
fi
63+
fi

Diff for: bin/scala

+34-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,37 @@
22

33
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >& /dev/null && pwd)/.."
44

5-
"$ROOT/bin/common" "$ROOT/dist/target/pack/bin/scala" "$@"
5+
scala_args() {
6+
7+
declare -a CLI_ARGS
8+
declare -a SCRIPT_ARGS
9+
declare DISABLE_BLOOP=1
10+
11+
while (( "$#" )); do
12+
case "$1" in
13+
"--")
14+
shift
15+
SCRIPT_ARGS+=("--")
16+
SCRIPT_ARGS+=("$@")
17+
break
18+
;;
19+
"clean" | "version" | "--version" | "-version" | "help" | "--help" | "-help")
20+
CLI_ARGS+=("$1")
21+
DISABLE_BLOOP=0 # clean command should not add --offline --server=false
22+
shift
23+
;;
24+
*)
25+
CLI_ARGS+=("$1")
26+
shift
27+
;;
28+
esac
29+
done
30+
31+
if [ $DISABLE_BLOOP -eq 1 ]; then
32+
CLI_ARGS+=("--offline" "--server=false")
33+
fi
34+
35+
echo "--power ${CLI_ARGS[@]} ${SCRIPT_ARGS[@]}"
36+
}
37+
38+
"$ROOT/bin/common" "scala" $(scala_args "$@")

Diff for: bin/scalac

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >& /dev/null && pwd)/.."
44

5-
"$ROOT/bin/common" "$ROOT/dist/target/pack/bin/scalac" "$@"
5+
"$ROOT/bin/common" "scalac" "$@"

Diff for: bin/scaladoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >& /dev/null && pwd)/.."
44

5-
"$ROOT/bin/common" "$ROOT/dist/target/pack/bin/scaladoc" "$@"
5+
"$ROOT/bin/common" "scaladoc" "$@"

Diff for: bin/test/TestScripts.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class TestScripts {
5757
s"bin/scalac script did not run properly. Output:$lineSep$dotcOutput"
5858
)
5959

60-
val (retDotr, dotrOutput) = executeScript("./bin/scala HelloWorld")
60+
val (retDotr, dotrOutput) = executeScript("./bin/scala -M HelloWorld")
6161
assert(
6262
retDotr == 0 && dotrOutput == "hello world\n",
6363
s"Running hello world exited with status: $retDotr and output: $dotrOutput"

Diff for: build.sbt

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ val `scaladoc-js-main` = Build.`scaladoc-js-main`
2828
val `scaladoc-js-contributors` = Build.`scaladoc-js-contributors`
2929
val `scala3-bench-run` = Build.`scala3-bench-run`
3030
val dist = Build.dist
31+
val `dist-mac-x86_64` = Build.`dist-mac-x86_64`
32+
val `dist-mac-aarch64` = Build.`dist-mac-aarch64`
33+
val `dist-win-x86_64` = Build.`dist-win-x86_64`
34+
val `dist-linux-x86_64` = Build.`dist-linux-x86_64`
35+
val `dist-linux-aarch64` = Build.`dist-linux-aarch64`
3136
val `community-build` = Build.`community-build`
3237
val `sbt-community-build` = Build.`sbt-community-build`
3338
val `scala3-presentation-compiler` = Build.`scala3-presentation-compiler`

Diff for: compiler/src/dotty/tools/MainGenericRunner.scala

+16
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,22 @@ object MainGenericRunner {
266266
run(settings.withExecuteMode(ExecuteMode.Run))
267267
else
268268
run(settings.withExecuteMode(ExecuteMode.Repl))
269+
end run
270+
271+
val ranByCoursierBootstrap =
272+
sys.props.isDefinedAt("coursier.mainJar")
273+
|| sys.props.get("bootstrap.mainClass").contains("dotty.tools.MainGenericRunner")
274+
275+
val silenced = sys.props.get("scala.use_legacy_launcher") == Some("true")
276+
277+
if !silenced then
278+
Console.err.println(s"[warning] MainGenericRunner class is deprecated since Scala 3.5.0, and Scala CLI features will not work.")
279+
Console.err.println(s"[warning] Please be sure to update to the Scala CLI launcher to use the new features.")
280+
if ranByCoursierBootstrap then
281+
Console.err.println(s"[warning] It appears that your Coursier-based Scala installation is misconfigured.")
282+
Console.err.println(s"[warning] To update to the new Scala CLI runner, please update (coursier, cs) commands first before re-installing scala.")
283+
Console.err.println(s"[warning] Check the Scala 3.5.0 release notes to troubleshoot your installation.")
284+
269285

270286
run(settings) match
271287
case Some(ex: (StringDriverException | ScriptingException)) => errorFn(ex.getMessage)

Diff for: compiler/test-coursier/dotty/tools/coursier/CoursierScalaTests.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ object CoursierScalaTests:
166166
case Nil => args
167167
case _ => "--" +: args
168168
val newJOpts = jOpts.map(s => s"--java-opt ${s.stripPrefix("-J")}").mkString(" ")
169-
execCmd("./cs", (s"""launch "org.scala-lang:scala3-compiler_3:${sys.env("DOTTY_BOOTSTRAPPED_VERSION")}" $newJOpts --main-class "$entry" --property "scala.usejavacp=true"""" +: newOptions)*)._2
169+
execCmd("./cs", (s"""launch "org.scala-lang:scala3-compiler_3:${sys.env("DOTTY_BOOTSTRAPPED_VERSION")}" $newJOpts --main-class "$entry" --property "scala.usejavacp=true" --property "scala.use_legacy_launcher=true"""" +: newOptions)*)._2
170170

171171
/** Get coursier script */
172172
@BeforeClass def setup(): Unit =

Diff for: compiler/test-resources/scripting/argfileClasspath.sc

-9
This file was deleted.

Diff for: compiler/test-resources/scripting/classpathReport.sc renamed to compiler/test-resources/scripting/classpathReport_scalacli.sc

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#!bin/scala -classpath 'dist/target/pack/lib/*'
2-
1+
#!/usr/bin/env bin/scala
2+
// This file is a Scala CLI script.
33
import java.nio.file.Paths
44

5-
def main(args: Array[String]): Unit =
5+
// def main(args: Array[String]): Unit = // MIGRATION: Scala CLI expects `*.sc` files to be straight-line code
66
val cwd = Paths.get(".").toAbsolutePath.normalize.toString.norm
77
printf("cwd: %s\n", cwd)
88
printf("classpath: %s\n", sys.props("java.class.path").norm)

Diff for: compiler/test-resources/scripting/cpArgumentsFile.txt

-1
This file was deleted.

Diff for: compiler/test-resources/scripting/envtest.sc

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
// this file is intended to be ran as an argument to the dotty.tools.scripting.ScriptingDriver class
2+
13
def main(args: Array[String]): Unit =
24
println("Hello " + util.Properties.propOrNull("key"))
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file is a Scala CLI script.
2+
3+
println("Hello " + util.Properties.propOrNull("key"))

Diff for: compiler/test-resources/scripting/hashBang.sc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env scala
1+
#!/usr/bin/env fake-program-to-test-hashbang-removal
22
# comment
33
STUFF=nada
44
!#

Diff for: compiler/test-resources/scripting/hashBang.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#!/usr/bin/env scala
1+
#!/usr/bin/env fake-program-to-test-hashbang-removal
22
# comment
33
STUFF=nada
44
!#
5-
5+
// everything above this point should be ignored by the compiler
66
def main(args: Array[String]): Unit =
77
System.err.printf("mainClassFromStack: %s\n",mainFromStack)
88
assert(mainFromStack.contains("hashBang"),s"fromStack[$mainFromStack]")

Diff for: compiler/test-resources/scripting/scriptName.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env scala
1+
// this file is intended to be ran as an argument to the dotty.tools.scripting.ScriptingDriver class
22

33
def main(args: Array[String]): Unit =
44
val name = Option(sys.props("script.name")) match {

Diff for: compiler/test-resources/scripting/scriptPath.sc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!dist/target/pack/bin/scala
1+
// this file is intended to be ran as an argument to the dotty.tools.scripting.ScriptingDriver class
22

33
def main(args: Array[String]): Unit =
44
args.zipWithIndex.foreach { case (arg,i) => printf("arg %d: [%s]\n",i,arg) }

0 commit comments

Comments
 (0)