Skip to content

Commit 30059d2

Browse files
committed
Part 12 - rework contrib.scoverage.api to be java based.
1 parent 38ba5e8 commit 30059d2

File tree

8 files changed

+204
-95
lines changed

8 files changed

+204
-95
lines changed

contrib/package.mill

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,7 @@ object `package` extends RootModule {
103103
}
104104

105105
object scoverage extends ContribModule {
106-
object api extends build.MillPublishScalaModule {
107-
def compileModuleDeps = Seq(build.main.api)
108-
}
106+
object api extends build.MillPublishJavaModule
109107

110108
def moduleDeps = Seq(scoverage.api)
111109
def compileModuleDeps = Seq(build.scalalib)
@@ -132,7 +130,6 @@ object `package` extends RootModule {
132130
object worker extends build.MillPublishScalaModule {
133131
// scoverage is on an old Scala version which doesnt support scalafix
134132
def fix(args: String*): Command[Unit] = T.command {}
135-
def compileModuleDeps = Seq(build.main.api)
136133
def moduleDeps = Seq(scoverage.api)
137134
def testDepPaths = T { Seq(compile().classes) }
138135

@@ -143,7 +140,6 @@ object `package` extends RootModule {
143140

144141
// Worker for Scoverage 2.0
145142
object worker2 extends build.MillPublishScalaModule {
146-
def compileModuleDeps = Seq(build.main.api)
147143
def moduleDeps = Seq(scoverage.api)
148144
def testDepPaths = T { Seq(compile().classes) }
149145
def compileIvyDeps = T {

contrib/scoverage/api/src/mill/contrib/scoverage/api/ScoverageReportWorkerApi.scala

Lines changed: 0 additions & 46 deletions
This file was deleted.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package mill.contrib.scoverage.api;
2+
3+
import java.nio.file.Path;
4+
import java.nio.file.Files;
5+
import java.io.IOException;
6+
import java.io.Serializable;
7+
8+
public interface ScoverageReportWorkerApi2 {
9+
10+
interface Logger {
11+
void info(String msg);
12+
void error(String msg);
13+
void debug(String msg);
14+
}
15+
16+
interface Ctx {
17+
Logger log();
18+
Path dest();
19+
}
20+
21+
public static abstract class ReportType implements Serializable {
22+
private String name;
23+
24+
/*private[api]*/
25+
ReportType(String name) {}
26+
27+
public static final ReportType Console = new ConsoleModule();
28+
public static final FileReportType Html = new HtmlModule();
29+
public static final FileReportType Xml = new XmlModule();
30+
public static final FileReportType XmlCobertura = new XmlCoberturaModule();
31+
32+
/* private[api]*/
33+
static final class ConsoleModule extends ReportType implements Serializable {
34+
/* private[api]*/
35+
ConsoleModule() {
36+
super("Console");
37+
}
38+
};
39+
40+
/* private[api]*/
41+
static final class HtmlModule extends FileReportType implements Serializable {
42+
/* private[api]*/
43+
HtmlModule() {
44+
super("Html", "htmlReport");
45+
}
46+
};
47+
48+
/* private[api]*/
49+
static final class XmlModule extends FileReportType implements Serializable {
50+
/* private[api]*/
51+
XmlModule() {
52+
super("Xml", "xmlReport");
53+
}
54+
}
55+
56+
/* private[api]*/
57+
static final class XmlCoberturaModule extends FileReportType implements Serializable {
58+
/* private[api]*/
59+
XmlCoberturaModule() {
60+
super("XmlCobertura", "xmlCoberturaReport");
61+
}
62+
}
63+
64+
@Override
65+
public String toString() {
66+
return name;
67+
}
68+
}
69+
70+
public static abstract class FileReportType extends ReportType implements Serializable {
71+
private final String folderName;
72+
73+
/*private[api]*/
74+
FileReportType(String name, String folderName) {
75+
super(name);
76+
this.folderName = folderName;
77+
}
78+
79+
public String folderName() {
80+
return folderName;
81+
}
82+
}
83+
84+
void report(ReportType reportType, Path[] sources, Path[] dataDirs, Path sourceRoot, Ctx ctx);
85+
86+
static void makeAllDirs(Path path) throws IOException {
87+
// Replicate behavior of `os.makeDir.all(path)`
88+
if (Files.isDirectory(path) && Files.isSymbolicLink(path)) {
89+
// do nothing
90+
} else {
91+
Files.createDirectories(path);
92+
}
93+
}
94+
95+
}

contrib/scoverage/src/mill/contrib/scoverage/ScoverageModule.scala

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package mill.contrib.scoverage
33
import coursier.Repository
44
import mill._
55
import mill.api.{Loose, PathRef, Result}
6-
import mill.contrib.scoverage.api.ScoverageReportWorkerApi.ReportType
6+
import mill.contrib.scoverage.api.ScoverageReportWorkerApi2.ReportType
77
import mill.main.BuildInfo
88
import mill.scalalib.api.ZincWorkerUtil
99
import mill.scalalib.{Dep, DepSyntax, JavaModule, ScalaModule}
@@ -114,17 +114,23 @@ trait ScoverageModule extends ScalaModule { outer: ScalaModule =>
114114
val millScalaVersion = BuildInfo.scalaVersion
115115

116116
if (sv.startsWith("1.")) {
117+
def clampScalaVersion(): String = {
118+
val v = "2.13.8"
119+
T.log.outputStream.println(
120+
s"Detected an unsupported Scala version (${millScalaVersion}). Using Scala version ${v} to resolve scoverage ${sv} reporting API."
121+
)
122+
v
123+
}
124+
117125
// In Scoverage 1.x, the reporting API is included in the plugin jar
118126
val scalaVersion = millScalaVersion.split("[.]", 4).toList.take(3) match {
119127
// Scoverage 1 is not released for Scala > 2.13.8, but we don't need to compiler specific code,
120128
// only the reporter API, which does not depend on the Compiler API, so using another full Scala version
121129
// should be safe
122130
case "2" :: "13" :: c :: _ if Try(c.toInt).getOrElse(0) > 8 =>
123-
val v = "2.13.8"
124-
T.log.outputStream.println(
125-
s"Detected an unsupported Scala version (${millScalaVersion}). Using Scala version ${v} to resolve scoverage ${sv} reporting API."
126-
)
127-
v
131+
clampScalaVersion()
132+
case "3" :: _ =>
133+
clampScalaVersion()
128134
case _ => millScalaVersion
129135
}
130136
Agg(ivy"org.scoverage:scalac-scoverage-plugin_${scalaVersion}:${sv}")
@@ -159,7 +165,8 @@ trait ScoverageModule extends ScalaModule { outer: ScalaModule =>
159165
millProjectModule(
160166
workerArtifact,
161167
repositoriesTask(),
162-
resolveFilter = _.toString.contains(workerArtifact)
168+
resolveFilter = _.toString.contains(workerArtifact),
169+
artifactSuffix = if (isScov2) "_3" else "_2.13"
163170
)
164171
}
165172

contrib/scoverage/src/mill/contrib/scoverage/ScoverageReport.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package mill.contrib.scoverage
22

3-
import mill.contrib.scoverage.api.ScoverageReportWorkerApi.ReportType
3+
import mill.contrib.scoverage.api.ScoverageReportWorkerApi2.ReportType
44
import mill.define.{Command, Module, Task}
55
import mill.eval.Evaluator
66
import mill.resolve.{Resolve, SelectMode}

contrib/scoverage/src/mill/contrib/scoverage/ScoverageReportWorker.scala

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@ package mill.contrib.scoverage
22

33
import mill.{Agg, Task}
44
import mill.api.{ClassLoader, Ctx, PathRef}
5-
import mill.contrib.scoverage.api.ScoverageReportWorkerApi
5+
import mill.contrib.scoverage.api.ScoverageReportWorkerApi2
66
import mill.define.{Discover, ExternalModule, Worker}
77

8+
import ScoverageReportWorker.ScoverageReportWorkerApiBridge
9+
import ScoverageReportWorkerApi2.ReportType
10+
import ScoverageReportWorkerApi2.Logger as ApiLogger
11+
import ScoverageReportWorkerApi2.Ctx as ApiCtx
12+
813
class ScoverageReportWorker extends AutoCloseable {
9-
private[this] var scoverageClCache = Option.empty[(Long, ClassLoader)]
14+
private var scoverageClCache = Option.empty[(Long, ClassLoader)]
1015

11-
def bridge(classpath: Agg[PathRef])(implicit ctx: Ctx): ScoverageReportWorkerApi = {
16+
def bridge(classpath: Agg[PathRef])(implicit ctx: Ctx): ScoverageReportWorkerApiBridge = {
1217

1318
val classloaderSig = classpath.hashCode
1419
val cl = scoverageClCache match {
@@ -24,11 +29,43 @@ class ScoverageReportWorker extends AutoCloseable {
2429
cl
2530
}
2631

27-
cl
28-
.loadClass("mill.contrib.scoverage.worker.ScoverageReportWorkerImpl")
29-
.getDeclaredConstructor()
30-
.newInstance()
31-
.asInstanceOf[api.ScoverageReportWorkerApi]
32+
val worker =
33+
cl
34+
.loadClass("mill.contrib.scoverage.worker.ScoverageReportWorkerImpl")
35+
.getDeclaredConstructor()
36+
.newInstance()
37+
.asInstanceOf[api.ScoverageReportWorkerApi2]
38+
39+
def ctx0(using ctx: Ctx): ApiCtx = {
40+
val logger = new ApiLogger {
41+
def info(msg: String): Unit = ctx.log.info(msg)
42+
def error(msg: String): Unit = ctx.log.error(msg)
43+
def debug(msg: String): Unit = ctx.log.debug(msg)
44+
}
45+
new {
46+
def log() = logger
47+
def dest() = ctx.dest.toNIO
48+
}
49+
}
50+
51+
new ScoverageReportWorkerApiBridge {
52+
override def report(
53+
reportType: ReportType,
54+
sources: Seq[os.Path],
55+
dataDirs: Seq[os.Path],
56+
sourceRoot: os.Path
57+
)(implicit
58+
ctx: Ctx
59+
): Unit = {
60+
worker.report(
61+
reportType,
62+
sources.map(_.toNIO).toArray,
63+
dataDirs.map(_.toNIO).toArray,
64+
sourceRoot.toNIO,
65+
ctx0
66+
)
67+
}
68+
}
3269
}
3370

3471
override def close(): Unit = {
@@ -37,6 +74,18 @@ class ScoverageReportWorker extends AutoCloseable {
3774
}
3875

3976
object ScoverageReportWorker extends ExternalModule {
77+
import ScoverageReportWorkerApi2.ReportType
78+
79+
trait ScoverageReportWorkerApiBridge {
80+
def report(
81+
reportType: ReportType,
82+
sources: Seq[os.Path],
83+
dataDirs: Seq[os.Path],
84+
sourceRoot: os.Path
85+
)(implicit
86+
ctx: Ctx
87+
): Unit
88+
}
4089

4190
def scoverageReportWorker: Worker[ScoverageReportWorker] =
4291
Task.Worker { new ScoverageReportWorker() }

contrib/scoverage/worker/src/mill/contrib/scoverage/worker/ScoverageReportWorkerImpl.scala

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,47 @@
11
package mill.contrib.scoverage.worker
22

3-
import mill.contrib.scoverage.api.ScoverageReportWorkerApi
43
import _root_.scoverage.report.{
54
CoberturaXmlWriter,
65
CoverageAggregator,
76
ScoverageHtmlWriter,
87
ScoverageXmlWriter
98
}
10-
import mill.api.Ctx
11-
import mill.contrib.scoverage.api.ScoverageReportWorkerApi.ReportType
9+
10+
import mill.contrib.scoverage.api.ScoverageReportWorkerApi2
11+
import ScoverageReportWorkerApi2.ReportType
12+
import ScoverageReportWorkerApi2.Ctx
13+
14+
import java.nio.file.Path
1215

1316
/**
1417
* Scoverage Worker for Scoverage 1.x
1518
*/
16-
class ScoverageReportWorkerImpl extends ScoverageReportWorkerApi {
19+
class ScoverageReportWorkerImpl extends ScoverageReportWorkerApi2 {
1720

1821
override def report(
1922
reportType: ReportType,
20-
sources: Seq[os.Path],
21-
dataDirs: Seq[os.Path],
23+
sources: Array[Path],
24+
dataDirs: Array[Path],
2225
// ignored in Scoverage 1.x
23-
sourceRoot: os.Path
24-
)(implicit ctx: Ctx): Unit =
26+
sourceRoot: Path,
27+
ctx: Ctx
28+
): Unit =
2529
try {
2630
ctx.log.info(s"Processing coverage data for ${dataDirs.size} data locations")
27-
CoverageAggregator.aggregate(dataDirs.map(_.toIO)) match {
31+
CoverageAggregator.aggregate(dataDirs.map(_.toFile).toIndexedSeq) match {
2832
case Some(coverage) =>
29-
val sourceFolders = sources.map(_.toIO)
33+
val sourceFolders = sources.map(_.toFile).toIndexedSeq
3034
val folder = ctx.dest
31-
os.makeDir.all(folder)
35+
ScoverageReportWorkerApi2.makeAllDirs(folder)
3236
reportType match {
3337
case ReportType.Html =>
34-
new ScoverageHtmlWriter(sourceFolders, folder.toIO, None)
38+
new ScoverageHtmlWriter(sourceFolders, folder.toFile, None)
3539
.write(coverage)
3640
case ReportType.Xml =>
37-
new ScoverageXmlWriter(sourceFolders, folder.toIO, false)
41+
new ScoverageXmlWriter(sourceFolders, folder.toFile, false)
3842
.write(coverage)
3943
case ReportType.XmlCobertura =>
40-
new CoberturaXmlWriter(sourceFolders, folder.toIO)
44+
new CoberturaXmlWriter(sourceFolders, folder.toFile)
4145
.write(coverage)
4246
case ReportType.Console =>
4347
ctx.log.info(s"Statement coverage.: ${coverage.statementCoverageFormatted}%")

0 commit comments

Comments
 (0)