From 0c08012c28d7aa228f510364a8329a273b8630e2 Mon Sep 17 00:00:00 2001 From: Eyal Roth Date: Fri, 19 Jun 2020 19:38:14 +0300 Subject: [PATCH 1/3] #140 Add functional test for compatibility with 'palantir/gradle-consistent-versions' plugin (test currently fails) --- .../org.scoverage/DetectScalaLibraryTest.java | 28 ++++++++++++++++--- .../gradle-consistent-versions/build.gradle | 14 ++++++++++ .../settings.gradle | 0 .../gradle-consistent-versions/versions.lock | 2 ++ .../gradle-consistent-versions/versions.props | 1 + .../org/scoverage/ScoveragePlugin.groovy | 9 +++--- 6 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle create mode 100644 src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/settings.gradle create mode 100644 src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.lock create mode 100644 src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.props diff --git a/src/functionalTest/java/org.scoverage/DetectScalaLibraryTest.java b/src/functionalTest/java/org.scoverage/DetectScalaLibraryTest.java index 9b2d163..dd9cf8a 100644 --- a/src/functionalTest/java/org.scoverage/DetectScalaLibraryTest.java +++ b/src/functionalTest/java/org.scoverage/DetectScalaLibraryTest.java @@ -7,6 +7,8 @@ import java.util.Arrays; import java.util.Collection; +import java.util.List; +import java.util.stream.Stream; @RunWith(Parameterized.class) public class DetectScalaLibraryTest extends ScoverageFunctionalTest { @@ -20,9 +22,21 @@ public class DetectScalaLibraryTest extends ScoverageFunctionalTest { @Parameterized.Parameter(0) public String projectDir; + @Parameterized.Parameter(1) + public String[] subVersions; + + @Parameterized.Parameter(2) + public String[] additionalParameters; + @Parameterized.Parameters(name = "{index}: Project {0} ") public static Collection data() { - Object[][] data = new Object[][]{{"/compile"}, {"/compileOnly"}, {"/implementation"}, {"/dependency-management"}}; + Object[][] data = new Object[][]{ + {"/compile", new String[] {".0", ".+"}, new String[0]}, + {"/compileOnly", new String[] {".0", ".+"}, new String[0]}, + {"/implementation", new String[] {".0", ".+"}, new String[0]}, + {"/dependency-management", new String[] {".0", ".+"}, new String[0]}, + {"/gradle-consistent-versions", new String[] {"ignored"}, new String[] {"--write-locks"}}, + }; return Arrays.asList(data); } @@ -33,12 +47,18 @@ public DetectScalaLibraryTest() { @Test public void test() { setProjectName("detect-scala-library" + projectDir); - testWithParameter(SCALA_LIBRARY_PARAMETER + SCALA_VERSION + ".0"); - testWithParameter(SCALA_LIBRARY_PARAMETER + SCALA_VERSION + ".+"); + for (String subVersion : subVersions) { + testWithParameter(SCALA_LIBRARY_PARAMETER + SCALA_VERSION + subVersion); + } } private void testWithParameter(String parameter) { - AssertableBuildResult result = dryRun("clean", parameter, "--info"); + + String[] basicParameters = {"clean", parameter, "--info"}; + String[] parameters = Stream.concat(Arrays.stream(basicParameters), Arrays.stream(additionalParameters)) + .toArray(String[]::new); + AssertableBuildResult result = dryRun(parameters); + String output = result.getResult().getOutput(); Assert.assertTrue(output.contains(EXPECTED_OUTPUT_A)); Assert.assertTrue(output.contains(EXPECTED_OUTPUT_B)); diff --git a/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle new file mode 100644 index 0000000..b59158b --- /dev/null +++ b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle @@ -0,0 +1,14 @@ +plugins { + id "com.palantir.consistent-versions" version "1.16.0" + id 'org.scoverage' +} + +repositories { + jcenter() +} + +description = 'defines scala library using the "implementation" configuration and the gradle-consistent-versions plugin' + +dependencies { + implementation group: 'org.scala-lang', name: 'scala-library' +} \ No newline at end of file diff --git a/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/settings.gradle b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/settings.gradle new file mode 100644 index 0000000..e69de29 diff --git a/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.lock b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.lock new file mode 100644 index 0000000..97decdb --- /dev/null +++ b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.lock @@ -0,0 +1,2 @@ +# Run ./gradlew --write-locks to regenerate this file +org.scala-lang:scala-library:2.12.0 (1 constraints: 3705353b) diff --git a/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.props b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.props new file mode 100644 index 0000000..4da792e --- /dev/null +++ b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.props @@ -0,0 +1 @@ +org.scala-lang:scala-library = 2.12.0 \ No newline at end of file diff --git a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy index d1e47ca..0bcb565 100644 --- a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy +++ b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy @@ -1,7 +1,6 @@ package org.scoverage import org.apache.commons.io.FileUtils -import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task @@ -343,10 +342,10 @@ class ScoveragePlugin implements Plugin { private String resolveScalaVersion(Project project) { - def resolvedDependencies = project.configurations.compileClasspath.resolvedConfiguration.firstLevelModuleDependencies + def components = project.configurations.compileClasspath.incoming.resolutionResult.getAllComponents() - def scalaLibrary = resolvedDependencies.find { - it.moduleGroup == "org.scala-lang" && it.moduleName == "scala-library" + def scalaLibrary = components.find { + it.moduleVersion.group == "org.scala-lang" && it.moduleVersion.name == "scala-library" } if (scalaLibrary == null) { @@ -354,7 +353,7 @@ class ScoveragePlugin implements Plugin { return project.extensions.scoverage.scoverageScalaVersion.get() } else { project.logger.info("Detected scala library in compilation classpath") - def fullScalaVersion = scalaLibrary.moduleVersion + def fullScalaVersion = scalaLibrary.moduleVersion.version return fullScalaVersion.substring(0, fullScalaVersion.lastIndexOf(".")) } } From 57a036aeee6b0df8fb158fae272fec3b79c715f3 Mon Sep 17 00:00:00 2001 From: Eyal Roth Date: Sun, 16 Aug 2020 18:25:22 +0300 Subject: [PATCH 2/3] #140 Resolve scalac plugin file at execution time instead of configuration time --- .../org/scoverage/ScoveragePlugin.groovy | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy index 0bcb565..d0c589c 100644 --- a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy +++ b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy @@ -27,7 +27,6 @@ class ScoveragePlugin implements Plugin { static final String DEFAULT_REPORT_DIR = 'reports' + File.separatorChar + 'scoverage' - private volatile File pluginFile = null private final ConcurrentHashMap> taskDependencies = new ConcurrentHashMap<>(); @Override @@ -172,13 +171,7 @@ class ScoveragePlugin implements Plugin { } compileTask.configure { - if (pluginFile == null) { - pluginFile = project.configurations[CONFIGURATION_NAME].find { - it.name.startsWith("scalac-scoverage-plugin") - } - } - - List parameters = ['-Xplugin:' + pluginFile.absolutePath] + List parameters = [] List existingParameters = scalaCompileOptions.additionalParameters if (existingParameters) { parameters.addAll(existingParameters) @@ -198,6 +191,18 @@ class ScoveragePlugin implements Plugin { scalaCompileOptions.additionalParameters = parameters // the compile task creates a store of measured statements outputs.file(new File(extension.dataDir.get(), 'scoverage.coverage.xml')) + + dependsOn project.configurations[CONFIGURATION_NAME] + doFirst { + /* + It is crucial that this would run in `doFirst`, as this resolves the (dependencies of the) + configuration, which we do not want to do at configuration time (but only at execution time). + */ + def pluginFile = project.configurations[CONFIGURATION_NAME].find { + it.name.startsWith("scalac-scoverage-plugin") + } + scalaCompileOptions.additionalParameters.add('-Xplugin:' + pluginFile.absolutePath) + } } project.gradle.taskGraph.whenReady { graph -> From cc9bdaab7fa8191889c373308891d54c6bf31254 Mon Sep 17 00:00:00 2001 From: Eyal Roth Date: Sun, 16 Aug 2020 18:58:07 +0300 Subject: [PATCH 3/3] #140 Only attempt to detect Scala version if it isn't already configured by the `scoverageScalaVersion` option --- README.md | 11 +++++-- .../org/scoverage/DetectScalaLibraryTest.java | 30 ++++++++++------- .../gradle-consistent-versions/build.gradle | 5 +++ .../org/scoverage/ScoverageExtension.groovy | 1 - .../org/scoverage/ScoveragePlugin.groovy | 32 ++++++++++++------- 5 files changed, 53 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 4e09b2c..98f0543 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@ build script. These options are as follows: * `scoverageVersion = ` (default `"1.4.1"`): The version of the scoverage scalac plugin. This (gradle) plugin should be compatible with all 1+ versions. -* `scoverageScalaVersion = ` (default `"2.12"`): The scala version of the scoverage scalac plugin. This will -be overridden by the version of the `scala-library` compile dependency (if the dependency is configured). +* `scoverageScalaVersion = ` (default `"2.12"`): The scala version of the scoverage scalac plugin. This +overrides the version of the `scala-library` compile dependency (if the dependency is configured). * `coverageOutputCobertura = ` (default `true`): Enables/disables cobertura.xml file generation (for both aggregated and non-aggregated reports). @@ -115,6 +115,13 @@ it is possible to only compile the code with the scoverage scalac plugin, thus r In order to do so, simply add the arguments `-x compileScala` to the gradle execution. For example: `gradle reportScoverage -x compileScala`. + +### Compatibility with Consistent Versions Plugin + +In order for the plugin to work alongside [Palantir's consistent versions plugin](https://github.com/palantir/gradle-consistent-versions), +the Scala version must be manually configured (via `scoverageScalaVersion`); otherwise, the plugin will attempt to +resolve the compilation classpath, which is prohibited by the versions plugin. + Migration to 4.x ---------------- diff --git a/src/functionalTest/java/org/scoverage/DetectScalaLibraryTest.java b/src/functionalTest/java/org/scoverage/DetectScalaLibraryTest.java index dd9cf8a..bcda654 100644 --- a/src/functionalTest/java/org/scoverage/DetectScalaLibraryTest.java +++ b/src/functionalTest/java/org/scoverage/DetectScalaLibraryTest.java @@ -16,8 +16,9 @@ public class DetectScalaLibraryTest extends ScoverageFunctionalTest { private static final String SCALA_VERSION = "2.12"; private static final String SCALA_LIBRARY_PARAMETER = "-PdetectedScalaLibraryVersion="; - private static final String EXPECTED_OUTPUT_A = "Detected scala library in compilation classpath"; - private static final String EXPECTED_OUTPUT_B = "Using scoverage scalac plugin version '" + SCALA_VERSION; + private static final String EXPECTED_OUTPUT_CONFIGURED_VERSION = "Using configured Scala version"; + private static final String EXPECTED_OUTPUT_DETECTED_VERSION = "Detected scala library in compilation classpath"; + private static final String EXPECTED_OUTPUT_USING = "Using scoverage scalac plugin version '" + SCALA_VERSION; @Parameterized.Parameter(0) public String projectDir; @@ -26,16 +27,19 @@ public class DetectScalaLibraryTest extends ScoverageFunctionalTest { public String[] subVersions; @Parameterized.Parameter(2) + public boolean detect; + + @Parameterized.Parameter(3) public String[] additionalParameters; @Parameterized.Parameters(name = "{index}: Project {0} ") public static Collection data() { Object[][] data = new Object[][]{ - {"/compile", new String[] {".0", ".+"}, new String[0]}, - {"/compileOnly", new String[] {".0", ".+"}, new String[0]}, - {"/implementation", new String[] {".0", ".+"}, new String[0]}, - {"/dependency-management", new String[] {".0", ".+"}, new String[0]}, - {"/gradle-consistent-versions", new String[] {"ignored"}, new String[] {"--write-locks"}}, + {"/compile", new String[] {".0", ".+"}, true, new String[0]}, + {"/compileOnly", new String[] {".0", ".+"}, true, new String[0]}, + {"/implementation", new String[] {".0", ".+"}, true, new String[0]}, + {"/dependency-management", new String[] {".0", ".+"}, true, new String[0]}, + {"/gradle-consistent-versions", new String[] {"ignored"}, false, new String[] {"--write-locks"}}, }; return Arrays.asList(data); } @@ -48,11 +52,11 @@ public DetectScalaLibraryTest() { public void test() { setProjectName("detect-scala-library" + projectDir); for (String subVersion : subVersions) { - testWithParameter(SCALA_LIBRARY_PARAMETER + SCALA_VERSION + subVersion); + testWithParameter(SCALA_LIBRARY_PARAMETER + SCALA_VERSION + subVersion, detect); } } - private void testWithParameter(String parameter) { + private void testWithParameter(String parameter, Boolean detect) { String[] basicParameters = {"clean", parameter, "--info"}; String[] parameters = Stream.concat(Arrays.stream(basicParameters), Arrays.stream(additionalParameters)) @@ -60,8 +64,12 @@ private void testWithParameter(String parameter) { AssertableBuildResult result = dryRun(parameters); String output = result.getResult().getOutput(); - Assert.assertTrue(output.contains(EXPECTED_OUTPUT_A)); - Assert.assertTrue(output.contains(EXPECTED_OUTPUT_B)); + if (detect) { + Assert.assertTrue(output.contains(EXPECTED_OUTPUT_DETECTED_VERSION)); + } else { + Assert.assertTrue(output.contains(EXPECTED_OUTPUT_CONFIGURED_VERSION)); + } + Assert.assertTrue(output.contains(EXPECTED_OUTPUT_USING)); } } \ No newline at end of file diff --git a/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle index b59158b..030a1c1 100644 --- a/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle +++ b/src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle @@ -11,4 +11,9 @@ description = 'defines scala library using the "implementation" configuration an dependencies { implementation group: 'org.scala-lang', name: 'scala-library' +} + +scoverage { + // 'detectedScalaLibraryVersion' is set by the test `DetectScalaLibraryTest.java` + scoverageScalaVersion = detectedScalaLibraryVersion } \ No newline at end of file diff --git a/src/main/groovy/org/scoverage/ScoverageExtension.groovy b/src/main/groovy/org/scoverage/ScoverageExtension.groovy index a65b8aa..9de93c5 100644 --- a/src/main/groovy/org/scoverage/ScoverageExtension.groovy +++ b/src/main/groovy/org/scoverage/ScoverageExtension.groovy @@ -60,7 +60,6 @@ class ScoverageExtension { scoverageVersion.set('1.4.1') scoverageScalaVersion = project.objects.property(String) - scoverageScalaVersion.set('2.12') sources = project.objects.property(File) sources.set(project.projectDir) diff --git a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy index d0c589c..ab5f4d2 100644 --- a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy +++ b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy @@ -24,6 +24,7 @@ class ScoveragePlugin implements Plugin { static final String CHECK_NAME = 'checkScoverage' static final String COMPILE_NAME = 'compileScoverageScala' static final String AGGREGATE_NAME = 'aggregateScoverage' + static final String DEFAULT_SCALA_VERSION = '2.12' static final String DEFAULT_REPORT_DIR = 'reports' + File.separatorChar + 'scoverage' @@ -347,19 +348,26 @@ class ScoveragePlugin implements Plugin { private String resolveScalaVersion(Project project) { - def components = project.configurations.compileClasspath.incoming.resolutionResult.getAllComponents() - - def scalaLibrary = components.find { - it.moduleVersion.group == "org.scala-lang" && it.moduleVersion.name == "scala-library" - } - - if (scalaLibrary == null) { - project.logger.info("No scala library detected. Using property 'scoverageScalaVersion'") - return project.extensions.scoverage.scoverageScalaVersion.get() + def scalaVersionProperty = project.extensions.scoverage.scoverageScalaVersion + if (scalaVersionProperty.isPresent()) { + def configuredScalaVersion = scalaVersionProperty.get() + project.logger.info("Using configured Scala version: $configuredScalaVersion") + return configuredScalaVersion } else { - project.logger.info("Detected scala library in compilation classpath") - def fullScalaVersion = scalaLibrary.moduleVersion.version - return fullScalaVersion.substring(0, fullScalaVersion.lastIndexOf(".")) + project.logger.info("No Scala version configured. Detecting scala library...") + def components = project.configurations.compileClasspath.incoming.resolutionResult.getAllComponents() + def scalaLibrary = components.find { + it.moduleVersion.group == "org.scala-lang" && it.moduleVersion.name == "scala-library" + } + if (scalaLibrary != null) { + def fullScalaVersion = scalaLibrary.moduleVersion.version + def scalaVersion = fullScalaVersion.substring(0, fullScalaVersion.lastIndexOf(".")) + project.logger.info("Detected scala library in compilation classpath. Scala version: $scalaVersion") + return scalaVersion + } else { + project.logger.info("No scala library detected. Using default Scala version: $DEFAULT_SCALA_VERSION") + return DEFAULT_SCALA_VERSION + } } }