@@ -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,70 +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
- def isFile (path : String ): Boolean =
46
- Files .isRegularFile(Paths .get(path))
47
-
48
- /* verify `dist/bin/scalac` */
44
+ /* verify `dist/bin/scalac` non-interference with command line args following script name */
49
45
@ Test def verifyScalacArgs =
50
- assert(isFile(scalacPath))
51
- printf(" scalacPath[%s]\n " ,scalacPath)
52
46
val commandline = (Seq (scalacPath, " -script" , showArgsScript) ++ testScriptArgs).mkString(" " )
53
- if bashPath.toFile.exists then
54
- var cmd = Array (bashExe, " -c" , commandline)
55
- val output = Process (cmd).lazyLines_!
47
+ val (validTest, exitCode, stdout, stderr) = bashCommand(commandline)
48
+ if validTest then
56
49
var fail = false
57
50
printf(" \n " )
58
- for (line, expect) <- output zip expectedOutput do
51
+ for (line, expect) <- stdout zip expectedOutput do
59
52
printf(" expected: %-17s\n actual : %s\n " , expect, line)
60
53
if line != expect then
61
54
fail = true
62
55
63
56
if fail then
64
- assert(output == expectedOutput)
57
+ assert(stdout == expectedOutput)
65
58
66
- /* verify `dist/bin/scala` */
59
+ /* verify `dist/bin/scala` non-interference with command line args following script name */
67
60
@ Test def verifyScalaArgs =
68
- assert(isFile(scalaPath))
69
61
val commandline = (Seq (scalaPath, showArgsScript) ++ testScriptArgs).mkString(" " )
70
- if bashPath.toFile.exists then
71
- var cmd = Array (bashExe, " -c" , commandline)
72
- val output = for {
73
- line <- Process (cmd).lazyLines_!
74
- } yield line
62
+ val (validTest, exitCode, stdout, stderr) = bashCommand(commandline)
63
+ if validTest then
75
64
var fail = false
76
65
printf(" \n " )
77
66
var mismatches = List .empty[(String , String )]
78
- for (line, expect) <- output zip expectedOutput do
67
+ for (line, expect) <- stdout zip expectedOutput do
79
68
printf(" expected: %-17s\n actual : %s\n " , expect, line)
80
69
if line != expect then
81
70
fail = true
82
71
83
72
if fail then
84
- assert(output == expectedOutput)
73
+ assert(stdout == expectedOutput)
85
74
86
75
/*
87
- * 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".
88
78
*/
89
79
@ Test def verifyScriptPathProperty =
90
80
val scriptFile = testFiles.find(_.getName == " scriptPath.sc" ).get
91
81
val expected = s " / ${scriptFile.getName}"
92
82
printf(" ===> verify valid system property script.path is reported by script [%s]\n " , scriptFile.getName)
93
- val (exitCode, stdout, stderr) = bashCommand( scriptFile.absPath )
94
- if exitCode == 0 && ! stderr.exists(_.contains( " Permission denied " )) then
95
- // var cmd = Array(bashExe, "-c", scriptFile.absPath)
96
- // val stdout = Process(cmd).lazyLines_!
97
- 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 " , _) }
98
88
val valid = stdout.exists { _.endsWith(expected) }
99
89
if valid then printf(" # valid script.path reported by [%s]\n " , scriptFile.getName)
100
90
assert(valid, s " script ${scriptFile.absPath} did not report valid script.path value " )
@@ -104,58 +94,111 @@ class BashScriptsTests:
104
94
*/
105
95
@ Test def verifyScalaOpts =
106
96
val scriptFile = testFiles.find(_.getName == " classpathReport.sc" ).get
107
- printf(" ===> verify valid system property script.path is reported by script [%s]\n " , scriptFile.getName)
108
- val argsfile = createArgsFile() // avoid problems caused by drive letter
97
+ printf(" ===> verify SCALA_OPTS='@argsfile' is properly handled by `dist/bin/scala`\n " )
109
98
val envPairs = List ((" SCALA_OPTS" , s " @ $argsfile" ))
110
- val (exitCode, stdout, stderr) = bashCommand(scriptFile.absPath, envPairs:_* )
111
- if exitCode != 0 || stderr.exists(_.contains(" Permission denied" )) then
112
- stderr.foreach { System .err.printf(" stderr [%s]\n " , _) }
113
- printf(" unable to execute script, return value is %d\n " , exitCode)
114
- else
115
- // val stdout: Seq[String] = Process(cmd, cwd, envPairs:_*).lazyLines_!.toList
116
- 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}"
117
102
val List (line1 : String , line2 : String ) = stdout.take(2 )
118
103
val valid = line2.dropWhile( _ != ' ' ).trim.startsWith(expected)
119
- 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)
120
105
assert(valid, s " script ${scriptFile.absPath} did not report valid java.class.path first entry " )
121
106
122
- 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
123
110
111
+ lazy val argsfile = createArgsFile() // avoid problems caused by drive letter
124
112
def createArgsFile (): String =
125
113
val utfCharset = java.nio.charset.StandardCharsets .UTF_8 .name
126
- val text = s " -classpath ${cwd.absPath}"
127
114
val path = Files .createTempFile(" scriptingTest" , " .args" )
115
+ val text = s " -classpath ${workingDirectory.absPath}"
128
116
Files .write(path, text.getBytes(utfCharset))
129
117
path.toFile.getAbsolutePath.replace('\\ ' , '/' )
130
118
131
- extension (str : String ) def dropExtension : String =
132
- 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
+ }
133
135
134
- extension(f : File ) def absPath : String =
135
- f.getAbsolutePath.replace('\\ ' , '/' )
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
+ }
136
141
137
- lazy val osname = Option (sys.props(" os.name" )).getOrElse(" " ).toLowerCase
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
+ }
138
147
139
- def getBashPath : String =
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
153
+
154
+ // use optional working directory TEST_CWD, if defined
155
+ lazy val workingDirectory : String = envOrElse(" TEST_CWD" , userDir)
156
+
157
+ // use optional TEST_BASH if defined, otherwise, bash must be in PATH
158
+ lazy val bashExe : String = envOrElse(" TEST_BASH" , whichBash)
159
+
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 =
140
177
var whichBash = " "
141
- // printf("osname[%s]\n", osname)
142
178
if osname.startsWith(" windows" ) then
143
179
whichBash = which(" bash.exe" )
144
180
else
145
181
whichBash = which(" bash" )
146
182
147
183
whichBash
148
184
149
- def bashCommand (cmdstr : String , envPairs : (String , String )* ): (Int , Seq [String ], Seq [String ]) = {
150
- import scala .sys .process ._
151
- val cmd = Seq (bashExe, " -c" , cmdstr)
152
- val proc = Process (cmd, None , envPairs * )
185
+ def bashCommand (cmdstr : String , additionalEnvPairs: List [(String , String )] = Nil ): (Boolean , Int , Seq [String ], Seq [String ]) = {
153
186
var (stdout, stderr) = (List .empty[String ], List .empty[String ])
154
- val exitVal = proc ! ProcessLogger (
155
- (out : String ) => stdout ::= out,
156
- (err : String ) => stderr ::= err
157
- )
158
- (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 )
159
202
}
160
203
161
204
def execCmd (command : String , options : String * ): Seq [String ] =
0 commit comments