-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix for #10761 ; expand wildcard classpath entries #11633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix for #10761 ; expand wildcard classpath entries #11633
Conversation
I'm wondering if the Scripting execution engine is the only place in the Scala 3 compiler that has to take care of wildcard classpaths. Any thoughts about it ?! |
I'm not aware of where else in the Scala 3 compiler there might also be a need to expand classpath. I wasn't able to produce problems except those that this PR addresses. |
My comment in #10761 (comment) points you to the code in the compiler which currently handles expanding wildcard, reusing that code would be good. |
@smarter - thanks, I updated the PR. compiler/src/dotty/tools/scripting/ScriptingDriver.scala now uses the
Test class added to verify:
|
@michelou In Windows, the additional test can prevent the wildcard expansion from failing. An alternative might be something like the following: /** Expand single path entry */
private def expandS(pattern: String): List[String] = {
val wildSuffix = "/*"
/* Get all subdirectories, jars, zips out of a directory. */
def lsDir(dir: Directory, filt: String => Boolean = _ => true) =
dir.list.filter(x => filt(x.name) && (x.isDirectory || isJarOrZip(x))).map(_.path).toList
if (pattern == "*") lsDir(Directory("."))
else if (pattern.replace('\\','/').endsWith(wildSuffix)) lsDir(Directory(pattern dropRight 2))
else if (pattern.contains('*')) {
try {
val regexp = ("^" + pattern.replace("""\*""", """.*""") + "$").r
lsDir(Directory(pattern).parent, regexp.findFirstIn(_).isDefined)
}
catch { case _: PatternSyntaxException => List(pattern) }
}
else List(pattern)
} |
So I would add the following comment befote the modified line :
|
@michelou - comment was added to line 135 of compiler/src/dotty/tools/io/ClassPath.scala as per your suggestion |
After the change to leverage I'm investigating, |
Added code to expand wildcards in compiler/src/dotty/tools/dotc/core/MacroClassLoader.scala. I will improve the coverage in the classpath test compiler/test/dotty/tools/io/ClasspathTest.scala |
It turns out that Windows jdk 11 (and maybe earlier versions too?) expand all command line arguments that look like wildcard classpath entries. As a result, -classpath args on the command line are expanded (Windows only), even if escaped and quoted, etc.. If a classpath is specified in the hashbang header, it doesn't get expanded. The most recent commit covers this use case. |
@philwalk In file |
I deleted the extra import, and will commit after I add some more tests (hopefully soon). |
While testing this PR, I discovered an unrelated problem with dist/bin/scalac -repl) PROG_NAME="$ReplMain" && shift ;;
- -script) PROG_NAME="$ScriptingMain" && target_script="$2" && in_scripting_args=true && shift && shift ;;
+ -script) PROG_NAME="$ScriptingMain" && target_script="$2" && in_scripting_args=true && shift && shift
+ while [[ $# -gt 0 ]]; do addScripting "$1" && shift ; done ;;
-compile) PROG_NAME="$CompilerMain" && shift ;; The bug manifests itself if the What's the recommended process for submitting a fix? |
Since this PR is complicated enough as it is, I suggest making another PR for that unrelated change. |
@michelou Is this one ready to go? |
@michelou I'm working on tests to thoroughly verify this PR, but they aren't ready yet. |
|
It can be temporary if there are objections to it. We possibly can generate an edited copy of The reason I added it was to be able to test In the test file ClasspathTest.scala on line 38: val cmd = Array(bashExe,"-c",s"SCALAC_ECHO_TEST=1 dist/target/pack/bin/scala -classpath 'lib/* $relpath") To see what happens, you can remove the SCALAC_ECHO_TEST from the test: val cmd = Array(bashExe,"-c",s"dist/target/pack/bin/scala -classpath 'lib/*' $relpath")
|
When I run sbt tests from a Windows command shell, the new classpath test fails, so I'm working on how to handle it. |
@philwalk Note about style : please add a space after commas, e.g. |
Classpath tests now cover the two most $ scala -classpath 'lib/*' script.sc A classpath consisting of a single wildcard entry, specified in a hashbang: #!/opt/scala3/bin/scala -classpath 'lib/*'
def main(args: Array[String]): Unit =
val psep = sys.props("path.separator")
for entry <- sys.props("java.class.path").split(psep) do
printf("%s\n",entry) One version of the single wildcard classpath use cases (in Windows) results in all the jar files in the the wildcard directory being expanded and passed as arguments to the compiler. The compiler seems to treat them as if they're source files and produces thousands of error messages.
|
…various style errors
I'm ready to push a bug fix and corrected style errors, should I wait until the current checks are completed? |
The comment on the most recent commit should have been: |
Strange. Job 0dc35d8 seems to be still running ?! |
close and re-open to trigger a rebuild ... there does seem to be something odd about the community build status reporting. |
@michelou I'm ready to push an updated version of compiler/test/dotty/tools/scripting/ClasspathTests.scala that eliminates the Are you aware of any other changes that are needed for this PR? |
@philwalk Your file |
@michelou - I will push my changes now, the link above is to the original proposal which has the objectionable lines. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks @philwalk 🎉
@michelou I'm merging this now. Feel free to open a new issue if you spot some problems. Thank you. |
This fixes #10761
Wildcard classpath entries are expanded, which solves 2 problems:
-save
option requires expanded classpath wildcard entries in jar manifest-classpath
wildcard entriesThe solution is not os-dependent, the jar manifest
Class-Path
property requires expanded wildcards.The callback
classpath:String
parameter in compiler/src/dotty/tools/scripting/ScriptingDriver.scala was changed toclasspathEntries:Seq[String]
so the expanded classpath could also be seen by compiler/src/dotty/tools/scripting/Main.scala and could to be written to the jar manifest.Two similar use-cases fixed by the PR each required a different fix:
A classpath consisting of a single wildcard entry, specified on the command line (fixed by appending
$PSEP
to the classpath):$ scala -classpath 'lib/*' script.sc
A classpath consisting of a single wildcard entry, specified in a hashbang (fixed by accepting '-classpath' and 'lib/*' passed together as a single argument to
dist/bin/scala
). An example of this use-case: