Skip to content

Commit

Permalink
Merge pull request #14252 from philwalk/fixes-with-workaround-for-13760
Browse files Browse the repository at this point in the history
fix 2 problems plus add workaround for #13760
  • Loading branch information
BarkingBad authored Jan 12, 2022
2 parents 84b26ac + bfee6be commit 0a834ff
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
13 changes: 10 additions & 3 deletions compiler/src/dotty/tools/MainGenericRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ case class Settings(
def withSave: Settings =
this.copy(save = true)

def noSave: Settings =
this.copy(save = false)

def withModeShouldBePossibleRun: Settings =
this.copy(modeShouldBePossibleRun = true)

Expand Down Expand Up @@ -135,6 +138,8 @@ object MainGenericRunner {
)
case "-save" :: tail =>
process(tail, settings.withSave)
case "-nosave" :: tail =>
process(tail, settings.noSave)
case "-with-compiler" :: tail =>
process(tail, settings.withCompiler)
case (o @ javaOption(striped)) :: tail =>
Expand Down Expand Up @@ -207,18 +212,20 @@ object MainGenericRunner {
case ExecuteMode.Script =>
val targetScript = Paths.get(settings.targetScript).toFile
val targetJar = settings.targetScript.replaceAll("[.][^\\/]*$", "")+".jar"
val precompiledJar = Paths.get(targetJar).toFile
val precompiledJar = File(targetJar)
val mainClass = if !precompiledJar.isFile then "" else Jar(targetJar).mainClass.getOrElse("")
val jarIsValid = mainClass.nonEmpty && precompiledJar.lastModified >= targetScript.lastModified
val jarIsValid = mainClass.nonEmpty && precompiledJar.lastModified >= targetScript.lastModified && settings.save
if jarIsValid then
// precompiledJar exists, is newer than targetScript, and manifest defines a mainClass
sys.props("script.path") = targetScript.toPath.toAbsolutePath.normalize.toString
val scalaClasspath = ClasspathFromClassloader(Thread.currentThread().getContextClassLoader).split(classpathSeparator)
val newClasspath = (settings.classPath.flatMap(_.split(classpathSeparator).filter(_.nonEmpty)) ++ removeCompiler(scalaClasspath) :+ ".").map(File(_).toURI.toURL)
if mainClass.nonEmpty then
val res = if mainClass.nonEmpty then
ObjectRunner.runAndCatch(newClasspath :+ File(targetJar).toURI.toURL, mainClass, settings.scriptArgs)
else
Some(IllegalArgumentException(s"No main class defined in manifest in jar: $precompiledJar"))
errorFn("", res)

else
val properArgs =
List("-classpath", settings.classPath.mkString(classpathSeparator)).filter(Function.const(settings.classPath.nonEmpty))
Expand Down
6 changes: 6 additions & 0 deletions compiler/test-resources/scripting/sqlDateError.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!bin/scala -nosave

def main(args: Array[String]): Unit = {
println(new java.sql.Date(100L))
System.err.println("SCALA_OPTS="+Option(System.getenv("SCALA_OPTS")).getOrElse(""))
}
21 changes: 21 additions & 0 deletions compiler/test/dotty/tools/scripting/BashScriptsTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,24 @@ class BashScriptsTests:
if valid then printf(s"\n===> success: classpath begins with %s, as reported by [%s]\n", workingDirectory, scriptFile.getName)
assert(valid, s"script ${scriptFile.absPath} did not report valid java.class.path first entry")

/*
* verify that individual scripts can override -save with -nosave (needed to address #13760).
*/
@Test def sqlDateTest =
val scriptBase = "sqlDateError"
val scriptFile = testFiles.find(_.getName == s"$scriptBase.sc").get
val testJar = testFile(s"$scriptBase.jar") // jar should not be created when scriptFile runs
printf("===> verify '-save' is cancelled by '-nosave' in script hashbang.`\n")
val (validTest, exitCode, stdout, stderr) = bashCommand(s"SCALA_OPTS=-save ${scriptFile.absPath}")
printf("stdout: %s\n", stdout.mkString("\n","\n",""))
if verifyValid(validTest) then
// the script should print '1969-12-31' or '1970-01-01', depending on time zone
// stdout can be polluted with an ANSI color prefix, in some test environments
val valid = stdout.mkString("").matches(""".*\d{4}-\d{2}-\d{2}.*""")
if (!valid) then
stdout.foreach { printf("stdout[%s]\n", _) }
stderr.foreach { printf("stderr[%s]\n", _) }
if valid then printf(s"\n===> success: scripts can override -save via -nosave\n")
assert(valid, s"script ${scriptFile.absPath} reported unexpected value for java.sql.Date ${stdout.mkString("\n")}")
assert(!testJar.exists,s"unexpected, jar file [$testJar] was created")

0 comments on commit 0a834ff

Please sign in to comment.