From bfee6befffe3118c7ca7674030561cd29f613a35 Mon Sep 17 00:00:00 2001 From: Phil Date: Tue, 11 Jan 2022 14:49:43 -0700 Subject: [PATCH] fix 2 problems plus add workaround for #13760 --- .../src/dotty/tools/MainGenericRunner.scala | 13 +++++++++--- .../test-resources/scripting/sqlDateError.sc | 6 ++++++ .../tools/scripting/BashScriptsTests.scala | 21 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100755 compiler/test-resources/scripting/sqlDateError.sc diff --git a/compiler/src/dotty/tools/MainGenericRunner.scala b/compiler/src/dotty/tools/MainGenericRunner.scala index fbc947ce175a..65ee672f0342 100644 --- a/compiler/src/dotty/tools/MainGenericRunner.scala +++ b/compiler/src/dotty/tools/MainGenericRunner.scala @@ -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) @@ -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 => @@ -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)) diff --git a/compiler/test-resources/scripting/sqlDateError.sc b/compiler/test-resources/scripting/sqlDateError.sc new file mode 100755 index 000000000000..b9a47d245d1a --- /dev/null +++ b/compiler/test-resources/scripting/sqlDateError.sc @@ -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("")) +} diff --git a/compiler/test/dotty/tools/scripting/BashScriptsTests.scala b/compiler/test/dotty/tools/scripting/BashScriptsTests.scala index 402e618733b9..d6181da95ee4 100644 --- a/compiler/test/dotty/tools/scripting/BashScriptsTests.scala +++ b/compiler/test/dotty/tools/scripting/BashScriptsTests.scala @@ -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") +