@@ -10,6 +10,7 @@ import org.junit.Test
10
10
11
11
import vulpix .TestConfiguration
12
12
13
+ import dotty .tools .dotc .config .Properties ._
13
14
14
15
/** Verifies correct handling of command line arguments by `dist/bin/scala` and `dist/bin/scalac`.
15
16
* +. arguments following a script path must be treated as script arguments
@@ -19,6 +20,13 @@ class BashScriptsTests:
19
20
// classpath tests managed by scripting.ClasspathTests.scala
20
21
def testFiles = scripts(" /scripting" )
21
22
23
+ printf(" osname[%s]\n " , osname)
24
+ printf(" using JAVA_HOME=%s\n " , javaHome)
25
+ printf(" using SCALA_HOME=%s\n " , scalaHome)
26
+ printf(" first 5 PATH entries:\n %s\n " , pathEntries.take(5 ).mkString(" \n " ))
27
+ printf(" scala path: [%s]\n " , scalaPath)
28
+ printf(" scalac path: [%s]\n " , scalacPath)
29
+
22
30
lazy val expectedOutput = List (
23
31
" arg 0:[a]" ,
24
32
" arg 1:[b]" ,
@@ -31,65 +39,52 @@ class BashScriptsTests:
31
39
lazy val testScriptArgs = Seq (
32
40
" a" , " b" , " c" , " -repl" , " -run" , " -script" , " -debug"
33
41
)
34
- lazy val (bashExe, bashPath) =
35
- val bexe = getBashPath
36
- val bpath = Paths .get(bexe)
37
- // printf("bashExe: [%s]\n", bexe)
38
- (bexe, bpath)
39
-
40
42
val showArgsScript = testFiles.find(_.getName == " showArgs.sc" ).get.absPath
41
43
42
- val scalacPath = " dist/target/pack/bin/scalac" // which("scalac")
43
- val scalaPath = " dist/target/pack/bin/scala" // which("scala")
44
-
45
- /* verify `dist/bin/scalac` */
44
+ /* verify `dist/bin/scalac` non-interference with command line args following script name */
46
45
@ Test def verifyScalacArgs =
47
- printf(" scalacPath[%s]\n " , scalacPath)
48
46
val commandline = (Seq (scalacPath, " -script" , showArgsScript) ++ testScriptArgs).mkString(" " )
49
- if bashPath.toFile.exists then
50
- var cmd = Array (bashExe, " -c" , commandline)
51
- val output = Process (cmd).lazyLines_!
47
+ val (validTest, exitCode, stdout, stderr) = bashCommand(commandline)
48
+ if validTest then
52
49
var fail = false
53
50
printf(" \n " )
54
- for (line, expect) <- output zip expectedOutput do
51
+ for (line, expect) <- stdout zip expectedOutput do
55
52
printf(" expected: %-17s\n actual : %s\n " , expect, line)
56
53
if line != expect then
57
54
fail = true
58
55
59
56
if fail then
60
- assert(output == expectedOutput)
57
+ assert(stdout == expectedOutput)
61
58
62
- /* verify `dist/bin/scala` */
59
+ /* verify `dist/bin/scala` non-interference with command line args following script name */
63
60
@ Test def verifyScalaArgs =
64
61
val commandline = (Seq (scalaPath, showArgsScript) ++ testScriptArgs).mkString(" " )
65
- if bashPath.toFile.exists then
66
- var cmd = Array (bashExe, " -c" , commandline)
67
- val output = for {
68
- line <- Process (cmd).lazyLines_!
69
- } yield line
62
+ val (validTest, exitCode, stdout, stderr) = bashCommand(commandline)
63
+ if validTest then
70
64
var fail = false
71
65
printf(" \n " )
72
66
var mismatches = List .empty[(String , String )]
73
- for (line, expect) <- output zip expectedOutput do
67
+ for (line, expect) <- stdout zip expectedOutput do
74
68
printf(" expected: %-17s\n actual : %s\n " , expect, line)
75
69
if line != expect then
76
70
fail = true
77
71
78
72
if fail then
79
- assert(output == expectedOutput)
73
+ assert(stdout == expectedOutput)
80
74
81
75
/*
82
- * verify that scriptPath.sc sees a valid script.path property.
76
+ * verify that scriptPath.sc sees a valid script.path property,
77
+ * and that it's value is the path to "scriptPath.sc".
83
78
*/
84
79
@ Test def verifyScriptPathProperty =
85
80
val scriptFile = testFiles.find(_.getName == " scriptPath.sc" ).get
86
81
val expected = s " / ${scriptFile.getName}"
87
82
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 " , _) }
83
+ printf( " calling scriptFile: %s \n " , scriptFile)
84
+ val (validTest, exitCode, stdout, stderr) = bashCommand(scriptFile.absPath)
85
+ if validTest then
86
+ stdout.foreach { printf( " stdout: [%s] \n " , _) }
87
+ stderr .foreach { printf(" stderr: [%s]\n " , _) }
93
88
val valid = stdout.exists { _.endsWith(expected) }
94
89
if valid then printf(" # valid script.path reported by [%s]\n " , scriptFile.getName)
95
90
assert(valid, s " script ${scriptFile.absPath} did not report valid script.path value " )
@@ -99,58 +94,111 @@ class BashScriptsTests:
99
94
*/
100
95
@ Test def verifyScalaOpts =
101
96
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
97
+ printf(" ===> verify SCALA_OPTS='@argsfile' is properly handled by `dist/bin/scala`\n " )
104
98
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}"
99
+ val (validTest, exitCode, stdout, stderr) = bashCommand(scriptFile.absPath, envPairs)
100
+ if validTest then
101
+ val expected = s " ${workingDirectory.toString}"
112
102
val List (line1 : String , line2 : String ) = stdout.take(2 )
113
103
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)
104
+ if valid then printf(s " \n ===> success: classpath begins with %s, as reported by [%s] \n " , workingDirectory , scriptFile.getName)
115
105
assert(valid, s " script ${scriptFile.absPath} did not report valid java.class.path first entry " )
116
106
117
- lazy val cwd = Paths .get(dotty.tools.dotc.config.Properties .userDir).toFile
107
+ def existingPath : String = envOrElse(" PATH" ," " ).norm
108
+ def adjustedPath = s " $javaHome/bin $psep$scalaHome/bin $psep$existingPath"
109
+ def pathEntries = adjustedPath.split(psep).toList
118
110
111
+ lazy val argsfile = createArgsFile() // avoid problems caused by drive letter
119
112
def createArgsFile (): String =
120
113
val utfCharset = java.nio.charset.StandardCharsets .UTF_8 .name
121
- val text = s " -classpath ${cwd.absPath}"
122
114
val path = Files .createTempFile(" scriptingTest" , " .args" )
115
+ val text = s " -classpath ${workingDirectory.absPath}"
123
116
Files .write(path, text.getBytes(utfCharset))
124
117
path.toFile.getAbsolutePath.replace('\\ ' , '/' )
125
118
126
- extension (str : String ) def dropExtension : String =
127
- str.reverse.dropWhile(_ != '.' ).drop(1 ).reverse
119
+ def fixHome (s : String ): String =
120
+ s.startsWith(" ~" ) match {
121
+ case false => s
122
+ case true => s.replaceFirst(" ~" ,userHome)
123
+ }
124
+
125
+ extension(s : String ) {
126
+ def toPath : Path = Paths .get(fixHome(s)) // .toAbsolutePath
127
+ def toFile : File = s.toPath.toFile
128
+ def absPath : String = s.toFile.absPath
129
+ def norm : String = s.replace('\\ ' , '/' ) // bash expects forward slash
130
+ def isFile : Boolean = s.toFile.isFile
131
+ def exists : Boolean = s.toPath.toFile.exists
132
+ def name : String = s.toFile.getName
133
+ def dropExtension : String = s.reverse.dropWhile(_ != '.' ).drop(1 ).reverse
134
+ }
135
+
136
+ extension(p : Path ) {
137
+ def listFiles : Seq [File ] = p.toFile.listFiles.toList
138
+ def norm : String = p.normalize.toString.replace('\\ ' , '/' )
139
+ def name : String = p.toFile.getName
140
+ }
141
+
142
+ extension(f : File ) {
143
+ def name = f.getName
144
+ def norm : String = f.toPath.normalize.norm
145
+ def absPath : String = f.getAbsolutePath.norm
146
+ }
147
+
148
+ lazy val psep : String = propOrElse(" path.separator" ," " )
149
+ lazy val osname = propOrElse(" os.name" , " " ).toLowerCase
150
+
151
+ lazy val scalacPath = s " $workingDirectory/dist/target/pack/bin/scalac " .norm
152
+ lazy val scalaPath = s " $workingDirectory/dist/target/pack/bin/scala " .norm
128
153
129
- extension( f : File ) def absPath : String =
130
- f.getAbsolutePath.replace( ' \\ ' , '/' )
154
+ // use optional working directory TEST_CWD, if defined
155
+ lazy val workingDirectory : String = envOrElse( " TEST_CWD " , userDir )
131
156
132
- lazy val osname = Option (sys.props(" os.name" )).getOrElse(" " ).toLowerCase
157
+ // use optional TEST_BASH if defined, otherwise, bash must be in PATH
158
+ lazy val bashExe : String = envOrElse(" TEST_BASH" , whichBash)
133
159
134
- def getBashPath : String =
160
+ // test env SCALA_HOME is:
161
+ // dist/target/pack, if present
162
+ // else, SCALA_HOME if defined
163
+ // else, not defined
164
+ lazy val scalaHome =
165
+ if scalacPath.isFile then scalacPath.replaceAll(" /bin/scalac" ," " )
166
+ else envOrElse(" SCALA_HOME" , " " ).norm
167
+
168
+ lazy val javaHome = envOrElse(" JAVA_HOME" , " " ).norm
169
+
170
+ lazy val testEnvPairs = List (
171
+ (" JAVA_HOME" , javaHome),
172
+ (" SCALA_HOME" , scalaHome),
173
+ (" PATH" , adjustedPath),
174
+ ).filter { case (name,valu) => valu.nonEmpty }
175
+
176
+ lazy val whichBash : String =
135
177
var whichBash = " "
136
- // printf("osname[%s]\n", osname)
137
178
if osname.startsWith(" windows" ) then
138
179
whichBash = which(" bash.exe" )
139
180
else
140
181
whichBash = which(" bash" )
141
182
142
183
whichBash
143
184
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 * )
185
+ def bashCommand (cmdstr : String , additionalEnvPairs: List [(String , String )] = Nil ): (Boolean , Int , Seq [String ], Seq [String ]) = {
148
186
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)
187
+ if bashExe.toFile.exists then
188
+ val cmd = Seq (bashExe, " -c" , cmdstr)
189
+ val envPairs = testEnvPairs ++ additionalEnvPairs
190
+ val proc = Process (cmd, None , envPairs * )
191
+ val exitVal = proc ! ProcessLogger (
192
+ (out : String ) => stdout ::= out,
193
+ (err : String ) => stderr ::= err
194
+ )
195
+ val validTest = exitVal == 0 && ! stderr.exists(_.contains(" Permission denied" ))
196
+ if ! validTest then
197
+ printf(" \n unable to execute script, return value is %d\n " , exitVal)
198
+ stderr.foreach { System .err.printf(" stderr [%s]\n " , _) }
199
+ (validTest, exitVal, stdout.reverse, stderr.reverse)
200
+ else
201
+ (false , - 1 , Nil , Nil )
154
202
}
155
203
156
204
def execCmd (command : String , options : String * ): Seq [String ] =
0 commit comments