11// Usage
2- // > scala-cli project/scripts/dottyCompileBisect.scala -- File1. scala File2 .scala
2+ // > scala-cli project/scripts/dottyCompileBisect.scala -- [--run <main.class.name>] [<compiler-option> ...] <file1. scala> [<fileN .scala> ...]
33//
44// This script will bisect the compilation failure starting with a fast bisection on released nightly builds.
55// Then it will bisect the commits between the last nightly that worked and the first nightly that failed.
88import sys .process ._
99import scala .io .Source
1010import Releases .Release
11+ import java .io .File
12+ import java .nio .file .{Files , Paths , StandardCopyOption }
1113
12- @ main def dottyCompileBisect (files : String * ): Unit =
13- val releaseBisect = ReleaseBisect (files.toList)
14- val fistBadRelease = releaseBisect.bisect(Releases .allReleases)
14+ @ main def dottyCompileBisect (args : String * ): Unit =
15+ val (mainClass, compilerArgs) = args match
16+ case Seq (" --run" , mainClass, compilerArgs* ) =>
17+ (Some (mainClass), compilerArgs)
18+ case _ =>
19+ (None , args)
20+
21+ val releaseBisect = ReleaseBisect (mainClass, compilerArgs.toList)
22+ val bisectedBadRelease = releaseBisect.bisectedBadRelease(Releases .allReleases)
1523 println(" \n Finished bisecting releases\n " )
16- fistBadRelease.previous match
17- case Some (lastGoodRelease) =>
18- println(s " Last good release: $lastGoodRelease\n First bad release: $fistBadRelease\n " )
19- val commitBisect = CommitBisect (files.toList)
20- commitBisect.bisect(lastGoodRelease.hash, fistBadRelease.hash)
24+
25+ bisectedBadRelease match
26+ case Some (firstBadRelease) =>
27+ firstBadRelease.previous match
28+ case Some (lastGoodRelease) =>
29+ println(s " Last good release: $lastGoodRelease" )
30+ println(s " First bad release: $firstBadRelease" )
31+ val commitBisect = CommitBisect (mainClass, compilerArgs.toList)
32+ commitBisect.bisect(lastGoodRelease.hash, firstBadRelease.hash)
33+ case None =>
34+ println(s " No good release found " )
2135 case None =>
22- println(s " No good release found " )
36+ println(s " No bad release found " )
2337
24- class ReleaseBisect (files : List [String ]):
38+ class ReleaseBisect (mainClass : Option [String ], compilerArgs : List [String ]):
39+ def bisectedBadRelease (releases : Vector [Release ]): Option [Release ] =
40+ Some (bisect(releases : Vector [Release ]))
41+ .filter(! isGoodRelease(_))
2542
2643 def bisect (releases : Vector [Release ]): Release =
2744 assert(releases.length > 1 , " Need at least 2 releases to bisect" )
@@ -35,7 +52,12 @@ class ReleaseBisect(files: List[String]):
3552
3653 private def isGoodRelease (release : Release ): Boolean =
3754 println(s " Testing ${release.version}" )
38- val res = s """ scala-cli compile ${files.mkString(" " )} -S " ${release.version}" """ .!
55+ val testCommand = mainClass match
56+ case Some (className) =>
57+ s " run --main-class ' $className' "
58+ case None =>
59+ " compile"
60+ val res = s """ scala-cli $testCommand -S ' ${release.version}' ${compilerArgs.mkString(" " )}""" .!
3961 val isGood = res == 0
4062 println(s " Test result: ${release.version} is a ${if isGood then " good" else " bad" } release \n " )
4163 isGood
@@ -64,10 +86,14 @@ object Releases:
6486
6587 override def toString : String = version
6688
67- class CommitBisect (files : List [String ]):
89+ class CommitBisect (mainClass : Option [ String ], compilerArgs : List [String ]):
6890 def bisect (lastGoodHash : String , fistBadHash : String ): Unit =
6991 println(s " Starting bisecting commits $lastGoodHash.. $fistBadHash\n " )
92+ val runOption = mainClass.map(className => s " --run $className" ).getOrElse(" " )
93+ val scriptFile = Paths .get(" project" , " scripts" , " dottyCompileBisect.sh" )
94+ val tempScriptFile = File .createTempFile(" dottyCompileBisect" , " sh" ).toPath
95+ Files .copy(scriptFile, tempScriptFile, StandardCopyOption .REPLACE_EXISTING )
7096 " git bisect start" .!
7197 s " git bisect bad $fistBadHash" .!
7298 s " git bisect good $lastGoodHash" .!
73- s " git bisect run sh project/scripts/dottyCompileBisect.sh ${files .mkString(" " )}" .!
99+ s " git bisect run sh ${tempScriptFile.toAbsolutePath} ${runOption} ${compilerArgs .mkString(" " )}" .!
0 commit comments