Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support coursier-downloaded scala wrapper tests on Windows #3325

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,7 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
| def scala3LtsPrefix = "${Scala.scala3LtsPrefix}"
| def scala3Lts = "${Scala.scala3Lts}"
| def scala3NextRc = "${Scala.scala3NextRc}"
| def scala3NextRcAnnounced = "${Scala.scala3NextRcAnnounced}"
| def scala3Next = "${Scala.scala3Next}"
| def scala3NextAnnounced = "${Scala.scala3NextAnnounced}"
| def defaultScala = "${Scala.defaultUser}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package scala.cli.integration

import com.eed3si9n.expecty.Expecty.expect

import java.nio.charset.Charset

import scala.jdk.CollectionConverters.IteratorHasAsScala
import scala.util.Properties

trait CoursierScalaInstallationTestHelper {
def withScalaRunnerWrapper(
root: os.Path,
localCache: os.Path,
localBin: os.Path,
scalaVersion: String
)(f: os.Path => Unit): Unit = {
os.proc(
TestUtil.cs,
"install",
"--cache",
localCache,
"--install-dir",
localBin,
s"scala:$scalaVersion"
).call(cwd = root)
val (launchScalaPath: os.Path, underlyingScriptPath: os.Path) =
if (Properties.isWin) {
val batchWrapperScript: os.Path = localBin / "scala.bat"
val charset = Charset.defaultCharset().toString
val batchWrapperContent = new String(os.read.bytes(batchWrapperScript), charset)
val setCommandLine = batchWrapperContent
.lines()
.iterator()
.asScala
.toList
.find(_.startsWith("SET CMDLINE="))
.getOrElse("")
val scriptPathRegex = """SET CMDLINE="(.*\\bin\\scala\.bat)" %CMD_LINE_ARGS%""".r
val batchScript =
setCommandLine match { case scriptPathRegex(extractedPath) => extractedPath }
val batchScriptPath = os.Path(batchScript)
val oldContent = os.read(batchScriptPath)
val newContent = oldContent.replace(
"call %SCALA_CLI_CMD_WIN%",
s"""set "SCALA_CLI_CMD_WIN=${TestUtil.cliPath}"
|call %SCALA_CLI_CMD_WIN%""".stripMargin
)
expect(newContent != oldContent)
os.write.over(batchScriptPath, newContent)
batchWrapperScript -> batchScriptPath
}
else {
val scalaBinary: os.Path = localBin / "scala"
val fileBytes = os.read.bytes(scalaBinary)
val shebang = new String(fileBytes.takeWhile(_ != '\n'), "UTF-8")
val binaryData = fileBytes.drop(shebang.length + 1)
val execLine = new String(binaryData.takeWhile(_ != '\n'), "UTF-8")
val scriptPathRegex = """exec "([^"]+/bin/scala).*"""".r
val scalaScript = execLine match { case scriptPathRegex(extractedPath) => extractedPath }
val scalaScriptPath = os.Path(scalaScript)
val lineToChange = "eval \"${SCALA_CLI_CMD_BASH[@]}\" \\"
// FIXME: the way the scala script calls the launcher currently ignores the --debug flag
val newContent = os.read(scalaScriptPath).replace(
lineToChange,
s"""SCALA_CLI_CMD_BASH=(\"\\\"${TestUtil.cliPath}\\\"\")
|$lineToChange""".stripMargin
)
os.write.over(scalaScriptPath, newContent)
scalaBinary -> scalaScriptPath
}
val wrapperVersion = os.proc(launchScalaPath, "version", "--cli-version")
.call(cwd = root).out.trim()
val cliVersion = os.proc(TestUtil.cli, "version", "--cli-version")
.call(cwd = root).out.trim()
expect(wrapperVersion == cliVersion)
f(launchScalaPath)
// clean up cs local binaries
val csPrebuiltBinaryDir =
os.Path(underlyingScriptPath.toString().substring(
0,
underlyingScriptPath.toString().indexOf(scalaVersion) + scalaVersion.length
))
System.err.println(s"Cleaning up, trying to remove $csPrebuiltBinaryDir")
try {
os.remove.all(csPrebuiltBinaryDir)

System.err.println(s"Cleanup complete. Removed $csPrebuiltBinaryDir")
}
catch {
case ex: java.nio.file.FileSystemException =>
System.err.println(s"Failed to remove $csPrebuiltBinaryDir: $ex")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import os.CommandResult

import scala.util.Properties

class SipScalaTests extends ScalaCliSuite with SbtTestHelper with MillTestHelper {
class SipScalaTests extends ScalaCliSuite
with SbtTestHelper
with MillTestHelper
with CoursierScalaInstallationTestHelper {
implicit class StringEnrichment(s: String) {
def containsExperimentalWarningOf(featureNameAndType: String): Boolean =
s.contains(s"The $featureNameAndType is experimental") ||
Expand Down Expand Up @@ -833,40 +836,20 @@ class SipScalaTests extends ScalaCliSuite with SbtTestHelper with MillTestHelper
}
}

if (!Properties.isWin) // FIXME: run this test on Windows
test("coursier scala installation works in --offline mode") {
TestInputs.empty.fromRoot { root =>
val localCache = root / "local-cache"
val localBin = root / "local-bin"
val sv = "3.5.0-RC4"
os.proc(
TestUtil.cs,
"install",
"--cache",
localCache,
"--install-dir",
localBin,
s"scala:$sv"
).call(cwd = root)
val scalaBinary: os.Path = localBin / "scala"
val fileBytes = os.read.bytes(scalaBinary)
val shebang = new String(fileBytes.takeWhile(_ != '\n'), "UTF-8")
val binaryData = fileBytes.drop(shebang.length + 1)
val execLine = new String(binaryData.takeWhile(_ != '\n'), "UTF-8")
val scriptPathRegex = """exec "([^"]+/bin/scala).*"""".r
val scalaScript = execLine match { case scriptPathRegex(extractedPath) => extractedPath }
val scalaScriptPath = os.Path(scalaScript)
val lineToChange = "eval \"${SCALA_CLI_CMD_BASH[@]}\" \\"
// FIXME: the way the scala script calls the launcher currently ignores the --debug flag
val newContent = os.read(scalaScriptPath).replace(
lineToChange,
s"""SCALA_CLI_CMD_BASH=(\"\\\"${TestUtil.cliPath}\\\"\")
|$lineToChange""".stripMargin
)
os.write.over(scalaScriptPath, newContent)
test("coursier scala installation works in --offline mode") {
TestInputs.empty.fromRoot { root =>
val localCache = root / "local-cache"
val localBin = root / "local-bin"
val scalaVersion = Constants.scala3NextRcAnnounced
withScalaRunnerWrapper(
root = root,
localCache = localCache,
localBin = localBin,
scalaVersion = scalaVersion
) { launchScalaPath =>
val r =
os.proc(
scalaScript,
launchScalaPath,
"--offline",
"--power",
"--with-compiler",
Expand All @@ -877,18 +860,11 @@ class SipScalaTests extends ScalaCliSuite with SbtTestHelper with MillTestHelper
env = Map("COURSIER_CACHE" -> localCache.toString),
check = false // need to clean up even on failure
)
// clean up cs local binaries
val csPrebuiltBinaryDir =
os.Path(scalaScript.substring(0, scalaScript.indexOf(sv) + sv.length))
try os.remove.all(csPrebuiltBinaryDir)
catch {
case ex: java.nio.file.FileSystemException =>
println(s"Failed to remove $csPrebuiltBinaryDir: $ex")
}
expect(r.exitCode == 0)
expect(r.out.trim() == sv)
expect(r.out.trim() == scalaVersion)
}
}
}

// this check is just to ensure this isn't being run for LTS RC jobs
// should be adjusted when a new LTS line is released
Expand Down
5 changes: 3 additions & 2 deletions project/deps.sc
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ object Scala {
def scala3Lts = s"$scala3LtsPrefix.4" // the LTS version currently used in the build
def scala3NextPrefix = "3.5"
def scala3Next = s"$scala3NextPrefix.2" // the newest/next version of Scala
def scala3NextAnnounced = scala3Next // the newest/next version of Scala that's been announced
def scala3NextRc = "3.6.2-RC3" // the latest RC version of Scala Next
def scala3NextAnnounced = scala3Next // the newest/next version of Scala that's been announced
def scala3NextRc = "3.6.2-RC3" // the latest RC version of Scala Next
def scala3NextRcAnnounced = scala3NextRc // the latest RC version of Scala Next

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