Skip to content

Commit 121d746

Browse files
committed
expand wildcard classpath entries; not os-dependent, required by jar manifest; fixes #10761
1 parent 086d1a8 commit 121d746

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

compiler/src/dotty/tools/scripting/Main.scala

100644100755
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ object Main:
3232
def main(args: Array[String]): Unit =
3333
val (compilerArgs, scriptFile, scriptArgs, saveJar, invokeFlag) = distinguishArgs(args)
3434
val driver = ScriptingDriver(compilerArgs, scriptFile, scriptArgs)
35-
try driver.compileAndRun { (outDir:Path, classpath:String, mainClass: String) =>
35+
try driver.compileAndRun { (outDir:Path, classpathEntries:Seq[Path], mainClass: String) =>
3636
if saveJar then
3737
// write a standalone jar to the script parent directory
38-
writeJarfile(outDir, scriptFile, scriptArgs, classpath, mainClass)
38+
writeJarfile(outDir, scriptFile, scriptArgs, classpathEntries, mainClass)
3939
invokeFlag
4040
}
4141
catch
@@ -47,10 +47,10 @@ object Main:
4747
throw e.getCause
4848

4949
private def writeJarfile(outDir: Path, scriptFile: File, scriptArgs:Array[String],
50-
classpath:String, mainClassName: String): Unit =
50+
classpathEntries:Seq[Path], mainClassName: String): Unit =
5151

52-
val javaClasspath = sys.props("java.class.path")
53-
val runtimeClasspath = s"${classpath}$pathsep$javaClasspath"
52+
//val javaClasspath = sys.props("java.class.path")
53+
//val runtimeClasspath = s"${classpath}$pathsep$javaClasspath"
5454

5555
val jarTargetDir: Path = Option(scriptFile.toPath.toAbsolutePath.getParent) match {
5656
case None => sys.error(s"no parent directory for script file [$scriptFile]")
@@ -60,7 +60,8 @@ object Main:
6060
def scriptBasename = scriptFile.getName.takeWhile(_!='.')
6161
val jarPath = s"$jarTargetDir/$scriptBasename.jar"
6262

63-
val cpPaths = runtimeClasspath.split(pathsep).map(_.toUrl)
63+
//val cpPaths = runtimeClasspath.split(pathsep).map(_.toUrl)
64+
val cpPaths = classpathEntries.map { _.toString.toUrl }
6465

6566
import java.util.jar.Attributes.Name
6667
val cpString:String = cpPaths.distinct.mkString(" ")

compiler/src/dotty/tools/scripting/ScriptingDriver.scala

100644100755
Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dotty.tools.scripting
22

3-
import java.nio.file.{ Files, Path }
3+
import java.nio.file.{ Files, Paths, Path }
44
import java.io.File
55
import java.net.{ URL, URLClassLoader }
66
import java.lang.reflect.{ Modifier, Method }
@@ -17,7 +17,7 @@ import dotty.tools.dotc.config.Settings.Setting._
1717
import sys.process._
1818

1919
class ScriptingDriver(compilerArgs: Array[String], scriptFile: File, scriptArgs: Array[String]) extends Driver:
20-
def compileAndRun(pack:(Path, String, String) => Boolean = null): Unit =
20+
def compileAndRun(pack:(Path, Seq[Path], String) => Boolean = null): Unit =
2121
val outDir = Files.createTempDirectory("scala3-scripting")
2222
setup(compilerArgs :+ scriptFile.getAbsolutePath, initCtx.fresh) match
2323
case Some((toCompile, rootCtx)) =>
@@ -28,11 +28,23 @@ class ScriptingDriver(compilerArgs: Array[String], scriptFile: File, scriptArgs:
2828
throw ScriptingException("Errors encountered during compilation")
2929

3030
try
31-
val (mainClass, mainMethod) = detectMainClassAndMethod(outDir, ctx.settings.classpath.value, scriptFile)
31+
val classpath = s"${ctx.settings.classpath.value}${pathsep}${sys.props("java.class.path")}"
32+
val classpathEntries: Seq[Path] =
33+
classpath.split(pathsep).toIndexedSeq.flatMap { entry =>
34+
val f = Paths.get(entry).toAbsolutePath.normalize.toFile
35+
// expand wildcard classpath entries
36+
if (f.getName == "*" && f.getParentFile.isDirectory){
37+
f.getParentFile.listFiles.filter { _.getName.toLowerCase.endsWith(".jar") }.map { _.toPath }.toSeq
38+
} else {
39+
Seq(f.toPath)
40+
}
41+
}.toIndexedSeq
42+
43+
val (mainClass, mainMethod) = detectMainClassAndMethod(outDir, classpathEntries, scriptFile)
3244
val invokeMain: Boolean =
3345
Option(pack) match
3446
case Some(func) =>
35-
func(outDir, ctx.settings.classpath.value, mainClass)
47+
func(outDir, classpathEntries, mainClass)
3648
case None =>
3749
true
3850
end match
@@ -52,11 +64,12 @@ class ScriptingDriver(compilerArgs: Array[String], scriptFile: File, scriptArgs:
5264
target.delete()
5365
end deleteFile
5466

55-
private def detectMainClassAndMethod(outDir: Path, classpath: String,
67+
private def detectMainClassAndMethod(outDir: Path, classpathEntries: Seq[Path],
5668
scriptFile: File): (String, Method) =
57-
val outDirURL = outDir.toUri.toURL
58-
val classpathUrls = classpath.split(pathsep).map(File(_).toURI.toURL)
59-
val cl = URLClassLoader(classpathUrls :+ outDirURL)
69+
70+
val classpathUrls = (classpathEntries :+ outDir).map { _.toUri.toURL }
71+
72+
val cl = URLClassLoader(classpathUrls.toArray)
6073

6174
def collectMainMethods(target: File, path: String): List[(String, Method)] =
6275
val nameWithoutExtension = target.getName.takeWhile(_ != '.')

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package tools
33
package scripting
44

55
import java.io.File
6+
import java.nio.file.Path
67

78
import org.junit.Test
89

@@ -65,7 +66,7 @@ class ScriptingTests:
6566
),
6667
scriptFile = scriptFile,
6768
scriptArgs = scriptArgs
68-
).compileAndRun { (path:java.nio.file.Path,classpath:String, mainClass:String) =>
69+
).compileAndRun { (path:java.nio.file.Path,classpathEntries:Seq[Path], mainClass:String) =>
6970
printf("mainClass from ScriptingDriver: %s\n",mainClass)
7071
true // call compiled script main method
7172
}
@@ -128,7 +129,7 @@ class ScriptingTests:
128129
compilerArgs = Array("-classpath", TestConfiguration.basicClasspath),
129130
scriptFile = scriptFile,
130131
scriptArgs = Array.empty[String]
131-
).compileAndRun { (path:java.nio.file.Path,classpath:String, mainClass:String) =>
132+
).compileAndRun { (path:java.nio.file.Path,classpathEntries:Seq[Path], mainClass:String) =>
132133
printf("success: no call to main method in mainClass: %s\n",mainClass)
133134
false // no call to compiled script main method
134135
}
@@ -141,7 +142,7 @@ class ScriptingTests:
141142
compilerArgs = Array("-classpath", TestConfiguration.basicClasspath),
142143
scriptFile = scriptFile,
143144
scriptArgs = Array.empty[String]
144-
).compileAndRun { (path:java.nio.file.Path,classpath:String, mainClass:String) =>
145+
).compileAndRun { (path:java.nio.file.Path,classpathEntries:Seq[Path], mainClass:String) =>
145146
printf("call main method in mainClass: %s\n",mainClass)
146147
true // call compiled script main method, create touchedFile
147148
}

0 commit comments

Comments
 (0)