Skip to content

Commit d7d70c0

Browse files
authored
Merge pull request #13132 from philwalk/fix-script-path-verify-test
test added to BashScriptsTests to verify script.path property
2 parents c53cc91 + 7705baf commit d7d70c0

File tree

5 files changed

+71
-14
lines changed

5 files changed

+71
-14
lines changed

compiler/test-resources/scripting/hashBang.sc

100644100755
File mode changed.

compiler/test-resources/scripting/mainClassOnStack.sc

100644100755
File mode changed.

compiler/test-resources/scripting/scriptPath.sc

100644100755
File mode changed.

compiler/test/dotty/tools/scripting/BashScriptsTests.scala

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@ import org.junit.Test
1111
import vulpix.TestConfiguration
1212

1313

14-
/** Runs all tests contained in `compiler/test-resources/scripting/` */
14+
/** Verifies correct handling of command line arguments by `dist/bin/scala` and `dist/bin/scalac`.
15+
* +. arguments following a script path must be treated as script arguments
16+
* +. preserve script command line arguments.
17+
*/
1518
class BashScriptsTests:
1619
// classpath tests managed by scripting.ClasspathTests.scala
17-
def testFiles = scripts("/scripting").filter { ! _.getName.startsWith("classpath") }
20+
def testFiles = scripts("/scripting")
1821

1922
lazy val expectedOutput = List(
2023
"arg 0:[a]",
@@ -28,10 +31,10 @@ class BashScriptsTests:
2831
lazy val testScriptArgs = Seq(
2932
"a", "b", "c", "-repl", "-run", "-script", "-debug"
3033
)
31-
lazy val (bashExe,bashPath) =
34+
lazy val (bashExe, bashPath) =
3235
val bexe = getBashPath
3336
val bpath = Paths.get(bexe)
34-
printf("bashExe: [%s]\n", bexe)
37+
// printf("bashExe: [%s]\n", bexe)
3538
(bexe, bpath)
3639

3740
val showArgsScript = testFiles.find(_.getName == "showArgs.sc").get.absPath
@@ -41,13 +44,11 @@ class BashScriptsTests:
4144

4245
/* verify `dist/bin/scalac` */
4346
@Test def verifyScalacArgs =
44-
printf("scalacPath[%s]\n",scalacPath)
47+
printf("scalacPath[%s]\n", scalacPath)
4548
val commandline = (Seq(scalacPath, "-script", showArgsScript) ++ testScriptArgs).mkString(" ")
4649
if bashPath.toFile.exists then
4750
var cmd = Array(bashExe, "-c", commandline)
48-
val output = for {
49-
line <- Process(cmd).lazyLines_!
50-
} yield line
51+
val output = Process(cmd).lazyLines_!
5152
var fail = false
5253
printf("\n")
5354
for (line, expect) <- output zip expectedOutput do
@@ -68,7 +69,7 @@ class BashScriptsTests:
6869
} yield line
6970
var fail = false
7071
printf("\n")
71-
var mismatches = List.empty[(String,String)]
72+
var mismatches = List.empty[(String, String)]
7273
for (line, expect) <- output zip expectedOutput do
7374
printf("expected: %-17s\nactual : %s\n", expect, line)
7475
if line != expect then
@@ -77,24 +78,81 @@ class BashScriptsTests:
7778
if fail then
7879
assert(output == expectedOutput)
7980

80-
extension (str: String) def dropExtension =
81+
/*
82+
* verify that scriptPath.sc sees a valid script.path property.
83+
*/
84+
@Test def verifyScriptPathProperty =
85+
val scriptFile = testFiles.find(_.getName == "scriptPath.sc").get
86+
val expected = s"/${scriptFile.getName}"
87+
printf("===> verify valid system property script.path is reported by script [%s]\n", scriptFile.getName)
88+
val (exitCode, stdout, stderr) = bashCommand(scriptFile.absPath)
89+
if exitCode == 0 && ! stderr.exists(_.contains("Permission denied")) then
90+
// var cmd = Array(bashExe, "-c", scriptFile.absPath)
91+
// val stdout = Process(cmd).lazyLines_!
92+
stdout.foreach { printf("######### [%s]\n", _) }
93+
val valid = stdout.exists { _.endsWith(expected) }
94+
if valid then printf("# valid script.path reported by [%s]\n", scriptFile.getName)
95+
assert(valid, s"script ${scriptFile.absPath} did not report valid script.path value")
96+
97+
/*
98+
* verify SCALA_OPTS can specify an @argsfile when launching a scala script in `dist/bin/scala`.
99+
*/
100+
@Test def verifyScalaOpts =
101+
val scriptFile = testFiles.find(_.getName == "classpathReport.sc").get
102+
printf("===> verify valid system property script.path is reported by script [%s]\n", scriptFile.getName)
103+
val argsfile = createArgsFile() // avoid problems caused by drive letter
104+
val envPairs = List(("SCALA_OPTS", s"@$argsfile"))
105+
val (exitCode, stdout, stderr) = bashCommand(scriptFile.absPath, envPairs:_*)
106+
if exitCode != 0 || stderr.exists(_.contains("Permission denied")) then
107+
stderr.foreach { System.err.printf("stderr [%s]\n", _) }
108+
printf("unable to execute script, return value is %d\n", exitCode)
109+
else
110+
// val stdout: Seq[String] = Process(cmd, cwd, envPairs:_*).lazyLines_!.toList
111+
val expected = s"${cwd.toString}"
112+
val List(line1: String, line2: String) = stdout.take(2)
113+
val valid = line2.dropWhile( _ != ' ').trim.startsWith(expected)
114+
if valid then printf(s"\n===> success: classpath begins with %s, as reported by [%s]\n", cwd, scriptFile.getName)
115+
assert(valid, s"script ${scriptFile.absPath} did not report valid java.class.path first entry")
116+
117+
lazy val cwd = Paths.get(dotty.tools.dotc.config.Properties.userDir).toFile
118+
119+
def createArgsFile(): String =
120+
val utfCharset = java.nio.charset.StandardCharsets.UTF_8.name
121+
val text = s"-classpath ${cwd.absPath}"
122+
val path = Files.createTempFile("scriptingTest", ".args")
123+
Files.write(path, text.getBytes(utfCharset))
124+
path.toFile.getAbsolutePath.replace('\\', '/')
125+
126+
extension (str: String) def dropExtension: String =
81127
str.reverse.dropWhile(_ != '.').drop(1).reverse
82128

83-
extension(f: File) def absPath =
129+
extension(f: File) def absPath: String =
84130
f.getAbsolutePath.replace('\\', '/')
85131

86132
lazy val osname = Option(sys.props("os.name")).getOrElse("").toLowerCase
87133

88134
def getBashPath: String =
89135
var whichBash = ""
90-
printf("osname[%s]\n", osname)
136+
//printf("osname[%s]\n", osname)
91137
if osname.startsWith("windows") then
92138
whichBash = which("bash.exe")
93139
else
94140
whichBash = which("bash")
95141

96142
whichBash
97143

144+
def bashCommand(cmdstr: String, envPairs: (String, String)*): (Int, Seq[String], Seq[String]) = {
145+
import scala.sys.process._
146+
val cmd = Seq(bashExe, "-c", cmdstr)
147+
val proc = Process(cmd, None, envPairs *)
148+
var (stdout, stderr) = (List.empty[String], List.empty[String])
149+
val exitVal = proc ! ProcessLogger (
150+
(out: String) => stdout ::= out,
151+
(err: String) => stderr ::= err
152+
)
153+
(exitVal, stdout.reverse, stderr.reverse)
154+
}
155+
98156
def execCmd(command: String, options: String *): Seq[String] =
99157
val cmd = (command :: options.toList).toSeq
100158
for {

compiler/test/dotty/tools/scripting/ClasspathTests.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ class ClasspathTests:
5656
printf("bash is [%s]\n", bashExe)
5757

5858
if packBinScalaExists then
59-
val echoTest = "" // "SCALAC_ECHO_TEST=1"
60-
val bashCmdline = s"SCALA_OPTS= $echoTest ${scalaCopy.norm} -classpath '$wildcardEntry' $relpath"
59+
val bashCmdline = s"SCALA_OPTS= ${scalaCopy.norm} -classpath '$wildcardEntry' $relpath"
6160

6261
// ask [dist/bin/scalac] to echo generated command line so we can verify some things
6362
val cmd = Array(bashExe, "-c", bashCmdline)

0 commit comments

Comments
 (0)