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

Commit 8b87fab

Browse files
authored
Merge pull request #54 from szeiger/wip/config-cleanup
A trip down the rabbit hole to enable colors from sbt
2 parents 4492e81 + c0ec7fa commit 8b87fab

File tree

11 files changed

+232
-268
lines changed

11 files changed

+232
-268
lines changed

src/main/scala/scala/tools/partest/PartestTask.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,7 @@ class PartestTask extends Task with CompilationPathProperty with ScalaTask {
118118
}
119119

120120
override def execute() {
121-
if (debug || propOrFalse("partest.debug")) {
122-
NestUI.setDebug()
123-
}
121+
val nestUI: NestUI = new NestUI(debug = debug || propOrFalse("partest.debug"))
124122

125123
if (compilationPath.isEmpty) sys.error("Mandatory attribute 'compilationPath' is not set.")
126124

@@ -130,7 +128,7 @@ class PartestTask extends Task with CompilationPathProperty with ScalaTask {
130128
})
131129

132130
var failureCount = 0
133-
val summary = new scala.tools.partest.nest.AntRunner(srcDir.getOrElse(null), new URLClassLoader(compilationPath.get.list.map(Path(_).toURL)), javacmd.getOrElse(null), javaccmd.getOrElse(null), scalacArgsFlat, javaOpts) {
131+
val summary = new scala.tools.partest.nest.AntRunner(srcDir.getOrElse(null), new URLClassLoader(compilationPath.get.list.map(Path(_).toURL)), javacmd.getOrElse(null), javaccmd.getOrElse(null), scalacArgsFlat, javaOpts, nestUI) {
134132
def echo(msg: String): Unit = PartestTask.this.log(msg)
135133
def log(msg: String): Unit = PartestTask.this.log(msg)
136134

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

Lines changed: 107 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,47 @@ import scala.tools.nsc.Properties.{ versionMsg, propOrFalse, setProp }
1212
import scala.collection.{ mutable, immutable }
1313
import TestKinds._
1414
import scala.reflect.internal.util.Collections.distinctBy
15-
import scala.tools.cmd.{ CommandLine, CommandLineParser, Instance }
1615

17-
abstract class AbstractRunner(argstr: String) extends {
18-
val parsed = RunnerSpec.creator(CommandLineParser tokenize argstr)
19-
} with RunnerSpec with Instance {
16+
abstract class AbstractRunner {
17+
18+
val config: RunnerSpec.Config
19+
20+
lazy val nestUI: NestUI = new NestUI(
21+
verbose = config.optVerbose,
22+
debug = config.optDebug || propOrFalse("partest.debug"),
23+
terse = config.optTerse,
24+
diffOnFail = config.optShowDiff,
25+
logOnFail = config.optShowLog,
26+
colorEnabled = colorEnabled
27+
)
2028

2129
val suiteRunner: SuiteRunner
2230

23-
import suiteRunner._
24-
import NestUI._
25-
import NestUI.color._
31+
protected val printSummary = true
32+
protected val partestCmd = "test/partest"
33+
protected val colorEnabled = sys.props contains "partest.colors"
34+
35+
private[this] var totalTests = 0
36+
private[this] val passedTests = mutable.ListBuffer[TestState]()
37+
private[this] val failedTests = mutable.ListBuffer[TestState]()
38+
39+
private[this] var summarizing = false
40+
private[this] var elapsedMillis = 0L
41+
private[this] var expectedFailures = 0
2642

27-
private var totalTests = 0
28-
private val passedTests = mutable.ListBuffer[TestState]()
29-
private val failedTests = mutable.ListBuffer[TestState]()
43+
import nestUI._
44+
import nestUI.color._
3045

31-
def comment(s: String) = echo(magenta("# " + s))
32-
def levyJudgment() = {
46+
private[this] def comment(s: String) = echo(magenta("# " + s))
47+
48+
private[this] def levyJudgment() = {
3349
if (totalTests == 0) echoMixed("No tests to run.")
3450
else if (elapsedMillis == 0) echoMixed("Test Run ABORTED")
3551
else if (isSuccess) echoPassed("Test Run PASSED")
3652
else echoFailed("Test Run FAILED")
3753
}
3854

39-
def passFailString(passed: Int, failed: Int, skipped: Int): String = {
55+
private[this] def passFailString(passed: Int, failed: Int, skipped: Int): String = {
4056
val total = passed + failed + skipped
4157
val isSuccess = failed == 0
4258
def p0 = s"$passed/$total"
@@ -47,12 +63,7 @@ abstract class AbstractRunner(argstr: String) extends {
4763
oempty(p, f, s) mkString ", "
4864
}
4965

50-
protected var partestCmd = "test/partest"
51-
protected var summarizing = false
52-
protected var printSummary = true
53-
private var elapsedMillis = 0L
54-
private var expectedFailures = 0
55-
protected def isSuccess = failedTests.size == expectedFailures
66+
private[this] def isSuccess = failedTests.size == expectedFailures
5667

5768
def issueSummaryReport() {
5869
// Don't run twice
@@ -69,7 +80,7 @@ abstract class AbstractRunner(argstr: String) extends {
6980
val message = passFail + elapsed
7081

7182
if (failed0.nonEmpty) {
72-
if (isPartestVerbose) {
83+
if (nestUI.verbose) {
7384
echo(bold(cyan("##### Transcripts from failed tests #####\n")))
7485
failed0 foreach { state =>
7586
comment(partestCmd + " " + state.testFile)
@@ -89,97 +100,93 @@ abstract class AbstractRunner(argstr: String) extends {
89100
}
90101
}
91102

92-
def run(): Unit = {
93-
if (optDebug || propOrFalse("partest.debug")) NestUI.setDebug()
94-
if (optVerbose) NestUI.setVerbose()
95-
if (optTerse) NestUI.setTerse()
96-
if (optShowDiff) NestUI.setDiffOnFail()
97-
if (optShowLog) NestUI.setLogOnFail()
98-
99-
// Early return on no args, version, or invalid args
100-
if (optVersion) return echo(versionMsg)
101-
if (optHelp) return NestUI.usage()
102-
103-
val (individualTests, invalid) = parsed.residualArgs map (p => Path(p)) partition denotesTestPath
104-
if (invalid.nonEmpty) {
105-
if (isPartestVerbose)
106-
invalid foreach (p => echoWarning(s"Discarding invalid test path " + p))
107-
else if (!isPartestTerse)
108-
echoWarning(s"Discarding ${invalid.size} invalid test paths")
109-
}
103+
/** Run the tests and return the success status */
104+
def run(): Boolean = {
105+
if (config.optVersion) echo(versionMsg)
106+
else if (config.optHelp) nestUI.usage()
107+
else {
108+
val (individualTests, invalid) = config.parsed.residualArgs map (p => Path(p)) partition denotesTestPath
109+
if (invalid.nonEmpty) {
110+
if (nestUI.verbose)
111+
invalid foreach (p => echoWarning(s"Discarding invalid test path " + p))
112+
else if (!nestUI.terse)
113+
echoWarning(s"Discarding ${invalid.size} invalid test paths")
114+
}
110115

111-
optTimeout foreach (x => setProp("partest.timeout", x))
116+
config.optTimeout foreach (x => setProp("partest.timeout", x))
112117

113-
if (!isPartestTerse)
114-
NestUI echo banner
118+
if (!nestUI.terse)
119+
nestUI.echo(suiteRunner.banner)
115120

116-
val partestTests = (
117-
if (optSelfTest) TestKinds.testsForPartest
118-
else Nil
119-
)
121+
val partestTests = (
122+
if (config.optSelfTest) TestKinds.testsForPartest
123+
else Nil
124+
)
120125

121-
val grepExpr = optGrep getOrElse ""
126+
val grepExpr = config.optGrep getOrElse ""
122127

123-
// If --grep is given we suck in every file it matches.
124-
// TODO: intersect results of grep with specified kinds, if any
125-
val greppedTests = if (grepExpr == "") Nil else {
126-
val paths = grepFor(grepExpr)
127-
if (paths.isEmpty)
128-
echoWarning(s"grep string '$grepExpr' matched no tests.\n")
128+
// If --grep is given we suck in every file it matches.
129+
// TODO: intersect results of grep with specified kinds, if any
130+
val greppedTests = if (grepExpr == "") Nil else {
131+
val paths = grepFor(grepExpr)
132+
if (paths.isEmpty)
133+
echoWarning(s"grep string '$grepExpr' matched no tests.\n")
129134

130-
paths.sortBy(_.toString)
131-
}
135+
paths.sortBy(_.toString)
136+
}
132137

133-
val isRerun = optFailed
134-
val rerunTests = if (isRerun) TestKinds.failedTests else Nil
135-
def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests
136-
137-
val givenKinds = standardKinds filter parsed.isSet
138-
val kinds = (
139-
if (givenKinds.nonEmpty) givenKinds
140-
else if (miscTests.isEmpty) standardKinds // If no kinds, --grep, or individual tests were given, assume --all
141-
else Nil
142-
)
143-
val kindsTests = kinds flatMap testsFor
144-
145-
def testContributors = {
146-
List(
147-
if (partestTests.isEmpty) "" else "partest self-tests",
148-
if (rerunTests.isEmpty) "" else "previously failed tests",
149-
if (kindsTests.isEmpty) "" else s"${kinds.size} named test categories",
150-
if (greppedTests.isEmpty) "" else s"${greppedTests.size} tests matching '$grepExpr'",
151-
if (individualTests.isEmpty) "" else "specified tests"
152-
) filterNot (_ == "") mkString ", "
153-
}
138+
val isRerun = config.optFailed
139+
val rerunTests = if (isRerun) TestKinds.failedTests else Nil
140+
def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests
141+
142+
val givenKinds = standardKinds filter config.parsed.isSet
143+
val kinds = (
144+
if (givenKinds.nonEmpty) givenKinds
145+
else if (miscTests.isEmpty) standardKinds // If no kinds, --grep, or individual tests were given, assume --all
146+
else Nil
147+
)
148+
val kindsTests = kinds flatMap testsFor
149+
150+
def testContributors = {
151+
List(
152+
if (partestTests.isEmpty) "" else "partest self-tests",
153+
if (rerunTests.isEmpty) "" else "previously failed tests",
154+
if (kindsTests.isEmpty) "" else s"${kinds.size} named test categories",
155+
if (greppedTests.isEmpty) "" else s"${greppedTests.size} tests matching '$grepExpr'",
156+
if (individualTests.isEmpty) "" else "specified tests"
157+
) filterNot (_ == "") mkString ", "
158+
}
154159

155-
val allTests: Array[Path] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) toArray
156-
val grouped = (allTests groupBy kindOf).toArray sortBy (x => standardKinds indexOf x._1)
160+
val allTests: Array[Path] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) toArray
161+
val grouped = (allTests groupBy kindOf).toArray sortBy (x => standardKinds indexOf x._1)
157162

158-
totalTests = allTests.size
159-
expectedFailures = propOrNone("partest.errors") match {
160-
case Some(num) => num.toInt
161-
case _ => 0
162-
}
163-
val expectedFailureMessage = if (expectedFailures == 0) "" else s" (expecting $expectedFailures to fail)"
164-
echo(s"Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n")
165-
166-
val (_, millis) = timed {
167-
for ((kind, paths) <- grouped) {
168-
val num = paths.size
169-
val ss = if (num == 1) "" else "s"
170-
comment(s"starting $num test$ss in $kind")
171-
val results = runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind)
172-
val (passed, failed) = results partition (_.isOk)
173-
174-
passedTests ++= passed
175-
failedTests ++= failed
176-
if (failed.nonEmpty) {
177-
comment(passFailString(passed.size, failed.size, 0) + " in " + kind)
163+
totalTests = allTests.size
164+
expectedFailures = propOrNone("partest.errors") match {
165+
case Some(num) => num.toInt
166+
case _ => 0
167+
}
168+
val expectedFailureMessage = if (expectedFailures == 0) "" else s" (expecting $expectedFailures to fail)"
169+
echo(s"Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n")
170+
171+
val (_, millis) = timed {
172+
for ((kind, paths) <- grouped) {
173+
val num = paths.size
174+
val ss = if (num == 1) "" else "s"
175+
comment(s"starting $num test$ss in $kind")
176+
val results = suiteRunner.runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind)
177+
val (passed, failed) = results partition (_.isOk)
178+
179+
passedTests ++= passed
180+
failedTests ++= failed
181+
if (failed.nonEmpty) {
182+
comment(passFailString(passed.size, failed.size, 0) + " in " + kind)
183+
}
184+
echo("")
178185
}
179-
echo("")
180186
}
187+
this.elapsedMillis = millis
188+
issueSummaryReport()
181189
}
182-
this.elapsedMillis = millis
183-
issueSummaryReport()
190+
isSuccess
184191
}
185192
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ package nest
1212
import java.net.URLClassLoader
1313

1414
// not using any Scala types to ease calling across different scala versions
15-
abstract class AntRunner(srcDir: String, testClassLoader: URLClassLoader, javaCmd: File, javacCmd: File, scalacArgs: Array[String], javaOpts: Option[Seq[String]]) extends SuiteRunner(
15+
abstract class AntRunner(srcDir: String, testClassLoader: URLClassLoader, javaCmd: File, javacCmd: File, scalacArgs: Array[String], javaOpts: Option[Seq[String]], nestUI: NestUI) extends SuiteRunner(
1616
testSourcePath = Option(srcDir) getOrElse PartestDefaults.sourcePath,
1717
new FileManager(testClassLoader = testClassLoader),
1818
updateCheck = false,
1919
failed = false,
20+
nestUI = nestUI,
2021
javaCmdPath = Option(javaCmd).map(_.getAbsolutePath) getOrElse PartestDefaults.javaCmd,
2122
javacCmdPath = Option(javacCmd).map(_.getAbsolutePath) getOrElse PartestDefaults.javacCmd,
2223
scalacExtraArgs = scalacArgs,

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

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,24 @@
33
* @author Philipp Haller
44
*/
55

6-
package scala.tools
7-
package partest
6+
package scala.tools.partest
87
package nest
98

10-
class ConsoleRunner(argstr: String) extends AbstractRunner(argstr) {
11-
12-
override val suiteRunner = new SuiteRunner (
13-
testSourcePath = optSourcePath getOrElse PartestDefaults.sourcePath,
9+
class ConsoleRunner(val config: RunnerSpec.Config) extends AbstractRunner {
10+
val suiteRunner = new SuiteRunner (
11+
testSourcePath = config.optSourcePath getOrElse PartestDefaults.sourcePath,
1412
fileManager = new FileManager(ClassPath split PathResolver.Environment.javaUserClassPath map (Path(_))), // the script sets up our classpath for us via ant
15-
updateCheck = optUpdateCheck,
16-
failed = optFailed)
17-
18-
// So we can ctrl-C a test run and still hear all
19-
// the buffered failure info.
20-
scala.sys addShutdownHook issueSummaryReport()
21-
22-
override def run(): Unit = {
23-
super.run()
24-
System exit ( if (isSuccess) 0 else 1 )
25-
}
26-
27-
run()
13+
updateCheck = config.optUpdateCheck,
14+
failed = config.optFailed,
15+
nestUI = nestUI)
2816
}
2917

3018
object ConsoleRunner {
3119
def main(args: Array[String]): Unit = {
32-
new ConsoleRunner(args mkString " ")
20+
val r = new ConsoleRunner(RunnerSpec.forArgs(args))
21+
// So we can ctrl-C a test run and still hear all
22+
// the buffered failure info.
23+
scala.sys addShutdownHook r.issueSummaryReport()
24+
System.exit( if (r.run) 0 else 1 )
3325
}
3426
}
35-

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class DirectCompiler(val runner: Runner) {
107107
}
108108

109109
def ids = sources.map(_.testIdent) mkString space
110-
vlog(s"% scalac $ids")
110+
nestUI.vlog(s"% scalac $ids")
111111

112112
def execCompile() =
113113
if (command.shouldStopWithInfo) {

0 commit comments

Comments
 (0)