Skip to content

Commit 9ec5d3d

Browse files
committed
Extract coursier scala installation setup & cleanup for tests to a helper trait for reuse
1 parent c89cbba commit 9ec5d3d

File tree

2 files changed

+122
-89
lines changed

2 files changed

+122
-89
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
// Failed to remove D:\a: java.nio.file.AccessDeniedException: D:\a\scala-cli\scala-cli\.git\objects\pack\pack-a6c37a2df98bda5377d5c462f2f14519cb5c2ece.idx
92+
System.err.println(s"Failed to remove $csPrebuiltBinaryDir: $ex")
93+
}
94+
}
95+
}

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

Lines changed: 27 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ package scala.cli.integration
33
import com.eed3si9n.expecty.Expecty.expect
44
import os.CommandResult
55

6-
import java.nio.charset.Charset
7-
import scala.jdk.CollectionConverters.IteratorHasAsScala
86
import scala.util.Properties
97

10-
class SipScalaTests extends ScalaCliSuite with SbtTestHelper with MillTestHelper {
8+
class SipScalaTests extends ScalaCliSuite
9+
with SbtTestHelper
10+
with MillTestHelper
11+
with CoursierScalaInstallationTestHelper {
1112
implicit class StringEnrichment(s: String) {
1213
def containsExperimentalWarningOf(featureNameAndType: String): Boolean =
1314
s.contains(s"The $featureNameAndType is experimental") ||
@@ -837,94 +838,31 @@ class SipScalaTests extends ScalaCliSuite with SbtTestHelper with MillTestHelper
837838

838839
test("coursier scala installation works in --offline mode") {
839840
TestInputs.empty.fromRoot { root =>
840-
val localCache = root / "local-cache"
841-
val localBin = root / "local-bin"
842-
val sv = Constants.scala3NextAnnounced
843-
os.proc(
844-
TestUtil.cs,
845-
"install",
846-
"--cache",
847-
localCache,
848-
"--install-dir",
849-
localBin,
850-
s"scala:$sv"
851-
).call(cwd = root)
852-
val launchScalaPath: os.Path =
853-
if (Properties.isWin) {
854-
val batchWrapperScript: os.Path = localBin / "scala.bat"
855-
val charset = Charset.defaultCharset().toString
856-
val batchWrapperContent = new String(os.read.bytes(batchWrapperScript), charset)
857-
val setCommandLine = batchWrapperContent
858-
.lines()
859-
.iterator()
860-
.asScala
861-
.toList
862-
.find(_.startsWith("SET CMDLINE="))
863-
.getOrElse("")
864-
val scriptPathRegex = """SET CMDLINE="(.*\\bin\\scala\.bat)" %CMD_LINE_ARGS%""".r
865-
val batchScript =
866-
setCommandLine match { case scriptPathRegex(extractedPath) => extractedPath }
867-
val batchScriptPath = os.Path(batchScript)
868-
val oldContent = os.read(batchScriptPath)
869-
val newContent = oldContent.replace(
870-
"call %SCALA_CLI_CMD_WIN%",
871-
s"""set "SCALA_CLI_CMD_WIN=${TestUtil.cliPath}"
872-
|call %SCALA_CLI_CMD_WIN%""".stripMargin
873-
)
874-
expect(newContent != oldContent)
875-
os.write.over(batchScriptPath, newContent)
876-
batchWrapperScript
877-
}
878-
else {
879-
val scalaBinary: os.Path = localBin / "scala"
880-
val fileBytes = os.read.bytes(scalaBinary)
881-
val shebang = new String(fileBytes.takeWhile(_ != '\n'), "UTF-8")
882-
val binaryData = fileBytes.drop(shebang.length + 1)
883-
val execLine = new String(binaryData.takeWhile(_ != '\n'), "UTF-8")
884-
val scriptPathRegex = """exec "([^"]+/bin/scala).*"""".r
885-
val scalaScript = execLine match { case scriptPathRegex(extractedPath) => extractedPath }
886-
val scalaScriptPath = os.Path(scalaScript)
887-
val lineToChange = "eval \"${SCALA_CLI_CMD_BASH[@]}\" \\"
888-
// FIXME: the way the scala script calls the launcher currently ignores the --debug flag
889-
val newContent = os.read(scalaScriptPath).replace(
890-
lineToChange,
891-
s"""SCALA_CLI_CMD_BASH=(\"\\\"${TestUtil.cliPath}\\\"\")
892-
|$lineToChange""".stripMargin
841+
val localCache = root / "local-cache"
842+
val localBin = root / "local-bin"
843+
val scalaVersion = Constants.scala3NextAnnounced
844+
withScalaRunnerWrapper(
845+
root = root,
846+
localCache = localCache,
847+
localBin = localBin,
848+
scalaVersion = scalaVersion
849+
) { launchScalaPath =>
850+
val r =
851+
os.proc(
852+
launchScalaPath,
853+
"--offline",
854+
"--power",
855+
"--with-compiler",
856+
"-e",
857+
"println(dotty.tools.dotc.config.Properties.versionNumberString)"
858+
).call(
859+
cwd = root,
860+
env = Map("COURSIER_CACHE" -> localCache.toString),
861+
check = false // need to clean up even on failure
893862
)
894-
os.write.over(scalaScriptPath, newContent)
895-
scalaBinary
896-
}
897-
val wrapperVersion = os.proc(launchScalaPath, "version", "--cli-version")
898-
.call(cwd = root).out.trim()
899-
val cliVersion = os.proc(TestUtil.cli, "version", "--cli-version")
900-
.call(cwd = root).out.trim()
901-
expect(wrapperVersion == cliVersion)
902-
val r =
903-
os.proc(
904-
launchScalaPath,
905-
"--offline",
906-
"--power",
907-
"--with-compiler",
908-
"-e",
909-
"println(dotty.tools.dotc.config.Properties.versionNumberString)"
910-
).call(
911-
cwd = root,
912-
env = Map("COURSIER_CACHE" -> localCache.toString),
913-
check = false // need to clean up even on failure
914-
)
915-
// clean up cs local binaries
916-
val csPrebuiltBinaryDir =
917-
os.Path(launchScalaPath.toString().substring(
918-
0,
919-
launchScalaPath.toString().indexOf(sv) + sv.length
920-
))
921-
try os.remove.all(csPrebuiltBinaryDir)
922-
catch {
923-
case ex: java.nio.file.FileSystemException =>
924-
println(s"Failed to remove $csPrebuiltBinaryDir: $ex")
863+
expect(r.exitCode == 0)
864+
expect(r.out.trim() == scalaVersion)
925865
}
926-
expect(r.exitCode == 0)
927-
expect(r.out.trim() == sv)
928866
}
929867
}
930868

0 commit comments

Comments
 (0)