Skip to content

Commit 2f0c7b8

Browse files
authored
Merge pull request #3325 from Gedochao/maintenance/coursier-installation-tests-on-windows
Support `coursier`-downloaded `scala` wrapper tests on Windows
2 parents dfa9f03 + e338513 commit 2f0c7b8

File tree

4 files changed

+116
-44
lines changed

4 files changed

+116
-44
lines changed

build.sc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
10371037
| def scala3LtsPrefix = "${Scala.scala3LtsPrefix}"
10381038
| def scala3Lts = "${Scala.scala3Lts}"
10391039
| def scala3NextRc = "${Scala.scala3NextRc}"
1040+
| def scala3NextRcAnnounced = "${Scala.scala3NextRcAnnounced}"
10401041
| def scala3Next = "${Scala.scala3Next}"
10411042
| def scala3NextAnnounced = "${Scala.scala3NextAnnounced}"
10421043
| def defaultScala = "${Scala.defaultUser}"
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package scala.cli.integration
2+
3+
import com.eed3si9n.expecty.Expecty.expect
4+
5+
import java.nio.charset.Charset
6+
7+
import scala.jdk.CollectionConverters.IteratorHasAsScala
8+
import scala.util.Properties
9+
10+
trait CoursierScalaInstallationTestHelper {
11+
def withScalaRunnerWrapper(
12+
root: os.Path,
13+
localCache: os.Path,
14+
localBin: os.Path,
15+
scalaVersion: String
16+
)(f: os.Path => Unit): Unit = {
17+
os.proc(
18+
TestUtil.cs,
19+
"install",
20+
"--cache",
21+
localCache,
22+
"--install-dir",
23+
localBin,
24+
s"scala:$scalaVersion"
25+
).call(cwd = root)
26+
val (launchScalaPath: os.Path, underlyingScriptPath: os.Path) =
27+
if (Properties.isWin) {
28+
val batchWrapperScript: os.Path = localBin / "scala.bat"
29+
val charset = Charset.defaultCharset().toString
30+
val batchWrapperContent = new String(os.read.bytes(batchWrapperScript), charset)
31+
val setCommandLine = batchWrapperContent
32+
.lines()
33+
.iterator()
34+
.asScala
35+
.toList
36+
.find(_.startsWith("SET CMDLINE="))
37+
.getOrElse("")
38+
val scriptPathRegex = """SET CMDLINE="(.*\\bin\\scala\.bat)" %CMD_LINE_ARGS%""".r
39+
val batchScript =
40+
setCommandLine match { case scriptPathRegex(extractedPath) => extractedPath }
41+
val batchScriptPath = os.Path(batchScript)
42+
val oldContent = os.read(batchScriptPath)
43+
val newContent = oldContent.replace(
44+
"call %SCALA_CLI_CMD_WIN%",
45+
s"""set "SCALA_CLI_CMD_WIN=${TestUtil.cliPath}"
46+
|call %SCALA_CLI_CMD_WIN%""".stripMargin
47+
)
48+
expect(newContent != oldContent)
49+
os.write.over(batchScriptPath, newContent)
50+
batchWrapperScript -> batchScriptPath
51+
}
52+
else {
53+
val scalaBinary: os.Path = localBin / "scala"
54+
val fileBytes = os.read.bytes(scalaBinary)
55+
val shebang = new String(fileBytes.takeWhile(_ != '\n'), "UTF-8")
56+
val binaryData = fileBytes.drop(shebang.length + 1)
57+
val execLine = new String(binaryData.takeWhile(_ != '\n'), "UTF-8")
58+
val scriptPathRegex = """exec "([^"]+/bin/scala).*"""".r
59+
val scalaScript = execLine match { case scriptPathRegex(extractedPath) => extractedPath }
60+
val scalaScriptPath = os.Path(scalaScript)
61+
val lineToChange = "eval \"${SCALA_CLI_CMD_BASH[@]}\" \\"
62+
// FIXME: the way the scala script calls the launcher currently ignores the --debug flag
63+
val newContent = os.read(scalaScriptPath).replace(
64+
lineToChange,
65+
s"""SCALA_CLI_CMD_BASH=(\"\\\"${TestUtil.cliPath}\\\"\")
66+
|$lineToChange""".stripMargin
67+
)
68+
os.write.over(scalaScriptPath, newContent)
69+
scalaBinary -> scalaScriptPath
70+
}
71+
val wrapperVersion = os.proc(launchScalaPath, "version", "--cli-version")
72+
.call(cwd = root).out.trim()
73+
val cliVersion = os.proc(TestUtil.cli, "version", "--cli-version")
74+
.call(cwd = root).out.trim()
75+
expect(wrapperVersion == cliVersion)
76+
f(launchScalaPath)
77+
// clean up cs local binaries
78+
val csPrebuiltBinaryDir =
79+
os.Path(underlyingScriptPath.toString().substring(
80+
0,
81+
underlyingScriptPath.toString().indexOf(scalaVersion) + scalaVersion.length
82+
))
83+
System.err.println(s"Cleaning up, trying to remove $csPrebuiltBinaryDir")
84+
try {
85+
os.remove.all(csPrebuiltBinaryDir)
86+
87+
System.err.println(s"Cleanup complete. Removed $csPrebuiltBinaryDir")
88+
}
89+
catch {
90+
case ex: java.nio.file.FileSystemException =>
91+
System.err.println(s"Failed to remove $csPrebuiltBinaryDir: $ex")
92+
}
93+
}
94+
}

modules/integration/src/test/scala/scala/cli/integration/SipScalaTests.scala

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import os.CommandResult
55

66
import scala.util.Properties
77

8-
class SipScalaTests extends ScalaCliSuite with SbtTestHelper with MillTestHelper {
8+
class SipScalaTests extends ScalaCliSuite
9+
with SbtTestHelper
10+
with MillTestHelper
11+
with CoursierScalaInstallationTestHelper {
912
implicit class StringEnrichment(s: String) {
1013
def containsExperimentalWarningOf(featureNameAndType: String): Boolean =
1114
s.contains(s"The $featureNameAndType is experimental") ||
@@ -833,40 +836,20 @@ class SipScalaTests extends ScalaCliSuite with SbtTestHelper with MillTestHelper
833836
}
834837
}
835838

836-
if (!Properties.isWin) // FIXME: run this test on Windows
837-
test("coursier scala installation works in --offline mode") {
838-
TestInputs.empty.fromRoot { root =>
839-
val localCache = root / "local-cache"
840-
val localBin = root / "local-bin"
841-
val sv = "3.5.0-RC4"
842-
os.proc(
843-
TestUtil.cs,
844-
"install",
845-
"--cache",
846-
localCache,
847-
"--install-dir",
848-
localBin,
849-
s"scala:$sv"
850-
).call(cwd = root)
851-
val scalaBinary: os.Path = localBin / "scala"
852-
val fileBytes = os.read.bytes(scalaBinary)
853-
val shebang = new String(fileBytes.takeWhile(_ != '\n'), "UTF-8")
854-
val binaryData = fileBytes.drop(shebang.length + 1)
855-
val execLine = new String(binaryData.takeWhile(_ != '\n'), "UTF-8")
856-
val scriptPathRegex = """exec "([^"]+/bin/scala).*"""".r
857-
val scalaScript = execLine match { case scriptPathRegex(extractedPath) => extractedPath }
858-
val scalaScriptPath = os.Path(scalaScript)
859-
val lineToChange = "eval \"${SCALA_CLI_CMD_BASH[@]}\" \\"
860-
// FIXME: the way the scala script calls the launcher currently ignores the --debug flag
861-
val newContent = os.read(scalaScriptPath).replace(
862-
lineToChange,
863-
s"""SCALA_CLI_CMD_BASH=(\"\\\"${TestUtil.cliPath}\\\"\")
864-
|$lineToChange""".stripMargin
865-
)
866-
os.write.over(scalaScriptPath, newContent)
839+
test("coursier scala installation works in --offline mode") {
840+
TestInputs.empty.fromRoot { root =>
841+
val localCache = root / "local-cache"
842+
val localBin = root / "local-bin"
843+
val scalaVersion = Constants.scala3NextRcAnnounced
844+
withScalaRunnerWrapper(
845+
root = root,
846+
localCache = localCache,
847+
localBin = localBin,
848+
scalaVersion = scalaVersion
849+
) { launchScalaPath =>
867850
val r =
868851
os.proc(
869-
scalaScript,
852+
launchScalaPath,
870853
"--offline",
871854
"--power",
872855
"--with-compiler",
@@ -877,18 +860,11 @@ class SipScalaTests extends ScalaCliSuite with SbtTestHelper with MillTestHelper
877860
env = Map("COURSIER_CACHE" -> localCache.toString),
878861
check = false // need to clean up even on failure
879862
)
880-
// clean up cs local binaries
881-
val csPrebuiltBinaryDir =
882-
os.Path(scalaScript.substring(0, scalaScript.indexOf(sv) + sv.length))
883-
try os.remove.all(csPrebuiltBinaryDir)
884-
catch {
885-
case ex: java.nio.file.FileSystemException =>
886-
println(s"Failed to remove $csPrebuiltBinaryDir: $ex")
887-
}
888863
expect(r.exitCode == 0)
889-
expect(r.out.trim() == sv)
864+
expect(r.out.trim() == scalaVersion)
890865
}
891866
}
867+
}
892868

893869
// this check is just to ensure this isn't being run for LTS RC jobs
894870
// should be adjusted when a new LTS line is released

project/deps.sc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ object Scala {
1010
def scala3Lts = s"$scala3LtsPrefix.4" // the LTS version currently used in the build
1111
def scala3NextPrefix = "3.5"
1212
def scala3Next = s"$scala3NextPrefix.2" // the newest/next version of Scala
13-
def scala3NextAnnounced = scala3Next // the newest/next version of Scala that's been announced
14-
def scala3NextRc = "3.6.2-RC3" // the latest RC version of Scala Next
13+
def scala3NextAnnounced = scala3Next // the newest/next version of Scala that's been announced
14+
def scala3NextRc = "3.6.2-RC3" // the latest RC version of Scala Next
15+
def scala3NextRcAnnounced = scala3NextRc // the latest RC version of Scala Next
1516

1617
// The Scala version used to build the CLI itself.
1718
def defaultInternal = sys.props.get("scala.version.internal").getOrElse(scala3Lts)

0 commit comments

Comments
 (0)