Skip to content

Commit 0713790

Browse files
committed
Improve bisect script:
* Support checking runtime success while bisecting * Properly report cases when no release was bad * Get correct results when running the script directly from the repository root
1 parent 6c521ae commit 0713790

File tree

3 files changed

+62
-18
lines changed

3 files changed

+62
-18
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ metals.sbt
3535
.idea_modules
3636
/.worksheet/
3737

38+
# scala-cli
39+
.scala-build
40+
3841
# Partest
3942
dotty.jar
4043
dotty-lib.jar
@@ -90,3 +93,4 @@ compiler/test-coursier/run/*.jar
9093
# docs related
9194
contributors.js
9295
content-contributors.css
96+
project/scripts/dottyCompileBisect.sh

project/scripts/dottyCompileBisect.scala renamed to project/scripts/dottyCompileBisect.sc

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
#!/usr/bin/env -S scala-cli shebang
2+
13
// Usage
2-
// > scala-cli project/scripts/dottyCompileBisect.scala -- File1.scala File2.scala
4+
// > ./project/scripts/dottyCompileBisect.sc [--run <main.class.name>] [<compiler-option> ...] <file1.scala> [<fileN.scala> ...]
35
//
46
// This script will bisect the compilation failure starting with a fast bisection on released nightly builds.
57
// Then it will bisect the commits between the last nightly that worked and the first nightly that failed.
@@ -8,20 +10,41 @@
810
import sys.process._
911
import scala.io.Source
1012
import Releases.Release
13+
import java.io.File
14+
import java.nio.file.{Files, Paths, StandardCopyOption}
15+
16+
17+
//main
18+
dottyCompileBisect(args.toSeq)
1119

12-
@main def dottyCompileBisect(files: String*): Unit =
13-
val releaseBisect = ReleaseBisect(files.toList)
14-
val fistBadRelease = releaseBisect.bisect(Releases.allReleases)
20+
def dottyCompileBisect(args: Seq[String]): Unit =
21+
val (mainClass, compilerArgs) = args match
22+
case Seq("--run", mainClass, compilerArgs*) =>
23+
(Some(mainClass), compilerArgs)
24+
case _ =>
25+
(None, args)
26+
27+
val releaseBisect = ReleaseBisect(mainClass, compilerArgs.toList)
28+
val bisectedBadRelease = releaseBisect.bisectedBadRelease(Releases.allReleases)
1529
println("\nFinished bisecting releases\n")
16-
fistBadRelease.previous match
17-
case Some(lastGoodRelease) =>
18-
println(s"Last good release: $lastGoodRelease\nFirst bad release: $fistBadRelease\n")
19-
val commitBisect = CommitBisect(files.toList)
20-
commitBisect.bisect(lastGoodRelease.hash, fistBadRelease.hash)
30+
31+
bisectedBadRelease match
32+
case Some(firstBadRelease) =>
33+
firstBadRelease.previous match
34+
case Some(lastGoodRelease) =>
35+
println(s"Last good release: $lastGoodRelease")
36+
println(s"First bad release: $firstBadRelease")
37+
val commitBisect = CommitBisect(mainClass, compilerArgs.toList)
38+
commitBisect.bisect(lastGoodRelease.hash, firstBadRelease.hash)
39+
case None =>
40+
println(s"No good release found")
2141
case None =>
22-
println(s"No good release found")
42+
println(s"No bad release found")
2343

24-
class ReleaseBisect(files: List[String]):
44+
class ReleaseBisect(mainClass: Option[String], compilerArgs: List[String]):
45+
def bisectedBadRelease(releases: Vector[Release]): Option[Release] =
46+
Some(bisect(releases: Vector[Release]))
47+
.filter(!isGoodRelease(_))
2548

2649
def bisect(releases: Vector[Release]): Release =
2750
assert(releases.length > 1, "Need at least 2 releases to bisect")
@@ -35,7 +58,12 @@ class ReleaseBisect(files: List[String]):
3558

3659
private def isGoodRelease(release: Release): Boolean =
3760
println(s"Testing ${release.version}")
38-
val res = s"""scala-cli compile ${files.mkString(" ")} -S "${release.version}"""".!
61+
val testCommand = mainClass match
62+
case Some(className) =>
63+
s"run --main-class '$className'"
64+
case None =>
65+
"compile"
66+
val res = s"""scala-cli $testCommand -S '${release.version}' ${compilerArgs.mkString(" ")}""".!
3967
val isGood = res == 0
4068
println(s"Test result: ${release.version} is a ${if isGood then "good" else "bad"} release\n")
4169
isGood
@@ -64,10 +92,14 @@ object Releases:
6492

6593
override def toString: String = version
6694

67-
class CommitBisect(files: List[String]):
95+
class CommitBisect(mainClass: Option[String], compilerArgs: List[String]):
6896
def bisect(lastGoodHash: String, fistBadHash: String): Unit =
6997
println(s"Starting bisecting commits $lastGoodHash..$fistBadHash\n")
98+
val runOption = mainClass.map(className => s"--run $className").getOrElse("")
99+
val scriptFile = Paths.get("project", "scripts", "dottyCompileBisect.sh")
100+
val tempScriptFile = File.createTempFile("dottyCompileBisect", "sh").toPath
101+
Files.copy(scriptFile, tempScriptFile, StandardCopyOption.REPLACE_EXISTING)
70102
"git bisect start".!
71103
s"git bisect bad $fistBadHash".!
72104
s"git bisect good $lastGoodHash".!
73-
s"git bisect run sh project/scripts/dottyCompileBisect.sh ${files.mkString(" ")}".!
105+
s"git bisect run sh ${tempScriptFile.toAbsolutePath} ${runOption} ${compilerArgs.mkString(" ")}".!

project/scripts/dottyCompileBisect.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,23 @@
22
# > git bisect start
33
# > git bisect bad <bad-commit>
44
# > git bisect good <good-commit>
5-
# > git bisect run project/scripts/dottyCompileBisect.sh <file.scala>
5+
# > git bisect run project/scripts/dottyCompileBisect.sh [--run <main.class.name>] [<compiler-option> ...] <file1.scala> [<fileN.scala> ...]
66
#
77
# Note: Use dottyCompileBisect.scala for faster bisection over commits that spans several days
88

9-
files=$@
10-
shift
9+
if [ "$1" == "--run" ]; then
10+
mainClass="$2"
11+
shift; shift
12+
fi
13+
14+
compilerArgs=$@
1115

1216
rm -r out
1317
mkdir out
1418
mkdir out/bisect
1519

16-
sbt "clean; scalac -d out/bisect $files"
20+
if [ -n "$mainClass" ]; then
21+
sbtRunCommand="scala -classpath out/bisect $mainClass"
22+
fi
23+
24+
sbt "clean; scalac -d out/bisect $compilerArgs; $sbtRunCommand"

0 commit comments

Comments
 (0)