Skip to content

Commit e5ac6c5

Browse files
authored
Use pathing jars in cli commands (#21121)
2 parents fd7a463 + e93430f commit e5ac6c5

File tree

10 files changed

+51
-93
lines changed

10 files changed

+51
-93
lines changed

compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala

+19-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import dotty.tools.io.{AbstractFile, VirtualDirectory}
77
import FileUtils.*
88
import dotty.tools.io.ClassPath
99
import dotty.tools.dotc.core.Contexts.*
10+
import java.nio.file.Files
1011

1112
/**
1213
* Provides factory methods for classpath. When creating classpath instances for a given path,
@@ -52,14 +53,30 @@ class ClassPathFactory {
5253

5354
// Internal
5455
protected def classesInPathImpl(path: String, expand: Boolean)(using Context): List[ClassPath] =
55-
for {
56+
val files = for {
5657
file <- expandPath(path, expand)
5758
dir <- {
5859
def asImage = if (file.endsWith(".jimage")) Some(AbstractFile.getFile(file)) else None
5960
Option(AbstractFile.getDirectory(file)).orElse(asImage)
6061
}
6162
}
62-
yield newClassPath(dir)
63+
yield dir
64+
65+
val expanded =
66+
if scala.util.Properties.propOrFalse("scala.expandjavacp") then
67+
for
68+
file <- files
69+
a <- ClassPath.expandManifestPath(file.absolutePath)
70+
path = java.nio.file.Paths.get(a.toURI()).nn
71+
if Files.exists(path)
72+
yield
73+
newClassPath(AbstractFile.getFile(path))
74+
else
75+
Seq.empty
76+
77+
files.map(newClassPath) ++ expanded
78+
79+
end classesInPathImpl
6380

6481
private def createSourcePath(file: AbstractFile)(using Context): ClassPath =
6582
if (file.isJarOrZip)

compiler/src/dotty/tools/io/ClassPath.scala

+9-4
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,18 @@ object ClassPath {
152152

153153
val baseDir = file.parent
154154
new Jar(file).classPathElements map (elem =>
155-
specToURL(elem) getOrElse (baseDir / elem).toURL
155+
specToURL(elem, baseDir) getOrElse (baseDir / elem).toURL
156156
)
157157
}
158158

159-
def specToURL(spec: String): Option[URL] =
160-
try Some(new URI(spec).toURL)
161-
catch case _: MalformedURLException | _: URISyntaxException => None
159+
def specToURL(spec: String, basedir: Directory): Option[URL] =
160+
try
161+
val uri = new URI(spec)
162+
if uri.isAbsolute() then Some(uri.toURL())
163+
else
164+
Some(basedir.resolve(Path(spec)).toURL)
165+
catch
166+
case _: MalformedURLException | _: URISyntaxException => None
162167

163168
def manifests: List[java.net.URL] = {
164169
import scala.jdk.CollectionConverters.EnumerationHasAsScala

dist/bin/common

+2-18
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,9 @@ source "$PROG_HOME/bin/common-shared"
66
# * The code below is for Dotty
77
# *-------------------------------------------------*/
88

9-
load_classpath () {
10-
command="$1"
11-
psep_pattern="$2"
12-
__CLASS_PATH=""
13-
while IFS= read -r line || [ -n "$line" ]; do
14-
# jna-5 only appropriate for some combinations
15-
if ! [[ ( -n ${conemu-} || -n ${msys-}) && "$line" == "*jna-5*" ]]; then
16-
if [ -n "$__CLASS_PATH" ]; then
17-
__CLASS_PATH+="$psep_pattern"
18-
fi
19-
__CLASS_PATH+="$PROG_HOME/maven2/$line"
20-
fi
21-
done < "$PROG_HOME/etc/$command.classpath"
22-
echo "$__CLASS_PATH"
23-
}
24-
259
compilerJavaClasspathArgs () {
26-
toolchain="$(load_classpath "scala" "$PSEP")"
27-
toolchain_extra="$(load_classpath "with_compiler" "$PSEP")"
10+
toolchain="$PROG_HOME/lib/scala.jar"
11+
toolchain_extra="$PROG_HOME/lib/with_compiler.jar"
2812

2913
if [ -n "$toolchain_extra" ]; then
3014
toolchain+="$PSEP$toolchain_extra"

dist/bin/common.bat

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ if not defined _PROG_HOME (
3838
set _EXITCODE=1
3939
goto :eof
4040
)
41-
set "_ETC_DIR=%_PROG_HOME%\etc"
41+
set "_LIB_DIR=%_PROG_HOME%\lib"
4242

4343
set _PSEP=;

dist/bin/scalac

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ eval "\"$JAVACMD\"" \
8686
${JAVA_OPTS:-$default_java_opts} \
8787
"${java_args[@]}" \
8888
"-classpath \"$jvm_cp_args\"" \
89+
"-Dscala.expandjavacp=true" \
8990
"-Dscala.usejavacp=true" \
9091
"-Dscala.home=\"$PROG_HOME\"" \
9192
"dotty.tools.MainGenericCompiler" \

dist/bin/scalac.bat

+3-30
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ call :compilerJavaClasspathArgs
2424
@rem we need to escape % in the java command path, for some reason this doesnt work in common.bat
2525
set "_JAVACMD=!_JAVACMD:%%=%%%%!"
2626

27-
call "%_JAVACMD%" %_JAVA_ARGS% -classpath "%_JVM_CP_ARGS%" "-Dscala.usejavacp=true" "-Dscala.home=%_PROG_HOME%" dotty.tools.MainGenericCompiler %_SCALA_ARGS%
27+
call "%_JAVACMD%" %_JAVA_ARGS% -classpath "%_JVM_CP_ARGS%" "-Dscala.usejavacp=true" "-Dscala.expandjavacp=true" "-Dscala.home=%_PROG_HOME%" dotty.tools.MainGenericCompiler %_SCALA_ARGS%
2828
if not %ERRORLEVEL%==0 (
2929
set _EXITCODE=1
3030
goto end
@@ -88,17 +88,8 @@ goto :eof
8888

8989
@rem output parameter: _JVM_CP_ARGS
9090
:compilerJavaClasspathArgs
91-
92-
set "CP_FILE=%_ETC_DIR%\scala.classpath"
93-
call :loadClasspathFromFile %CP_FILE%
94-
set "__TOOLCHAIN=%_CLASS_PATH_RESULT%"
95-
96-
set "CP_FILE=%_ETC_DIR%\with_compiler.classpath"
97-
call :loadClasspathFromFile %CP_FILE%
98-
99-
if defined _CLASS_PATH_RESULT (
100-
set "__TOOLCHAIN=%__TOOLCHAIN%%_PSEP%%_CLASS_PATH_RESULT%"
101-
)
91+
set "__TOOLCHAIN=%_LIB_DIR%\scala.jar"
92+
set "__TOOLCHAIN=%__TOOLCHAIN%%_PSEP%%_LIB_DIR%\with_compiler.jar%"
10293

10394
if defined _SCALA_CPATH (
10495
set "_JVM_CP_ARGS=%__TOOLCHAIN%%_SCALA_CPATH%"
@@ -107,24 +98,6 @@ if defined _SCALA_CPATH (
10798
)
10899
goto :eof
109100

110-
@REM concatentate every line in "%_ARG_FILE%" with _PSEP
111-
@REM arg 1 - file to read
112-
:loadClasspathFromFile
113-
set _ARG_FILE=%1
114-
set _CLASS_PATH_RESULT=
115-
if exist "%_ARG_FILE%" (
116-
for /f "usebackq delims=" %%i in ("%_ARG_FILE%") do (
117-
set "_LIB=%_PROG_HOME%\maven2\%%i"
118-
set "_LIB=!_LIB:/=\!"
119-
if not defined _CLASS_PATH_RESULT (
120-
set "_CLASS_PATH_RESULT=!_LIB!"
121-
) else (
122-
set "_CLASS_PATH_RESULT=!_CLASS_PATH_RESULT!%_PSEP%!_LIB!"
123-
)
124-
)
125-
)
126-
goto :eof
127-
128101
@rem #########################################################################
129102
@rem ## Cleanups
130103

dist/bin/scaladoc

+3-9
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ CompilerMain=dotty.tools.dotc.Main
3636
DecompilerMain=dotty.tools.dotc.decompiler.Main
3737
ReplMain=dotty.tools.repl.Main
3838
ScriptingMain=dotty.tools.scripting.Main
39+
JVM_CP_ARGS="$PROG_HOME/lib/scaladoc.jar"
3940

4041
PROG_NAME=$CompilerMain
4142

@@ -52,12 +53,6 @@ addScrip() {
5253
script_args+=("'$1'")
5354
}
5455

55-
classpathArgs () {
56-
CLASS_PATH="$(load_classpath "scaladoc" "$PSEP")"
57-
58-
jvm_cp_args="-classpath \"$CLASS_PATH\""
59-
}
60-
6156
#for A in "$@" ; do echo "A[$A]" ; done ; exit 2
6257

6358
while [[ $# -gt 0 ]]; do
@@ -79,12 +74,11 @@ case "$1" in
7974
esac
8075
done
8176

82-
classpathArgs
83-
8477
eval "\"$JAVACMD\"" \
8578
${JAVA_OPTS:-$default_java_opts} \
8679
"${java_args[@]}" \
87-
"${jvm_cp_args-}" \
80+
-classpath "${JVM_CP_ARGS}" \
81+
-Dscala.expandjavacp=true \
8882
-Dscala.usejavacp=true \
8983
"dotty.tools.scaladoc.Main" \
9084
"${scala_args[@]}" \

dist/bin/scaladoc.bat

+2-26
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ call :args %*
2121
@rem #########################################################################
2222
@rem ## Main
2323

24-
call :classpathArgs
25-
2624
if defined JAVA_OPTS ( set _JAVA_OPTS=%JAVA_OPTS%
2725
) else ( set _JAVA_OPTS=%_DEFAULT_JAVA_OPTS%
2826
)
@@ -31,7 +29,8 @@ if defined JAVA_OPTS ( set _JAVA_OPTS=%JAVA_OPTS%
3129
set "_JAVACMD=!_JAVACMD:%%=%%%%!"
3230

3331
call "%_JAVACMD%" %_JAVA_OPTS% %_JAVA_DEBUG% %_JAVA_ARGS% ^
34-
-classpath "%_CLASS_PATH%" ^
32+
-classpath "%_LIB_DIR%\scaladoc.jar" ^
33+
-Dscala.expandjavacp=true ^
3534
-Dscala.usejavacp=true ^
3635
dotty.tools.scaladoc.Main %_SCALA_ARGS% %_RESIDUAL_ARGS%
3736
if not %ERRORLEVEL%==0 (
@@ -103,29 +102,6 @@ goto :eof
103102
set _RESIDUAL_ARGS=%_RESIDUAL_ARGS% %~1
104103
goto :eof
105104

106-
@rem output parameter: _CLASS_PATH
107-
:classpathArgs
108-
set "_ETC_DIR=%_PROG_HOME%\etc"
109-
@rem keep list in sync with bash script `bin\scaladoc` !
110-
call :loadClasspathFromFile
111-
goto :eof
112-
113-
@REM concatentate every line in "%_ETC_DIR%\scaladoc.classpath" with _PSEP
114-
:loadClasspathFromFile
115-
set _CLASS_PATH=
116-
if exist "%_ETC_DIR%\scaladoc.classpath" (
117-
for /f "usebackq delims=" %%i in ("%_ETC_DIR%\scaladoc.classpath") do (
118-
set "_LIB=%_PROG_HOME%\maven2\%%i"
119-
set "_LIB=!_LIB:/=\!"
120-
if not defined _CLASS_PATH (
121-
set "_CLASS_PATH=!_LIB!"
122-
) else (
123-
set "_CLASS_PATH=!_CLASS_PATH!%_PSEP%!_LIB!"
124-
)
125-
)
126-
)
127-
goto :eof
128-
129105
@rem #########################################################################
130106
@rem ## Cleanups
131107

project/Build.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2134,7 +2134,7 @@ object Build {
21342134
republishRepo := target.value / "republish",
21352135
packResourceDir += (republishRepo.value / "bin" -> "bin"),
21362136
packResourceDir += (republishRepo.value / "maven2" -> "maven2"),
2137-
packResourceDir += (republishRepo.value / "etc" -> "etc"),
2137+
packResourceDir += (republishRepo.value / "lib" -> "lib"),
21382138
republishCommandLibs +=
21392139
("scala" -> List("scala3-interfaces", "scala3-compiler", "scala3-library", "tasty-core")),
21402140
republishCommandLibs +=

project/RepublishPlugin.scala

+10-2
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,24 @@ object RepublishPlugin extends AutoPlugin {
213213
val classpaths = coursierFetch(coursierJar, log, csrCacheDir, localRepo, resolvedLocal.map(_.id.toString))
214214

215215
if (commandLibs.nonEmpty) {
216-
IO.createDirectory(republishDir / "etc")
216+
IO.createDirectory(republishDir / "lib")
217217
for ((command, libs) <- commandLibs) {
218218
val (negated, actual) = libs.partition(_.startsWith("^!"))
219219
val subtractions = negated.map(_.stripPrefix("^!"))
220220

221221
def compose(libs: List[String]): List[String] =
222222
libs.map(fuzzyFind(classpaths, _)).reduceOption(_ ++ _).map(_.distinct).getOrElse(Nil)
223223

224+
// Compute the classpath entries
224225
val entries = compose(actual).diff(compose(subtractions))
225-
IO.write(republishDir / "etc" / s"$command.classpath", entries.mkString("\n"))
226+
// Generate the MANIFEST for the pathing jar
227+
val manifest = new java.util.jar.Manifest();
228+
manifest.getMainAttributes().put(java.util.jar.Attributes.Name.MANIFEST_VERSION, "1.0");
229+
manifest.getMainAttributes().put(java.util.jar.Attributes.Name.CLASS_PATH, entries.map(e => s"../maven2/$e").mkString(" "))
230+
// Write the pathing jar to the Disk
231+
val file = republishDir / "lib" / s"$command.jar"
232+
val jar = new java.util.jar.JarOutputStream(new java.io.FileOutputStream(file), manifest)
233+
jar.close()
226234
}
227235
}
228236

0 commit comments

Comments
 (0)