Skip to content
This repository was archived by the owner on Sep 8, 2022. It is now read-only.

Commit 2698d6f

Browse files
committed
Further clean up classpath handling
- remove mutation, code duplication - allow versioned jars for scala-library etc by looking only at prefix - specialized lib must come first - don't crash when codelib not found (e.g. for stand-alone scala-xml) - scalacheck classloader: instantiate framework directly - make fileManager lazy to avoid NPE
1 parent ee99827 commit 2698d6f

File tree

9 files changed

+267
-369
lines changed

9 files changed

+267
-369
lines changed

src/main/scala/scala/tools/partest/PartestDefaults.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ object PartestDefaults {
1212
def testRootDir = testRootName map (x => Directory(x))
1313

1414
// def classPath = propOrElse("partest.classpath", "")
15-
def classPath = PathResolver.Environment.javaUserClassPath // XXX
15+
def classPath = ClassPath split PathResolver.Environment.javaUserClassPath // XXX
1616

1717
def javaCmd = propOrElse("partest.javacmd", "java")
1818
def javacCmd = propOrElse("partest.javac_cmd", "javac")

src/main/scala/scala/tools/partest/nest/AntRunner.scala

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,15 @@ abstract class AntRunner(compilationPaths: Array[String], javaCmd: File, javacCm
2727
def onFinishKind(kind: String, passed: Array[TestState], failed: Array[TestState]): Unit
2828
def onFinishTest(testFile: File, result: TestState): TestState = result
2929

30-
private val cpfiles = compilationPaths map { fs => new File(fs) } toList
31-
private def findCp(name: String) = cpfiles find (f =>
32-
(f.getName == s"scala-$name.jar")
33-
|| (f.absolutePathSegments endsWith Seq("classes", name))
34-
) map (_.getAbsolutePath) getOrElse error(s"Provided compilationPath does not contain a Scala $name element.\nLooked in: ${compilationPaths.mkString(":")}")
35-
36-
final val fileManager = new FileManager {
37-
val COMPILATION_CLASSPATH: String = ClassPath.join(compilationPaths: _*)
38-
val LATEST_LIB: String = findCp("library")
39-
val LATEST_REFLECT: String = findCp("reflect")
40-
val LATEST_COMP: String = findCp("compiler")
41-
val testRootPath: String = "test"
42-
val testRootDir: Directory = Directory(testRootPath)
43-
44-
def failed = false
45-
def updateCheck = false
46-
47-
override val JAVACMD: String = Option(javaCmd) map (_.getAbsolutePath) getOrElse "java"
48-
override val JAVAC_CMD: String = Option(javacCmd) map (_.getAbsolutePath) getOrElse "javac"
49-
override def SCALAC_OPTS: Seq[String] = super.SCALAC_OPTS ++ scalacArgs
50-
}
30+
def updateCheck: Boolean = false
31+
def failed: Boolean = false
32+
33+
final lazy val fileManager =
34+
new FileManager(
35+
testClassPath = compilationPaths map { fs => Path(fs) } toList,
36+
javaCmd = Option(javaCmd) map (_.getAbsolutePath),
37+
javacCmd = Option(javacCmd) map (_.getAbsolutePath),
38+
scalacOpts = scalacArgs.toSeq)
5139

5240
final override def runTest(manager: RunnerManager, testFile: File): TestState =
5341
onFinishTest(testFile, manager runTest testFile)

src/main/scala/scala/tools/partest/nest/ConsoleFileManager.scala

Lines changed: 52 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -14,123 +14,93 @@ import scala.util.Properties.{ propOrElse, scalaCmd, scalacCmd }
1414
import scala.tools.nsc.{ io, util }
1515
import PathResolver.{ Environment, Defaults }
1616

17-
case class ConsoleFileManager(
18-
testBuild: Option[String] = PartestDefaults.testBuild,
19-
testClasses: Option[String] = None,
20-
updateCheck: Boolean = false,
21-
failed: Boolean = false) extends FileManager {
22-
def testBuildFile = testBuild map (testParent / _)
23-
24-
lazy val srcDir = PathSettings.srcDir
25-
lazy val testRootDir = PathSettings.testRoot
26-
lazy val testRootPath = testRootDir.toAbsolute.path
27-
def testParent = testRootDir.parent
28-
29-
override def compilerUnderTest =
30-
(if (testClasses.isDefined) testClassesDir
31-
else testBuildFile getOrElse {
32-
latestCompFile.getParentFile.getParentFile.getAbsoluteFile
33-
}).toString
34-
35-
36-
vlog("COMPILATION_CLASSPATH: "+COMPILATION_CLASSPATH)
37-
38-
if (!srcDir.isDirectory) {
39-
NestUI.failure("Source directory \"" + srcDir.path + "\" not found")
40-
sys.exit(1)
41-
}
42-
43-
lazy val COMPILATION_CLASSPATH = {
17+
object ConsoleFileManager {
18+
val classPath = {
19+
val srcDir = {
20+
val src = PathSettings.srcDir
21+
if (!src.isDirectory) {
22+
NestUI.failure("Source directory \"" + src.path + "\" not found")
23+
sys.exit(1)
24+
}
25+
src
26+
}
4427
val libs = (srcDir / Directory("lib")).files filter (_ hasExtension "jar") map (_.toCanonical.path)
4528

4629
// add all jars in libs
47-
(PartestDefaults.classPath :: libs.toList) mkString pathSeparator
30+
val cp = (PartestDefaults.classPath ++ libs.toList)
31+
vlog("testClassPath: " + cp)
32+
cp map (Path(_))
4833
}
4934

50-
def findLatest() {
35+
def mostRecentTrifecta(testBuild: Option[String], testClasses: Option[String]) = {
36+
val testParent = PathSettings.testRoot.parent
37+
val testClassesDir = testClasses map (tc => Path(tc).toCanonical.toDirectory)
38+
val testBuildDir = testBuild map (b => (testParent / b).toCanonical.toDirectory)
39+
5140
vlog("test parent: "+testParent)
5241

5342
def prefixFileWith(parent: File, relPath: String) = (SFile(parent) / relPath).toCanonical
5443
def prefixFile(relPath: String) = (testParent / relPath).toCanonical
5544

56-
if (testClasses.isDefined) {
57-
testClassesDir = Path(testClasses.get).toCanonical.toDirectory
58-
vlog("Running with classes in "+testClassesDir)
59-
60-
latestLibFile = testClassesDir / "library"
61-
latestReflectFile = testClassesDir / "reflect"
62-
latestCompFile = testClassesDir / "compiler"
63-
}
64-
else if (testBuild.isDefined) {
65-
val dir = Path(testBuild.get)
66-
vlog("Running on "+dir)
67-
latestLibFile = dir / "lib/scala-library.jar"
68-
latestReflectFile = dir / "lib/scala-reflect.jar"
69-
latestCompFile = dir / "lib/scala-compiler.jar"
70-
}
71-
else {
72-
def setupQuick() {
45+
(testClassesDir map { testClassesDir => vlog(s"Running with classes in $testClassesDir")
46+
(testClassesDir / "library",
47+
testClassesDir / "reflect",
48+
testClassesDir / "compiler")
49+
}) orElse (testBuildDir map { testBuild => vlog(s"Running on $testBuild")
50+
(testBuild / "lib/scala-library.jar",
51+
testBuild / "lib/scala-reflect.jar",
52+
testBuild / "lib/scala-compiler.jar")
53+
}) getOrElse {
54+
def setupQuick = {
7355
vlog("Running build/quick")
74-
latestLibFile = prefixFile("build/quick/classes/library")
75-
latestReflectFile = prefixFile("build/quick/classes/reflect")
76-
latestCompFile = prefixFile("build/quick/classes/compiler")
56+
(prefixFile("build/quick/classes/library"),
57+
prefixFile("build/quick/classes/reflect"),
58+
prefixFile("build/quick/classes/compiler"))
7759
}
7860

79-
def setupInst() {
61+
def setupInst = {
8062
vlog("Running dist (installed)")
8163
val p = testParent.getParentFile
82-
latestLibFile = prefixFileWith(p, "lib/scala-library.jar")
83-
latestReflectFile = prefixFileWith(p, "lib/scala-reflect.jar")
84-
latestCompFile = prefixFileWith(p, "lib/scala-compiler.jar")
64+
(prefixFileWith(p, "lib/scala-library.jar"),
65+
prefixFileWith(p, "lib/scala-reflect.jar"),
66+
prefixFileWith(p, "lib/scala-compiler.jar"))
8567
}
8668

87-
def setupDist() {
69+
def setupDist = {
8870
vlog("Running dists/latest")
89-
latestLibFile = prefixFile("dists/latest/lib/scala-library.jar")
90-
latestReflectFile = prefixFile("dists/latest/lib/scala-reflect.jar")
91-
latestCompFile = prefixFile("dists/latest/lib/scala-compiler.jar")
71+
(prefixFile("dists/latest/lib/scala-library.jar"),
72+
prefixFile("dists/latest/lib/scala-reflect.jar"),
73+
prefixFile("dists/latest/lib/scala-compiler.jar"))
9274
}
9375

94-
def setupPack() {
76+
def setupPack = {
9577
vlog("Running build/pack")
96-
latestLibFile = prefixFile("build/pack/lib/scala-library.jar")
97-
latestReflectFile = prefixFile("build/pack/lib/scala-reflect.jar")
98-
latestCompFile = prefixFile("build/pack/lib/scala-compiler.jar")
78+
(prefixFile("build/pack/lib/scala-library.jar"),
79+
prefixFile("build/pack/lib/scala-reflect.jar"),
80+
prefixFile("build/pack/lib/scala-compiler.jar"))
9981
}
10082

10183
def mostRecentOf(base: String, names: String*) =
10284
names map (x => prefixFile(base + "/" + x).lastModified) reduceLeft (_ max _)
10385

10486
// detect most recent build
10587
val quickTime = mostRecentOf("build/quick/classes", "compiler/compiler.properties", "reflect/reflect.properties", "library/library.properties")
106-
val packTime = mostRecentOf("build/pack/lib", "scala-compiler.jar", "scala-reflect.jar", "scala-library.jar")
107-
val distTime = mostRecentOf("dists/latest/lib", "scala-compiler.jar", "scala-reflect.jar", "scala-library.jar")
10888
val instTime = mostRecentOf("lib", "scala-compiler.jar", "scala-reflect.jar", "scala-library.jar")
89+
val distTime = mostRecentOf("dists/latest/lib", "scala-compiler.jar", "scala-reflect.jar", "scala-library.jar")
90+
val packTime = mostRecentOf("build/pack/lib", "scala-compiler.jar", "scala-reflect.jar", "scala-library.jar")
10991

11092
val pairs = Map(
111-
(quickTime, () => setupQuick()),
112-
(packTime, () => setupPack()),
113-
(distTime, () => setupDist()),
114-
(instTime, () => setupInst())
93+
(quickTime, () => setupQuick),
94+
(instTime, () => setupInst),
95+
(distTime, () => setupDist),
96+
(packTime, () => setupPack)
11597
)
11698

11799
// run setup based on most recent time
118100
pairs(pairs.keys max)()
119101
}
120-
121-
LATEST_LIB = latestLibFile.getAbsolutePath
122-
LATEST_REFLECT = latestReflectFile.getAbsolutePath
123-
LATEST_COMP = latestCompFile.getAbsolutePath
124102
}
125-
126-
var LATEST_LIB: String = ""
127-
var LATEST_REFLECT: String = ""
128-
var LATEST_COMP: String = ""
129-
130-
var latestLibFile: File = _
131-
var latestReflectFile: File = _
132-
var latestCompFile: File = _
133-
var testClassesDir: Directory = _
134-
// initialize above fields
135-
findLatest()
136103
}
104+
105+
case class ConsoleFileManager(testBuild: Option[String] = PartestDefaults.testBuild, testClasses: Option[String] = None)
106+
extends FileManager(ConsoleFileManager.classPath, ConsoleFileManager.mostRecentTrifecta(testBuild, testClasses))

src/main/scala/scala/tools/partest/nest/ConsoleRunner.scala

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ class ConsoleRunner(argstr: String) extends {
2525
// the buffered failure info.
2626
scala.sys addShutdownHook issueSummaryReport()
2727

28-
lazy val fileManager: ConsoleFileManager = new ConsoleFileManager(
29-
if (optPack) Some("build/pack") else optBuildPath,
30-
optClassPath,
31-
updateCheck = optUpdateCheck,
32-
failed = optFailed)
28+
lazy val fileManager: ConsoleFileManager =
29+
new ConsoleFileManager(if (optPack) Some("build/pack") else optBuildPath, optClassPath)
3330

34-
private var totalTests = 0
31+
def updateCheck = optUpdateCheck
32+
def failed = optFailed
33+
34+
private var totalTests = 0
3535
private val passedTests = mutable.ListBuffer[TestState]()
3636
private val failedTests = mutable.ListBuffer[TestState]()
3737

@@ -47,15 +47,15 @@ class ConsoleRunner(argstr: String) extends {
4747
val total = passed + failed + skipped
4848
val isSuccess = failed == 0
4949
def p0 = s"$passed/$total"
50-
def p = (if (isSuccess) bold(green(p0)) else p0) + " passed"
51-
def f = if (failed == 0) "" else bold(red("" + failed)) + " failed"
52-
def s = if (skipped == 0) "" else bold(yellow("" + skipped)) + " skipped"
50+
def p = ( if (isSuccess) bold(green(p0)) else p0 ) + " passed"
51+
def f = if (failed == 0) "" else bold(red("" + failed)) + " failed"
52+
def s = if (skipped == 0) "" else bold(yellow("" + skipped)) + " skipped"
5353

5454
oempty(p, f, s) mkString ", "
5555
}
5656

57-
private var summarizing = false
58-
private var elapsedMillis = 0L
57+
private var summarizing = false
58+
private var elapsedMillis = 0L
5959
private var expectedFailures = 0
6060
private def isSuccess = failedTests.size == expectedFailures
6161

@@ -64,14 +64,14 @@ class ConsoleRunner(argstr: String) extends {
6464
if (!summarizing) {
6565
summarizing = true
6666

67-
val passed0 = passedTests.toList
68-
val failed0 = failedTests.toList
69-
val passed = passed0.size
70-
val failed = failed0.size
71-
val skipped = totalTests - (passed + failed)
72-
val passFail = passFailString(passed, failed, skipped)
73-
val elapsed = if (elapsedMillis > 0) " (elapsed time: " + elapsedString(elapsedMillis) + ")" else ""
74-
val message = passFail + elapsed
67+
val passed0 = passedTests.toList
68+
val failed0 = failedTests.toList
69+
val passed = passed0.size
70+
val failed = failed0.size
71+
val skipped = totalTests - (passed + failed)
72+
val passFail = passFailString(passed, failed, skipped)
73+
val elapsed = if (elapsedMillis > 0) " (elapsed time: " + elapsedString(elapsedMillis) + ")" else ""
74+
val message = passFail + elapsed
7575

7676
if (failed0.nonEmpty) {
7777
if (isPartestVerbose) {
@@ -159,8 +159,8 @@ class ConsoleRunner(argstr: String) extends {
159159

160160
totalTests = allTests.size
161161
expectedFailures = propOrNone("partest.errors") match {
162-
case Some(num) => num.toInt
163-
case _ => 0
162+
case Some(num) => num.toInt
163+
case _ => 0
164164
}
165165
val expectedFailureMessage = if (expectedFailures == 0) "" else s" (expecting $expectedFailures to fail)"
166166
echo(s"Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n")
@@ -183,9 +183,9 @@ class ConsoleRunner(argstr: String) extends {
183183
}
184184
this.elapsedMillis = millis
185185
issueSummaryReport()
186-
System exit (if (isSuccess) 0 else 1)
186+
System exit ( if (isSuccess) 0 else 1 )
187187
}
188-
188+
189189
run()
190190
}
191191

src/main/scala/scala/tools/partest/nest/DirectCompiler.scala

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,20 @@ class DirectCompiler(val fileManager: FileManager) {
3939
def newGlobal(settings: Settings, logWriter: FileWriter): Global =
4040
newGlobal(settings, new ExtConsoleReporter(settings, new PrintWriter(logWriter)))
4141

42-
def newSettings(): TestSettings = new TestSettings(fileManager.LATEST_LIB)
43-
def newSettings(outdir: String): TestSettings = {
44-
val cp = ClassPath.join(fileManager.LATEST_LIB, outdir)
45-
val s = new TestSettings(cp)
46-
s.outdir.value = outdir
47-
s
48-
}
49-
5042
def compile(runner: Runner, opts0: List[String], sources: List[File]): TestState = {
5143
import runner.{ sources => _, _ }
44+
import ClassPath.{join, split}
45+
46+
// adding codelib.jar to the classpath
47+
// codelib provides the possibility to override standard reify
48+
// this shields the massive amount of reification tests from changes in the API
49+
val codeLib = PathSettings.srcCodeLib.fold[List[Path]](x => Nil, lib => List[Path](lib))
50+
// add the instrumented library version to classpath -- must come first
51+
val specializedOverride: List[Path] = if (kind == "specialized") List(PathSettings.srcSpecLib.fold(sys.error, identity)) else Nil
5252

53-
val testSettings = new TestSettings(ClassPath.join(fileManager.LATEST_LIB, outDir.getPath))
53+
val classPath: List[Path] = specializedOverride ++ codeLib ++ fileManager.testClassPath ++ List[Path](outDir)
54+
55+
val testSettings = new TestSettings(fileManager.joinPaths(classPath))
5456
val logWriter = new FileWriter(logFile)
5557
val srcDir = if (testFile.isDirectory) testFile else Path(testFile).parent.jfile
5658
val opts = fileManager.updatePluginPath(opts0, AbstractFile getDirectory outDir, AbstractFile getDirectory srcDir)
@@ -59,27 +61,11 @@ class DirectCompiler(val fileManager: FileManager) {
5961
val reporter = global.reporter.asInstanceOf[ExtConsoleReporter]
6062
def errorCount = reporter.ERROR.count
6163

62-
def defineSettings(s: Settings) = {
63-
s.outputDirs setSingleOutput outDir.getPath
64-
// adding codelib.jar to the classpath
65-
// codelib provides the possibility to override standard reify
66-
// this shields the massive amount of reification tests from changes in the API
67-
prependToClasspaths(s, codelib)
68-
s.classpath append fileManager.COMPILATION_CLASSPATH // adding this why?
69-
70-
// add the instrumented library version to classpath
71-
if (kind == "specialized")
72-
prependToClasspaths(s, speclib)
73-
74-
// check that option processing succeeded
75-
opts0.isEmpty || command.ok
76-
}
77-
78-
if (!defineSettings(testSettings))
79-
if (opts0.isEmpty)
80-
reporter.error(null, s"bad settings: $testSettings")
81-
else
82-
reporter.error(null, opts0.mkString("bad options: ", space, ""))
64+
testSettings.outputDirs setSingleOutput outDir.getPath
65+
66+
// check that option processing succeeded
67+
if (opts0.nonEmpty && !command.ok)
68+
reporter.error(null, opts0.mkString("bad options: ", space, ""))
8369

8470
def ids = sources.map(_.testIdent) mkString space
8571
vlog(s"% scalac $ids")

0 commit comments

Comments
 (0)