scoverage / gradle-scoverage

A plugin to enable the use of Scoverage in a gradle Scala project
Apache License 2.0
53 stars 38 forks source link

Scala 3 support; Upgrade to Scoverage version 2.0.7 #188

Closed msigmond closed 1 year ago

msigmond commented 2 years ago

Added Scala 3 support, which also required to upgrade to the modularized Scoverage version 2.0.7. I was able to test the plugin against Scala 2.13 as Scala 3 my publishing to the local Maven repository. However the crossScalaVersionTests are failing, I am still working on that. Please review, and let me know your feedback.

maiflai commented 2 years ago

thanks very much - will review the test failures

msigmond commented 2 years ago

Thank you, @maiflai . Here is the error I am seeing:

> Configure project :2_12
Evaluating project ':2_12' using build file '/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/2_12/build.gradle'.
Compiling build file '/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/2_12/build.gradle' using SubsetScriptTransformer.
Compiling build file '/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/2_12/build.gradle' using BuildScriptTransformer.
Using scoverage scalac plugin 2.0.7 for scala 2.13.6

FAILURE: Build failed with an exception.

* Where:
Build file '/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/2_12/build.gradle' line: 2

* What went wrong:
A problem occurred evaluating project ':2_12'.
> Cannot change dependencies of dependency configuration ':2_12:implementation' after it has been included in dependency resolution.

Where in the main branch the build looks as follows:

> Configure project :2_12
Evaluating project ':2_12' using build file '/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/2_12/build.gradle'.
Compiling build file '/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/2_12/build.gradle' using SubsetScriptTransformer.
Compiling build file '/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/2_12/build.gradle' using BuildScriptTransformer.
No Scala version configured. Detecting scala library...
Downloading https://repo.maven.apache.org/maven2/org/scala-lang/scala-library/2.12.8/scala-library-2.12.8.pom to /home/marton/IdeaProjects/gradle-scoverage/build/tmp/crossScalaVersionTest/work/.gradle-test-kit/.tmp/gradle_download15364130658063046665bin
Detected scala library in compilation classpath. Scala version: 2.12.8
Using scoverage scalac plugin 1.4.11 for scala 2.12.8

Any hint is much appreciated.

maiflai commented 2 years ago

I think this is because the scala version is now determined before the project is evaluated?

msigmond commented 2 years ago

I think this is because the scala version is now determined before the project is evaluated?

You were right, this is exactly the issue. I will fix it soon.

msigmond commented 1 year ago

This version now builds fine: all tests go to success. I will add Scala 3 cases to the src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version.

msigmond commented 1 year ago

I added a Scala 3.2 case to the multi module cross version test suite. I intentionally added a Scala 3 enum. However it appears to me that somehow the Scala 2 compiler gets applied, and compilation fails on the enum with the following error:

2022-11-23T19:48:13.405-0500 [DEBUG] [org.gradle.api.internal.tasks.scala.ZincScalaCompilerFactory] Returning already retrieved and compiled bridge: /home/marton/IdeaProjects/gradle-scoverage/build/tmp/crossScalaVersionTest/work/.gradle-test-kit/caches/7.2/zinc-1.3.5_2.13.8_11/compiler-bridge.jar. 2022-11-23T19:48:13.408-0500 [DEBUG] [org.gradle.api.internal.tasks.scala.ZincScalaCompilerFactory] [zinc] Running cached compiler e150d77 for Scala compiler version 2.13.8 2022-11-23T19:48:13.409-0500 [DEBUG] [org.gradle.api.internal.tasks.scala.ZincScalaCompilerFactory] [zinc] The Scala compiler is invoked with: -deprecation -unchecked -bootclasspath /home/marton/IdeaProjects/gradle-scoverage/build/tmp/crossScalaVersionTest/work/.gradle-test-kit/caches/modules-2/files-2.1/org.scala-lang/scala-library/2.13.8/5a865f03a794b27e6491740c4c419a19e4511a3d/scala-library-2.13.8.jar -classpath /home/marton/IdeaProjects/gradle-scoverage/build/tmp/crossScalaVersionTest/work/.gradle-test-kit/caches/modules-2/files-2.1/org.scala-lang/scala3-library_3/3.2.0/d775805d7d73cd4d9d9c734cc04e4d923cd19065/scala3-library_3-3.2.0.jar:/home/marton/IdeaProjects/gradle-scoverage/build/tmp/crossScalaVersionTest/work/.gradle-test-kit/caches/modules-2/files-2.1/org.scala-lang/scala-library/2.13.8/5a865f03a794b27e6491740c4c419a19e4511a3d/scala-library-2.13.8.jar:/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/3_2/build/classes/java/main:/home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/3_2/build/classes/scala/main 2022-11-23T19:48:13.476-0500 [ERROR] [org.gradle.api.internal.tasks.scala.ZincScalaCompilerFactory] [Error] /home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/3_2/src/main/scala/org/hello/World3_2.scala:6: illegal start of simple expression 2022-11-23T19:48:13.476-0500 [ERROR] [org.gradle.api.internal.tasks.scala.ZincScalaCompilerFactory] [Error] /home/marton/IdeaProjects/gradle-scoverage/build/resources/crossScalaVersionTest/projects/scala-multi-module-cross-version/3_2/src/main/scala/org/hello/World3_2.scala:14: ')' expected but '}' found.

I have not been able to figure out yet why Scala 2 compiler is used instead of Scala 3.

@maiflai , all, do you have any suggestion? I pushed the code so you could take a look.

maiflai commented 1 year ago

thanks again, will investigate

maiflai commented 1 year ago

thanks again, will investigate

I think that https://docs.gradle.org/current/userguide/scala_plugin.html suggests we need Gradle 7.5+ to compile Scala 3.x

distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
distributionSha256Sum=7ba68c54029790ab444b39d7e293d3236b2632631fb5f2e012bb28b4ff669e4b

Unfortunately several tests then fail - e.g.

Value for metadata of project :common has not been calculated yet.

I think it gets more complicated on your branch because scalatest has changed.

testImplementation "org.scalatestplus:junit-4-13_3:3.2.14.0" // I did not see a JUnit 5 artefact
import org.scalatest.funsuite.AnyFunSuite
import org.scalatestplus.junit.JUnitRunner

Even when this compiles, it fails to report coverage.

Thoughts?

msigmond commented 1 year ago

Thanks a lot @maiflai for taking a look.

I attached my test project: Scala3CodeCoverageViaGradle.zip This one takes the modified Scoverage Gradle plugin from the local Maven repository.

It looks to me that Scoverage reporting works fine in this project: the report looks as expected, and also fails the build when coverage falls below the minimum rate. When I build this with --debug, I can see that the Dotty compiler is invoked:

2022-11-27T17:08:31.914-0500 [DEBUG] [org.gradle.api.internal.tasks.scala.ZincScalaCompilerFactory] Calling Dotty compiler with arguments (CompilerInterface): -deprecation -unchecked -bootclasspath /home/marton/.gradle/caches/modules-2/files-2.1/org.scala-lang/scala-library/2.13.8/5a865f03a794b27e6491740c4c419a19e4511a3d/scala-library-2.13.8.jar -classpath /home/marton/.gradle/caches/modules-2/files-2.1/org.scala-lang/scala3-library_3/3.2.0/d775805d7d73cd4d9d9c734cc04e4d923cd19065/scala3-library_3-3.2.0.jar:/home/marton/.gradle/caches/modules-2/files-2.1/commons-collections/commons-collections/3.2.2/8ad72fe39fa8c91eaaf12aadb21e0c3661fe26d5/commons-collections-3.2.2.jar:/home/marton/.gradle/caches/modules-2/files-2.1/org.scala-lang/scala-library/2.13.8/5a865f03a794b27e6491740c4c419a19e4511a3d/scala-library-2.13.8.jar:/home/marton/IdeaProjects/Scala3CodeCoverageViaGradle/build/classes/java/main:/home/marton/IdeaProjects/Scala3CodeCoverageViaGradle/build/classes/scala/main

This test project uses Gradle 7.4, I will try upgrade the Scoverage project to 7.4 as well.

msigmond commented 1 year ago

It compiles fine with Gradle 7.4, thanks again for the hint, @maiflai

msigmond commented 1 year ago

Let me give an update:

I am struggling with the Scala 3 part of the scala-multi-module-cross-version test: It seems that different scoverage.coverage file is generated when running a real Gradle build, vs. running the build from the Gradle Test Kit:

In order to troubleshoot I copied the src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version into a separate Gradle project (named it GradleMultiFromScoveragePlugin). In that project the following build goes to success with no issue: $ gradle clean :3_2:reportScoverage --info --full-stacktrace

Then I triggered the same build from the Gradle Test Kit as follows:

public class MainTest {
    @Test
    public void testHelloWorldTask() throws IOException {
        final String mainTask = ":3_2:reportScoverage";
        final File testProjectDir = new File("/home/marton/IdeaProjects/GradleMultiFromScoveragePlugin");
        BuildResult result = GradleRunner.create()
                .withProjectDir(testProjectDir)
                .withArguments("clean", mainTask, "--info", "--full-stacktrace")
                .build();

        assertEquals(SUCCESS, result.task(mainTask).getOutcome());
    }
}

This build fails with the following error:

Caused by: java.lang.RuntimeException: No source root found for '/GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala' (source roots: '/home/marton/IdeaProjects/GradleMultiFromScoveragePlugin/3_2/src/main/scala/')
    at scoverage.reporter.BaseReportWriter.relativeSource(BaseReportWriter.scala:35)
    at scoverage.reporter.BaseReportWriter.relativeSource(BaseReportWriter.scala:23)
    at scoverage.reporter.CoberturaXmlWriter.klass(CoberturaXmlWriter.scala:54)
    at scoverage.reporter.CoberturaXmlWriter.pack$$anonfun$1(CoberturaXmlWriter.scala:78)
    ...

Interestingly different, and incorrect build/scoverage/scoverage.coverage file is generated in the Test Kit - the file path looks wrong:

$ diff -r good_build/scoverage/scoverage.coverage bad_build/scoverage/scoverage.coverage
22c22
< ../../IdeaProjects/GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala
---
> ../../../../../../../GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala
39c39
< ../../IdeaProjects/GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala
---
> ../../../../../../../GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala
56c56
< ../../IdeaProjects/GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala
---
> ../../../../../../../GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala
73c73
< ../../IdeaProjects/GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala
---
> ../../../../../../../GradleMultiFromScoveragePlugin/3_2/src/main/scala/org/hello/World3_2.scala

I tried to play around with a few things such (i.e. working directory), but no luck yet. I keep looking.

maiflai commented 1 year ago
parameters.add("-P:scoverage:sourceRoot:${extension.project.getRootDir().absolutePath}".toString())

Perhaps the Test Kit moves the root directory to a temporary location?

msigmond commented 1 year ago

Everything looks good, except 5 tests: these are the ones with the -PscoverageCompileOnly flag. This is related to the upgrade from Gradle 7.2 to Gradle 7.4 (I tested in isolation). I am investigating this.

maiflai commented 1 year ago

https://github.com/gradle/gradle/issues/20330 suggests that this might be an upstream issue.

I'm working on a fork of this pull request; it seems that renaming the 'common' project to '_common' fixes the project resolution issues.

msigmond commented 1 year ago

Thank you @maiflai as always!

msigmond commented 1 year ago

This change is completed in #192 .

msigmond commented 1 year ago

Completed in #192 , closing.