Skip to content

fix 2 problems plus add workaround for #13760 #14252

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

Merged
merged 1 commit into from
Jan 12, 2022
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
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")