@@ -4,6 +4,7 @@ package vulpix
4
4
5
5
import java .io .{File => JFile , IOException }
6
6
import java .lang .System .{lineSeparator => EOL }
7
+ import java .net .URL
7
8
import java .nio .file .StandardCopyOption .REPLACE_EXISTING
8
9
import java .nio .file .{Files , NoSuchFileException , Path , Paths }
9
10
import java .nio .charset .StandardCharsets
@@ -127,10 +128,10 @@ trait ParallelTesting extends RunnerOrchestration { self =>
127
128
}
128
129
sb.toString + " \n\n "
129
130
}
130
- case self : SeparateCompilationSource => {
131
+ case self : SeparateCompilationSource => { // TODO: this is incorrect when using other versions of compiler
131
132
val command = sb.toString
132
133
val fsb = new StringBuilder (command)
133
- self.compilationGroups.foreach { files =>
134
+ self.compilationGroups.foreach { (_, files) =>
134
135
files.map(_.getPath).foreach { path =>
135
136
fsb.append(delimiter)
136
137
lineLen = 8
@@ -173,31 +174,28 @@ trait ParallelTesting extends RunnerOrchestration { self =>
173
174
flags : TestFlags ,
174
175
outDir : JFile
175
176
) extends TestSource {
176
-
177
- /** Get the files grouped by `_X` as a list of groups, files missing this
178
- * suffix will be put into the same group.
179
- * Files in each group are sorted alphabetically.
180
- *
181
- * Filters out all none source files
182
- */
183
- def compilationGroups : List [Array [JFile ]] =
184
- dir
185
- .listFiles
186
- .groupBy { file =>
187
- val name = file.getName
188
- Try {
189
- val potentialNumber = name
190
- .substring(0 , name.lastIndexOf('.' ))
191
- .reverse.takeWhile(_ != '_' ).reverse
192
-
193
- potentialNumber.toInt.toString
194
- }
195
- .toOption
196
- .getOrElse(" " )
197
- }
198
- .toList.sortBy(_._1).map(_._2.filter(isSourceFile).sorted)
199
-
200
- def sourceFiles : Array [JFile ] = compilationGroups.flatten.toArray
177
+ case class Group (ordinal : Int , compiler : String , target : String )
178
+
179
+ def compilationGroups : List [(Group , Array [JFile ])] =
180
+ val Name = """ [^_]*((?:_.*)*)\.\w+""" .r
181
+ val Target = """ t([\d\.]+)""" .r
182
+ val Compiler = """ v([\d\.]+)""" .r
183
+ val Ordinal = """ (\d+)""" .r
184
+ def groupFor (file : JFile ): Group =
185
+ val Name (annotPart) = file.getName
186
+ val annots = annotPart.split(" _" )
187
+ val ordinal = annots.collectFirst { case Ordinal (n) => n.toInt }.getOrElse(Int .MinValue )
188
+ val target = annots.collectFirst { case Target (t) => t }.getOrElse(" " )
189
+ val compiler = annots.collectFirst { case Compiler (c) => c}.getOrElse(" " )
190
+ Group (ordinal, compiler, target)
191
+
192
+ dir.listFiles
193
+ .groupBy(groupFor)
194
+ .toList
195
+ .sortBy { (g, _) => (g.ordinal, g.compiler, g.target) }
196
+ .map { (g, f) => (g, f.sorted) }
197
+
198
+ def sourceFiles = compilationGroups.map(_._2).flatten.toArray
201
199
}
202
200
203
201
private trait CompilationLogic { this : Test =>
@@ -216,7 +214,12 @@ trait ParallelTesting extends RunnerOrchestration { self =>
216
214
List (reporter)
217
215
218
216
case testSource @ SeparateCompilationSource (_, dir, flags, outDir) =>
219
- testSource.compilationGroups.map(files => compile(files, flags, suppressErrors, outDir)) // TODO? only `compile` option?
217
+ testSource.compilationGroups.map { (group, files) =>
218
+ if group.compiler.isEmpty then
219
+ compile(files, flags, suppressErrors, outDir)
220
+ else
221
+ compileWithOtherCompiler(group.compiler, files, flags, outDir)
222
+ }
220
223
})
221
224
222
225
final def countErrorsAndWarnings (reporters : Seq [TestReporter ]): (Int , Int ) =
@@ -500,6 +503,18 @@ trait ParallelTesting extends RunnerOrchestration { self =>
500
503
reporter
501
504
}
502
505
506
+ protected def compileWithOtherCompiler (compiler : String , files : Array [JFile ], flags : TestFlags , targetDir : JFile ): TestReporter =
507
+ val reporter = TestReporter .reporter(realStdout, ERROR ) // TODO: do some reporting
508
+
509
+ val command = Array (getCompiler(compiler).toString + " /bin/scalac" ) ++ flags.and(" -d" , targetDir.getPath).all ++ files.map(_.getPath)
510
+ val process = Runtime .getRuntime.exec(command)
511
+ val output = Source .fromInputStream(process.getErrorStream).mkString
512
+ if process.waitFor() != 0 then
513
+ echo(s " \n Compilation using Scala $compiler failed: \n $output" )
514
+ fail()
515
+
516
+ reporter
517
+
503
518
protected def compileFromTasty (flags0 : TestFlags , suppressErrors : Boolean , targetDir : JFile ): TestReporter = {
504
519
val tastyOutput = new JFile (targetDir.getPath + " _from-tasty" )
505
520
tastyOutput.mkdir()
@@ -1371,4 +1386,26 @@ object ParallelTesting {
1371
1386
1372
1387
def isTastyFile (f : JFile ): Boolean =
1373
1388
f.getName.endsWith(" .tasty" )
1389
+
1390
+ def getCompiler (version : String ): JFile =
1391
+ val patch = trueVersions(version)
1392
+ val dir = cache.resolve(s " scala3- ${patch}" ).toFile
1393
+ if dir.exists then
1394
+ dir
1395
+ else
1396
+ import scala .sys .process ._
1397
+ val zipPath = cache.resolve(s " scala3- $patch.zip " )
1398
+ (URL (s " https://github.com/lampepfl/dotty/releases/download/ $patch/scala3- $patch.zip " ) #>> zipPath.toFile #&& s " unzip $zipPath -d $cache" ).!!
1399
+ dir
1400
+
1401
+
1402
+ private val trueVersions = Map (
1403
+ " 3.0" -> " 3.0.2" ,
1404
+ " 3.1" -> " 3.1.0"
1405
+ )
1406
+
1407
+ private lazy val cache =
1408
+ val dir = Files .createTempDirectory(" dotty.tests" )
1409
+ // dir.toFile.deleteOnExit()
1410
+ dir
1374
1411
}
0 commit comments