diff --git a/compiler/test-resources/scripting/showArgs.sc b/compiler/test-resources/scripting/showArgs.sc new file mode 100644 index 000000000000..28f16a9022b3 --- /dev/null +++ b/compiler/test-resources/scripting/showArgs.sc @@ -0,0 +1,6 @@ +#!/usr/bin/env scala + +// precise output format expected by BashScriptsTests.scala +def main(args: Array[String]): Unit = + for (a,i) <- args.zipWithIndex do + printf(s"arg %2d:[%s]\n",i,a) diff --git a/compiler/test/dotty/tools/scripting/BashScriptsTests.scala b/compiler/test/dotty/tools/scripting/BashScriptsTests.scala new file mode 100644 index 000000000000..cadf86467ae7 --- /dev/null +++ b/compiler/test/dotty/tools/scripting/BashScriptsTests.scala @@ -0,0 +1,100 @@ +package dotty +package tools +package scripting + +import java.io.File +import java.nio.file.{Path, Paths, Files} +import scala.sys.process._ + +import org.junit.Test + +import vulpix.TestConfiguration + + +/** Runs all tests contained in `compiler/test-resources/scripting/` */ +class BashScriptsTests: + // classpath tests managed by scripting.ClasspathTests.scala + def testFiles = scripts("/scripting").filter { ! _.getName.startsWith("classpath") } + + lazy val expectedOutput = List( + "arg 0:[a]", + "arg 1:[b]", + "arg 2:[c]", + "arg 3:[-repl]", + "arg 4:[-run]", + "arg 5:[-script]", + "arg 6:[-debug]", + ) + lazy val testScriptArgs = Seq( + "a", "b", "c", "-repl", "-run", "-script", "-debug" + ) + lazy val (bashExe,bashPath) = + val bexe = getBashPath + val bpath = Paths.get(bexe) + printf("bashExe: [%s]\n", bexe) + (bexe, bpath) + + val showArgsScript = testFiles.find(_.getName == "showArgs.sc").get.absPath + + val scalacPath = which("scalac") + val scalaPath = which("scala") + + /* verify `dist/bin/scalac` */ + @Test def verifyScalacArgs = + val commandline = (Seq(scalacPath, "-script", showArgsScript) ++ testScriptArgs).mkString(" ") + if bashPath.toFile.exists then + var cmd = Array(bashExe, "-c", commandline) + val output = for { + line <- Process(cmd).lazyLines_! + } yield line + var fail = false + printf("\n") + for (line, expect) <- output zip expectedOutput do + printf("expected: %-17s| actual: %s\n", line, expect) + if line != expect then + fail = true + + if fail then + assert(output == expectedOutput) + + /* verify `dist/bin/scala` */ + @Test def verifyScalaArgs = + val commandline = (Seq(scalaPath, showArgsScript) ++ testScriptArgs).mkString(" ") + if bashPath.toFile.exists then + var cmd = Array(bashExe, "-c", commandline) + val output = for { + line <- Process(cmd).lazyLines_! + } yield line + var fail = false + printf("\n") + for (line, expect) <- output zip expectedOutput do + printf("expected: %-17s| actual: %s\n", line, expect) + if line != expect then + fail = true + + if fail then + assert(output == expectedOutput) + + extension (str: String) def dropExtension = + str.reverse.dropWhile(_ != '.').drop(1).reverse + + extension(f: File) def absPath = + f.getAbsolutePath.replace('\\', '/') + + lazy val osname = Option(sys.props("os.name")).getOrElse("").toLowerCase + + def getBashPath: String = + var whichBash = "" + printf("osname[%s]\n", osname) + if osname.startsWith("windows") then + whichBash = which("bash.exe") + else + whichBash = which("bash") + + whichBash + + def execCmd(command: String, options: String *): Seq[String] = + val cmd = (command :: options.toList).toSeq + for { + line <- Process(cmd).lazyLines_! + } yield line diff --git a/dist/bin/scala b/dist/bin/scala old mode 100755 new mode 100644 index 83e7720ef43d..3c6720d9b94f --- a/dist/bin/scala +++ b/dist/bin/scala @@ -118,34 +118,35 @@ while [[ $# -gt 0 ]]; do shift ;; *) - if [ "${execute_mode-}" == 'script' ]; then - addScript "$1" - else - # script if extension .scala or .sc, or if has scala hashbang line - - # no -f test, issue meaningful error message (file not found) - if [[ "$1" == *.scala || "$1" == *.sc ]]; then - setExecuteMode 'script' # execute_script=true - - # -f test needed before we examine the hashbang line - elif [[ (-f "$1" && `head -n 1 -- "$1" | grep '#!.*scala'`) ]]; then - setExecuteMode 'script' # execute_script=true - fi + # script if extension .scala or .sc, or if has scala hashbang line + # no -f test, issue meaningful error message (file not found) + if [[ "$1" == *.scala || "$1" == *.sc ]]; then + setExecuteMode 'script' # execute_script=true + + # -f test needed before we examine the hashbang line + elif [[ (-f "$1" && `head -n 1 -- "$1" | grep '#!.*scala'`) ]]; then + setExecuteMode 'script' # execute_script=true + fi - if [ "${execute_mode-}" == 'script' ]; then - target_script="$1" - if [ ! -f $target_script ]; then - # likely a typo or missing script file, quit early - echo "not found: $target_script" 1>&2 - scala_exit_status=2 - onExit - fi - else - # all unrecognized args appearing prior to a script name - addResidual "$1" + if [ "${execute_mode-}" == 'script' ]; then + target_script="$1" + shift + if [ ! -f $target_script ]; then + # likely a typo or missing script file, quit early + echo "not found: $target_script" 1>&2 + scala_exit_status=2 + onExit fi + # all are script args + while [[ $# -gt 0 ]]; do + addScript "${1}" + shift + done + else + # all unrecognized args appearing prior to a script name + addResidual "$1" + shift fi - shift ;; esac diff --git a/dist/bin/scalac b/dist/bin/scalac old mode 100755 new mode 100644 index 14a3998215c6..9a168316d16f --- a/dist/bin/scalac +++ b/dist/bin/scalac @@ -42,7 +42,7 @@ case "$1" in -Oshort) addJava "-XX:+TieredCompilation -XX:TieredStopAtLevel=1" && shift ;; -repl) PROG_NAME="$ReplMain" && shift ;; -script) PROG_NAME="$ScriptingMain" && target_script="$2" && shift && shift - while [[ $# -gt 0 ]]; do addScripting "$1" && shift ; done ;; + while [[ $# -gt 0 ]]; do addScript "$1" && shift ; done ;; -compile) PROG_NAME="$CompilerMain" && shift ;; -decompile) PROG_NAME="$DecompilerMain" && shift ;; -print-tasty) PROG_NAME="$DecompilerMain" && addScala "-print-tasty" && shift ;; @@ -64,7 +64,7 @@ compilerJavaClasspathArgs if [ "$PROG_NAME" == "$ScriptingMain" ]; then setScriptName="-Dscript.path=$target_script" - scripting_string="-script $target_script ${scripting_args[@]}" + scripting_string="-script $target_script ${script_args[@]}" fi [ -n "$script_trace" ] && set -x