Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isolate scoverage modules from their parent modules #3118

Merged
merged 10 commits into from
Apr 12, 2024
34 changes: 15 additions & 19 deletions contrib/scoverage/src/mill/contrib/scoverage/ScoverageModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package mill.contrib.scoverage
import coursier.Repository
import mill._
import mill.api.{Loose, PathRef, Result}
import mill.main.BuildInfo
import mill.contrib.scoverage.api.ScoverageReportWorkerApi.ReportType
import mill.main.BuildInfo
import mill.scalalib.api.ZincWorkerUtil
import mill.scalalib.{Dep, DepSyntax, JavaModule, ScalaModule}
import mill.util.Util.millProjectModule
Expand Down Expand Up @@ -188,6 +188,7 @@ trait ScoverageModule extends ScalaModule { outer: ScalaModule =>
PathRef(T.dest)
}

override def compileResources: T[Seq[PathRef]] = outer.compileResources
override def generatedSources: Target[Seq[PathRef]] = T { outer.generatedSources() }
override def allSources: Target[Seq[PathRef]] = T { outer.allSources() }
override def moduleDeps: Seq[JavaModule] = outer.moduleDeps
Expand Down Expand Up @@ -225,30 +226,25 @@ trait ScoverageModule extends ScalaModule { outer: ScalaModule =>
def xmlCoberturaReport(): Command[Unit] = T.command { doReport(ReportType.XmlCobertura) }
def consoleReport(): Command[Unit] = T.command { doReport(ReportType.Console) }

override def skipIdea = outer.skipIdea
override def skipIdea = true
}

trait ScoverageTests extends ScalaTests {
override def upstreamAssemblyClasspath = T {
super.upstreamAssemblyClasspath() ++
resolveDeps(T.task {
outer.scoverageRuntimeDeps().map(bindDependency())
})()
}
override def compileClasspath = T {
super.compileClasspath() ++
resolveDeps(T.task {
outer.scoverageRuntimeDeps().map(bindDependency())
})()
}
override def runClasspath = T {
super.runClasspath() ++

/**
* Alter classfiles and resources from upstream modules and dependencies
* by removing the ones from outer.localRunClasspath() and replacing them
* with outer.scoverage.localRunClasspath()
*/
override def runClasspath: T[Seq[PathRef]] = T {
val outerLocalRunClasspath = outer.localRunClasspath().toSet
super.runClasspath().filterNot(
outerLocalRunClasspath
) ++
outer.scoverage.localRunClasspath() ++
resolveDeps(T.task {
outer.scoverageRuntimeDeps().map(bindDependency())
})()
}

// Need the sources compiled with scoverage instrumentation to run.
override def moduleDeps: Seq[JavaModule] = Seq(outer.scoverage)
}
}
60 changes: 60 additions & 0 deletions example/misc/7-contrib-scoverage/build.sc
romain-gilles-ultra marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import mill._, scalalib._
import $ivy.`com.lihaoyi::mill-contrib-scoverage:`

import mill.contrib.scoverage._

object foo extends RootModule with ScoverageModule {
def scoverageVersion = "2.1.0"
def scalaVersion = "2.13.11"
def ivyDeps = Agg(
ivy"com.lihaoyi::scalatags:0.12.0",
ivy"com.lihaoyi::mainargs:0.6.2"
)

object test extends ScoverageTests /*with TestModule.Utest */{
def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.7.11")
def testFramework = "utest.runner.Framework"
}
}

// This is a basic Mill build for a single `ScalaModule`, enhanced with
// Scoverage plugin. The root module extends the `ScoverageModule` and
// specifies the version of scoverage version to use here: `2.1.0`. This
// version can be changed if there is a newer one. Now you can call the
// scoverage targets to produce coverage reports.
// The sub test module extends `ScoverageTests` to transform the
// execution of the various testXXX targets to use scoverage and produce
// coverage data.
// This lets us perform the coverage operations but before that you
// must first run the test.
// `./mill test` then `./mill scoverage.consoleReport` and get your
// coverage into your console output.
//
// You can download this example project using the *download* link above
// if you want to try out the commands below yourself. The only requirement is
// that you have some version of the JVM installed; the `./mill` script takes
// care of any further dependencies that need to be downloaded.

/** Usage

> ./mill test # Run the tests and produce the coverage data
...
+ foo.FooTests.simple ... <h1>hello</h1>
+ foo.FooTests.escaping ... <h1>&lt;hello&gt;</h1>

> ./mill resolve scoverage._ # List what tasks are available to run from scoverage
...
scoverage.consoleReport
...
scoverage.htmlReport
...
scoverage.xmlCoberturaReport
...
scoverage.xmlReport
...

> ./mill scoverage.consoleReport
...
Statement coverage.: 16.67%
Branch coverage....: 100.00%
*/
16 changes: 16 additions & 0 deletions example/misc/7-contrib-scoverage/src/Foo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package foo
import scalatags.Text.all._
import mainargs.{main, ParserForMethods}

object Foo {
def generateHtml(text: String) = {
h1(text).toString
}

@main
def main(text: String) = {
println(generateHtml(text))
}

def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args)
}
16 changes: 16 additions & 0 deletions example/misc/7-contrib-scoverage/test/src/FooTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package foo
import utest._
object FooTests extends TestSuite {
def tests = Tests {
test("simple") {
val result = Foo.generateHtml("hello")
assert(result == "<h1>hello</h1>")
result
}
test("escaping") {
val result = Foo.generateHtml("<hello>")
assert(result == "<h1>&lt;hello&gt;</h1>")
result
}
}
}