Skip to content

Make the plugin compatible with Palantir's consistent versions plugin #143

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ build script. These options are as follows:
* `scoverageVersion = <String>` (default `"1.4.1"`): The version of the scoverage scalac plugin. This (gradle) plugin
should be compatible with all 1+ versions.

* `scoverageScalaVersion = <String>` (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 = <String>` (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 = <boolean>` (default `true`): Enables/disables cobertura.xml file generation (for both aggregated and non-aggregated reports).

Expand Down Expand Up @@ -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
----------------

Expand Down
46 changes: 37 additions & 9 deletions src/functionalTest/java/org/scoverage/DetectScalaLibraryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,40 @@

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 {

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;

@Parameterized.Parameter(1)
public String[] subVersions;

@Parameterized.Parameter(2)
public boolean detect;

@Parameterized.Parameter(3)
public String[] additionalParameters;

@Parameterized.Parameters(name = "{index}: Project {0} ")
public static Collection<Object[]> data() {
Object[][] data = new Object[][]{{"/compile"}, {"/compileOnly"}, {"/implementation"}, {"/dependency-management"}};
Object[][] data = new Object[][]{
{"/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);
}

Expand All @@ -33,15 +51,25 @@ 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, detect);
}
}

private void testWithParameter(String parameter) {
AssertableBuildResult result = dryRun("clean", parameter, "--info");
private void testWithParameter(String parameter, Boolean detect) {

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));
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));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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'
}

scoverage {
// 'detectedScalaLibraryVersion' is set by the test `DetectScalaLibraryTest.java`
scoverageScalaVersion = detectedScalaLibraryVersion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Run ./gradlew --write-locks to regenerate this file
org.scala-lang:scala-library:2.12.0 (1 constraints: 3705353b)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.scala-lang:scala-library = 2.12.0
1 change: 0 additions & 1 deletion src/main/groovy/org/scoverage/ScoverageExtension.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
54 changes: 33 additions & 21 deletions src/main/groovy/org/scoverage/ScoveragePlugin.groovy
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -25,10 +24,10 @@ class ScoveragePlugin implements Plugin<PluginAware> {
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'

private volatile File pluginFile = null
private final ConcurrentHashMap<Task, Set<? extends Task>> taskDependencies = new ConcurrentHashMap<>();

@Override
Expand Down Expand Up @@ -173,13 +172,7 @@ class ScoveragePlugin implements Plugin<PluginAware> {
}

compileTask.configure {
if (pluginFile == null) {
pluginFile = project.configurations[CONFIGURATION_NAME].find {
it.name.startsWith("scalac-scoverage-plugin")
}
}

List<String> parameters = ['-Xplugin:' + pluginFile.absolutePath]
List<String> parameters = []
List<String> existingParameters = scalaCompileOptions.additionalParameters
if (existingParameters) {
parameters.addAll(existingParameters)
Expand All @@ -199,6 +192,18 @@ class ScoveragePlugin implements Plugin<PluginAware> {
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 ->
Expand Down Expand Up @@ -343,19 +348,26 @@ class ScoveragePlugin implements Plugin<PluginAware> {

private String resolveScalaVersion(Project project) {

def resolvedDependencies = project.configurations.compileClasspath.resolvedConfiguration.firstLevelModuleDependencies

def scalaLibrary = resolvedDependencies.find {
it.moduleGroup == "org.scala-lang" && it.moduleName == "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
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
}
}
}

Expand Down