Skip to content

Commit 721390d

Browse files
committed
tests for script internal and external wildcard classpath use cases
1 parent bd06fad commit 721390d

File tree

4 files changed

+83
-27
lines changed

4 files changed

+83
-27
lines changed
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
#!dist/target/pack/bin/scala -classpath 'dist/target/pack/lib/*'
2+
3+
import java.nio.file.Paths
4+
25
def main(args: Array[String]): Unit =
3-
println(sys.props("java.class.path"))
6+
val cwd = Paths.get(".").toAbsolutePath.toString.replace('\\','/').replaceAll("/$","")
7+
printf("cwd: %s\n",cwd)
8+
printf("classpath: %s\n",sys.props("java.class.path"))
9+

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

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,35 @@ class ClasspathTests:
2222

2323
// only interested in classpath test scripts
2424
def testFiles = scripts("/scripting").filter { _.getName.matches("classpath.*[.]sc") }
25+
val testScriptName = "classpathReport.sc"
26+
def testScript = testFiles.find { _.getName == testScriptName } match
27+
case None => sys.error(s"test script not found: ${testScriptName}")
28+
case Some(file) => file
29+
30+
def packBinScalaExists:Boolean =
31+
val scalaScriptPath = Paths.get("dist/target/pack/bin/scala")
32+
scalaScriptPath.toFile.exists
2533

2634
/*
27-
* Call test scripts
35+
* verify java command line generated by scalac.
2836
*/
2937
@Test def scalacEchoTest =
30-
for scriptFile <- testFiles do
31-
val relpath = scriptFile.toPath.relpath.norm
32-
printf("===> test script name [%s]\n",relpath)
33-
printf("%s\n",relpath)
34-
printf("bash is [%s]\n",bashExe)
35-
38+
val relpath = testScript.toPath.relpath.norm
39+
printf("===> scalacEchoTest for script [%s]\n",relpath)
40+
printf("bash is [%s]\n",bashExe)
41+
42+
if packBinScalaExists then
3643
val echoTest = "SCALAC_ECHO_TEST=1"
37-
val bashCmdline = s"SCALA_OPTS= $echoTest dist/target/pack/bin/scala -classpath 'lib/*' $relpath"
44+
val bashCmdline = s"SCALA_OPTS= $echoTest dist/target/pack/bin/scala -classpath '$wildcardEntry' $relpath"
3845

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

42-
cmd.foreach { printf("[%s]\n",_) }
49+
//cmd.foreach { printf("[%s]\n",_) }
4350

4451
val javaCommandLine = exec(cmd:_*).mkString(" ").split(" ").filter { _.trim.nonEmpty }
45-
javaCommandLine.foreach { printf("scalac-java-command[%s]\n",_) }
52+
printf("\n==================== isWin[%s], cygwin[%s], mingw[%s], msys[%s]\n",isWin,cygwin,mingw,msys)
53+
javaCommandLine.foreach { printf("java-command[%s]\n",_) }
4654

4755
val output = scala.collection.mutable.Queue(javaCommandLine:_*)
4856
output.dequeueWhile( _ != "dotty.tools.scripting.Main")
@@ -66,7 +74,6 @@ class ClasspathTests:
6674
// PR #10761: verify that [dist/bin/scala] -classpath processing adds $psep to wildcard if Windows
6775
val classpathValue = consumeNext
6876
printf("classpath value [%s]\n",classpathValue)
69-
if isWin then printf("cygwin[%s], mingw[%s], msys[%s]\n",cygwin,mingw,msys)
7077
assert( !winshell || classpathValue.contains(psep) )
7178

7279
// expecting -script next
@@ -77,12 +84,57 @@ class ClasspathTests:
7784
printf("last: %s\nrelp: %s\n",javaCommandLine.last,relpath)
7885
assert(javaCommandLine.last == relpath,s"unexpected output passed to scripting.Main")
7986

87+
/*
88+
* verify classpath reported by called script.
89+
*/
90+
@Test def hashbangClasspathVerifyTest =
91+
val relpath = testScript.toPath.relpath.norm
92+
printf("===> hashbangClasspathVerifyTest for script [%s]\n",relpath)
93+
printf("bash is [%s]\n",bashExe)
94+
95+
if false && packBinScalaExists then
96+
val bashCmdline = s"SCALA_OPTS= $relpath"
97+
val cmd = Array(bashExe,"-c",bashCmdline)
98+
99+
cmd.foreach { printf("[%s]\n",_) }
100+
101+
// test script reports the classpath it sees
102+
val scriptOutput = exec(cmd:_*)
103+
val scriptCwd = findTaggedLine("cwd",scriptOutput)
104+
printf("script ran in directory [%s]\n",scriptCwd)
105+
val scriptCp = findTaggedLine("classpath",scriptOutput)
106+
107+
val hashbangClasspathJars = scriptCp.split(psep).map { _.getName }.sorted.distinct
108+
val packlibJars = listJars(s"$scriptCwd/dist/target/pack/lib").sorted.distinct
109+
110+
// verify that the classpath set in the hashbang line is effective
111+
if hashbangClasspathJars.size != packlibJars.size then
112+
printf("%d test script jars in classpath\n",hashbangClasspathJars.size)
113+
printf("%d jar files in dist/target/pack/lib\n",packlibJars.size)
114+
115+
assert(hashbangClasspathJars.size == packlibJars.size)
80116

117+
118+
//////////////// end of tests ////////////////
81119
lazy val cwd = Paths.get(".").toAbsolutePath
120+
lazy val wildcardEntry = "dist/target/pack/lib/*"
121+
122+
def listJars(dir: String) =
123+
val packlibDir = Paths.get(dir).toFile
124+
if packlibDir.isDirectory then
125+
packlibDir.listFiles.toList.map { _.getName }.filter { _.endsWith(".jar") }
126+
else
127+
Nil
82128

83129
import scala.jdk.CollectionConverters._
84130
lazy val env:Map[String,String] = System.getenv.asScala.toMap
85131

132+
// script output expected as "<tag>: <value>"
133+
def findTaggedLine(tag: String, lines: Seq[String]): String =
134+
lines.find { _.startsWith(tag) } match
135+
case None => sys.error(s"no $tag: found in script output")
136+
case Some(cwd) => cwd.dropWhile( _ != ' ').trim // discard tag
137+
86138
def exec(cmd: String *): Seq[String] = Process(cmd).lazyLines_!.toList
87139

88140
def which(str:String) =
@@ -125,6 +177,8 @@ extension(p:Path)
125177
def norm: String = p.toString.replace('\\','/')
126178

127179
extension(path: String)
180+
def getName: String = norm.replaceAll(".*/","")
181+
128182
// Normalize path separator, convert relative path to absolute
129183
def norm: String =
130184
path.replace('\\', '/') match {

dist/bin/scala

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ truncated_params="${*#-}"
5353
# options_indicator != 0 if at least one parameter is not an option
5454
options_indicator=$(( ${#all_params} - ${#truncated_params} - $# ))
5555

56-
[ -n "$SCALA_OPTS" ] && set -- $SCALA_OPTS $@
56+
[ -n "$SCALA_OPTS" ] && set -- $SCALA_OPTS "$@"
5757

5858
while [[ $# -gt 0 ]]; do
5959
case "$1" in
@@ -65,19 +65,18 @@ while [[ $# -gt 0 ]]; do
6565
execute_run=true
6666
shift
6767
;;
68-
-cp | -classpath)
69-
CLASS_PATH="$2"
70-
if [[ $cygwin || $mingw || $msys ]]; then
71-
# in Windows, need to protect a single wildcard entry from jdk globbing.
72-
# (jdk globbing replaces a single wildcard arg to multiple jar file args!)
73-
if [[ $CLASS_PATH =~ \* && ! $CLASS_PATH =~ \; ]]; then
74-
CLASS_PATH=";$CLASS_PATH"
75-
fi
76-
fi
68+
-cp | -classpath )
69+
CLASS_PATH="$2${PSEP}"
7770
class_path_count+=1
7871
shift
7972
shift
8073
;;
74+
-cp*|-classpath*)
75+
# hashbang can combine args, e.g. "-classpath 'lib/*'"
76+
CLASS_PATH="${1#* *}${PSEP}"
77+
echo "CLASS_PATH[$CLASS_PATH]" 1>&2
78+
class_path_count+=1
79+
;;
8180
-with-compiler)
8281
with_compiler=true
8382
shift

dist/bin/scalac

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,8 @@ classpathArgs
119119
if [ "$PROG_NAME" == "$ScriptingMain" ]; then
120120
scripting_string="-script $target_script ${scripting_args[@]}"
121121
fi
122-
if [ -n "$SCALAC_ECHO_TEST" ]; then
123-
EVAL=echo # to test with EVAL=echo
124-
else
125-
EVAL=eval
126-
fi
122+
123+
EVAL=eval ; [ -n "$SCALAC_ECHO_TEST" ] && EVAL=echo
127124
$EVAL "\"$JAVACMD\"" \
128125
${JAVA_OPTS:-$default_java_opts} \
129126
"${DEBUG-}" \

0 commit comments

Comments
 (0)