form-com / diff-coverage-gradle Goto Github PK
View Code? Open in Web Editor NEWGradle plugin for computing code coverage on modified code
License: MIT License
Gradle plugin for computing code coverage on modified code
License: MIT License
I'm getting the following error when trying to execute diffCoverage
task:
Caused by: java.lang.NoSuchMethodError: 'void kotlin.jvm.internal.FunctionReferenceImpl.<init>(int, java.lang.Object, java.lang.Class, java.lang.String, java.lang.String, int)'
at com.form.coverage.report.analyzable.DiffCoverageAnalyzableReport$buildAnalyzer$1.<init>(DiffCoverageAnalyzableReport.kt)
at com.form.coverage.report.analyzable.DiffCoverageAnalyzableReport.buildAnalyzer(DiffCoverageAnalyzableReport.kt:37)
at com.form.coverage.report.ReportGenerator$create$bundleCoverage$1.invoke(ReportGenerator.kt:50)
at com.form.coverage.report.ReportGenerator$create$bundleCoverage$1.invoke(ReportGenerator.kt:16)
It seems to be related to https://youtrack.jetbrains.com/issue/KT-39389#focus=Comments-27-4184517.0-0, but I have not found a workaround for it.
I'm building this for an android project where I'm currently using gradle 6.5 and kotline 4.0. I have tried updating those but I still get this error when executing diffCoverage
.
It looks like a change like this solves it for me, but I'm not sure this is the right approach:
diff --git a/jacoco-filtering-extension/src/main/kotlin/com/form/coverage/report/analyzable/DiffCoverageAnalyzableReport.kt b/jacoco-filtering-extension/src/main/kotlin/com/form/coverage/report/analyzable/DiffCoverageAnalyzableReport.kt
index 7b106f2..e913e15 100644
--- a/jacoco-filtering-extension/src/main/kotlin/com/form/coverage/report/analyzable/DiffCoverageAnalyzableReport.kt
+++ b/jacoco-filtering-extension/src/main/kotlin/com/form/coverage/report/analyzable/DiffCoverageAnalyzableReport.kt
@@ -34,7 +34,10 @@ internal class DiffCoverageAnalyzableReport(
return FilteringAnalyzer(
executionDataStore,
coverageVisitor,
- reportMode.codeUpdateInfo::isInfoExists
+ {
+ reportMode.codeUpdateInfo.isInfoExists(it)
+ }
+
) {
ModifiedLinesFilter(reportMode.codeUpdateInfo)
}
When I'm using default git.compare, I found the diff file is not completely correct.
For example, we have master and dev branchs.
In this case, the diff file is including the commits on master and treating as delete operation.
Actually, the master should be always latest comparing to our develop branch, and have some commits we don't have if we don't merge master.
I'm not sure it's a issue or you do want this, but I think we should ignore the commits dev don't have, at least provide a config value.
For now, I use this command to generate the diffFile, please check and hope it helps.
1. git diff origin/master... > reports/git.diff
2. git diff --ignore-space-change origin/master... > reports/git.diff
Describe the bug
The diffSource.git.compareWith
configuration has no effect if the files have not been committed to git.
If this is by design, it should be clearly documented. However, it does not align with the expectation of executing git diff <ref>
and saving the results to a file that the plugin points to. In particular, it makes a diff reference to HEAD
completely useless after the commit.
Additionally the comment in the config explicitly specifies uncommitted files:
Compares current HEAD and all uncommited with provided branch
Desktop (please complete the following information):
To Reproduce
gradle diffCoverage
with the below configurationdiffCoverageReport {
diffSource {
git.compareWith 'refs/remotes/origin/main'
}
reports {
html = true
}
}
build/reports/jacoco
directory:diff.patch
file has 0 bytesdiffCoverage/html/index.html
says "No class files specified." (See also report in #65 for which this may have been the cause.)Expected behavior
Changed files are found and diff.patch
is not empty.
Additional context
Workaround is to configure:
diffSource {
file = 'build/tmp/git.diff'
}
and then execute:
git diff refs/remotes/origin/main > build/tmp/git.diff
gradle diffCoverage
Consider adding support for https://docs.gradle.org/current/userguide/configuration_cache.html
Current issue;
https://docs.gradle.org/7.4.2/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution
13 problems were found storing the configuration cache, 1 of which seems unique.
- Task `:diffCoverage` of type `com.form.coverage.gradle.DiffCoverageTask`: invocation of 'Task.project' at execution time is unsupported.
See https://docs.gradle.org/7.4.2/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution
Caused by: org.gradle.api.InvalidUserCodeException: Invocation of 'Task.project' by task ':diffCoverage' at execution time is unsupported.
at org.gradle.configurationcache.initialization.DefaultConfigurationCacheProblemsListener.onTaskExecutionAccessProblem(ConfigurationCacheProblemsListener.kt:74)
at org.gradle.configurationcache.initialization.DefaultConfigurationCacheProblemsListener.onProjectAccess(ConfigurationCacheProblemsListener.kt:53)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:464)
at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:446)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:61)
at org.gradle.internal.event.DefaultListenerManager$EventBroadcast$ListenerDispatch.dispatch(DefaultListenerManager.java:434)
at org.gradle.internal.event.DefaultListenerManager$EventBroadcast.dispatch(DefaultListenerManager.java:221)
at org.gradle.internal.event.DefaultListenerManager$EventBroadcast.dispatch(DefaultListenerManager.java:192)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy174.onProjectAccess(Unknown Source)
at org.gradle.api.internal.AbstractTask.notifyProjectAccess(AbstractTask.java:1053)
at org.gradle.api.internal.AbstractTask.getProject(AbstractTask.java:237)
at org.gradle.api.DefaultTask.getProject(DefaultTask.java:59)
at com.form.coverage.gradle.DiffCoverageTask.getOutputDir(DiffCoverageTask.kt:45)
at com.form.coverage.gradle.DiffCoverageTask.executeAction(DiffCoverageTask.kt:56)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
sorry but can you pls share an example to config diffCoverageReport in kotlin instead of groovy? not too familiar with kotlin π
Describe the bug
When there are two java files in different module, that have same package and class name, the coverage is wrong
e.g.
There is no test for both A and B before.
After I changed A class and add related test case
I think the root cause is, the plugin didn't add module name for distinguish two different class
I don't read the source code, but I think the uniqueKey is
Version info:
To Reproduce
diffCoverageReport {
violationRules.failIfCoverageLessThan 0.7
}
Both two files don't have test class
Then change module A file, and run diffCoverage
After upgrading from 0.8.1 to 0.9.0/0.9.1, diffCoverage task keep throwing exception that 'diffCoverageReport.classesDirs' file collection is empty.
My gradle version is 4.10.3.
Here is my configurations
subprojects {
jacocoTestReport {
dependsOn test
group = "Reporting"
description = "Generate Jacoco coverage reports"
executionData files("${buildDir}/jacoco/jacoco.exec")
sourceDirectories = files("${projectDir}/src/main/java")
def generatedFilter = [
'**/generated/**'
]
classDirectories = files(
fileTree(dir: "${buildDir}/classes/java/main", excludes: generatedFilter),
fileTree(dir: "${buildDir}/classes/main", excludes: generatedFilter)
)
reports {
xml.enabled = true
html.enabled = true
csv.enabled = true
xml.destination file("${buildDir}/reports/jacoco.xml")
csv.destination file("${buildDir}/reports/jacoco.csv")
html.destination file("${buildDir}/reports/fullCoverage")
}
afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it, exclude: generatedFilter)
})
}
}
diffCoverageReport {
def diffFile = System.getProperty('jacoco.diff.file') ?: ''
def diffRepo = System.getProperty('jacoco.diff.repo') ?: 'origin'
def diffBranch = System.getProperty('jacoco.diff.branch') ?: 'master'
diffSource {
if (diffFile) {
file = diffFile
} else {
git.compareWith "refs/remotes/${diffRepo}/${diffBranch}"
}
}
jacocoExecFiles = files(jacocoTestReport.executionData)
classesDirs = files(jacocoTestReport.classDirectories)
srcDirs = files(jacocoTestReport.sourceDirectories)
reports {
html = true
csv = true
xml = true
baseReportDir = "${buildDir}/reports"
}
}
}
Describe the bug
The log4j version that is included as a dependency has security vulnerabilities.
It however doesn't appear that the code uses this dependency at all.
https://logging.apache.org/log4j/2.x/security.html
Desktop (please complete the following information):
To Reproduce
See vulnerabilities report
Enviroment:
Android Studio 4.2.2
Gradle plugin 6.7
diffCoveragePlugin: 0.9.1
Caused by: java.lang.ClassCastException: org.gradle.api.DefaultTask_Decorated cannot be cast to org.gradle.testing.jacoco.tasks.JacocoReport
at com.form.coverage.gradle.DiffTaskAutoConfigurationKt$jacocoTestReportsSettings$3.invoke(DiffTaskAutoConfiguration.kt:58)
at com.form.coverage.gradle.DiffTaskAutoConfigurationKt$jacocoTestReportsSettings$3.invoke(DiffTaskAutoConfiguration.kt)
at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:172)
at com.form.coverage.gradle.DiffTaskAutoConfigurationKt.jacocoTestReportsSettings(DiffTaskAutoConfiguration.kt:99)
at com.form.coverage.gradle.DiffTaskAutoConfigurationKt.collectFileCollectionOrAutoconfigure(DiffTaskAutoConfiguration.kt:47)
at com.form.coverage.gradle.DiffTaskAutoConfigurationKt.collectFileCollectionOrThrow(DiffTaskAutoConfiguration.kt:9)
at com.form.coverage.gradle.DiffCoverageTask.getSourcesFiles(DiffCoverageTask.kt:30)
at org.gradle.api.internal.tasks.properties.bean.AbstractNestedRuntimeBeanNode$BeanPropertyValue$1$1.create(AbstractNestedRuntimeBeanNode.java:77)
at org.gradle.internal.deprecation.DeprecationLogger.whileDisabled(DeprecationLogger.java:236)
at org.gradle.api.internal.tasks.properties.bean.AbstractNestedRuntimeBeanNode$BeanPropertyValue$1.get(AbstractNestedRuntimeBeanNode.java:73)
at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers.java:167)
at org.gradle.api.internal.tasks.properties.bean.AbstractNestedRuntimeBeanNode$BeanPropertyValue.call(AbstractNestedRuntimeBeanNode.java:133)
at org.gradle.util.GUtil.uncheckedCall(GUtil.java:442)
at org.gradle.util.DeferredUtil.unpackNestableDeferred(DeferredUtil.java:64)
at org.gradle.api.internal.file.collections.UnpackingVisitor.add(UnpackingVisitor.java:84)
at org.gradle.api.internal.file.DefaultFileCollectionFactory$ResolvingFileCollection.visitChildren(DefaultFileCollectionFactory.java:310)
at org.gradle.api.internal.file.CompositeFileCollection.visitDependencies(CompositeFileCollection.java:108)
at org.gradle.api.internal.tasks.CachingTaskDependencyResolveContext$TaskGraphImpl.getNodeValues(CachingTaskDependencyResolveContext.java:112)
at org.gradle.internal.graph.CachingDirectedGraphWalker$GraphWithEmptyEdges.getNodeValues(CachingDirectedGraphWalker.java:213)
at org.gradle.internal.graph.CachingDirectedGraphWalker.doSearch(CachingDirectedGraphWalker.java:121)
at org.gradle.internal.graph.CachingDirectedGraphWalker.findValues(CachingDirectedGraphWalker.java:73)
at org.gradle.api.internal.tasks.CachingTaskDependencyResolveContext.getDependencies(CachingTaskDependencyResolveContext.java:67)
... 114 more
What is the plugin id that I should use to include this plugin??
I am using this in my build.gradle
file
plugins {
id "jacoco"
id "com.form.diff-coverage" version "0.9.0"
}
* Exception is:
org.gradle.api.plugins.UnknownPluginException: Plugin [id: 'com.form.diff-coverage', version: '0.9.0'] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.form.diff-coverage:com.form.diff-coverage.gradle.plugin:0.9.0')
Searched in the following repositories:
Gradle Central Plugin Repository
at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.resolveToFoundResult(DefaultPluginRequestApplicator.java:222)
at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$resolvePluginRequests$4(DefaultPluginRequestApplicator.java:148)
at org.gradle.util.CollectionUtils.collect(CollectionUtils.java:207)
at org.gradle.util.CollectionUtils.collect(CollectionUtils.java:201)
at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.resolvePluginRequests(DefaultPluginRequestApplicator.java:146)
at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugins(DefaultPluginRequestApplicator.java:86)
at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:117)
at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:65)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
at org.gradle.configuration.BuildOperationScriptPlugin.lambda$apply$0(BuildOperationScriptPlugin.java:62)
at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:43)
at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:62)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$0(DefaultProjectStateRegistry.java:250)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:277)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:249)
at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:42)
at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:35)
at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.lambda$run$0(LifecycleProjectEvaluator.java:100)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$0(DefaultProjectStateRegistry.java:250)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$withProjectLock$3(DefaultProjectStateRegistry.java:310)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:213)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:310)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:291)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:249)
at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:91)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:63)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:723)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:150)
at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:41)
at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:67)
at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:46)
at org.gradle.configuration.BuildTreePreparingProjectsPreparer.prepareProjects(BuildTreePreparingProjectsPreparer.java:64)
at org.gradle.configuration.BuildOperationFiringProjectsPreparer$ConfigureBuild.run(BuildOperationFiringProjectsPreparer.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
at org.gradle.configuration.BuildOperationFiringProjectsPreparer.prepareProjects(BuildOperationFiringProjectsPreparer.java:40)
at org.gradle.initialization.DefaultGradleLauncher.prepareProjects(DefaultGradleLauncher.java:226)
at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:164)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:125)
at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:71)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:213)
at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:67)
at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:56)
at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner.runClientAction(AbstractClientProvidedBuildActionRunner.java:53)
at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:47)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:66)
at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:90)
at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:49)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:44)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:44)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.lambda$execute$0(InProcessBuildActionExecuter.java:59)
at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:86)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:58)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.lambda$execute$0(BuildTreeScopeLifecycleBuildActionExecuter.java:34)
at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:53)
at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:33)
at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:28)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:104)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:55)
at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:64)
at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:37)
at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.lambda$execute$0(SessionScopeLifecycleBuildActionExecuter.java:54)
at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:67)
at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:50)
at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:58)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
Hi,
I met a problem about FileNotFoundException while running diffCoverage task.
I'm testing with this configuration, and always get this error
diffCoverageReport {
def diffBranch = System.getProperty('jacoco-diff-branch') ?: 'master'
diffSource {
git.compareWith "refs/heads/${diffBranch}"
}
jacocoExecFiles = files(jacocoTestReport.executionData)
classesDirs = files(jacocoTestReport.classDirectories)
srcDirs = files(jacocoTestReport.sourceDirectories)
reports {
xml = true
html = false
csv = true
}
}
When I change reports.html
to true, the error disappeared.
I tried to debug the source code, and I found the report is generated at ${buildDir}/reports/jacoco/diffCoverage/xxx.format
.
And I found this code, HTML is using FileMultiReportOutput, XML/CSV is using FileOutputStream.
FileMultiReportOutput will auto create the parent directory, but FileOutputStream is not, and it also throws a FileNotFoundException
So it can explain why when reports.html = false, it cannot auto mkdir parent dirs and throws a exception.
And under further analysis, I also don't know why the code goes here, it looks like full report generator, but fullCoverageReport
is not setted to true.
Describe the bug
FAILURE: Build failed with an exception.
'diffCoverageReport.jacocoExecFiles' file collection is empty.
Desktop (please complete the following information):
To Reproduce
./gradlew clean diffCoverage
Expected behavior
The build fails, it would be great to add an option to fail silently. The use-case is in CI builds the diff might not have any test coverage and can lead to this failure.
Logs
FAILURE: Build failed with an exception.
'diffCoverageReport.jacocoExecFiles' file collection is empty.
Run with --stacktrace option to get the stack trace.
Run with --info or --debug option to get more log output
Additional context
Add any other context about the problem here.
Describe the feature
Since this plugin is an extension of Jacoco, and Jacoco allows us to configure the coverage to multiple decimals (e.g. 0.65), I had the wrong impression that we can do the same for this plugin.
When I set the minBranches
to 0.61, the exception still reports the same message
java.lang.Exception: Rule violated for bundle clients: branches covered ratio is 0.2, but expected minimum is 0.6
Desktop (please complete the following information):
To Reproduce
diffCoverageReport {
diffSource.file = 'diff.patch'
violationRules {
minBranches = 0.61
failOnViolation = true
}
}
Expected behavior
The report can be more precise when the coverage is set to 2 decimals, such as
java.lang.Exception: Rule violated for bundle clients: branches covered ratio is 0.29, but expected minimum is 0.61
Additional context
I checked the config usage and seems we only set a single decimal for the double
type, which might be the reason but I could be wrong.
Please let me know if it can be supported. Thanks!
> Task :diffCoverage
Execution optimizations have been disabled for task ':diffCoverage' to ensure correctness due to the following reasons:
- Gradle detected a problem with the following location: '<PATH>/build/classes/java/main'. Reason: Task ':diffCoverage' uses this output of task ':compileJava' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4/userguide/validation_problems.html#implicit_dependency for more details about this problem.
- Gradle detected a problem with the following location: '<PATH>/build/jacoco/test.exec'. Reason: Task ':diffCoverage' uses this output of task ':test' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4/userguide/validation_problems.html#implicit_dependency for more details about this problem.
- Gradle detected a problem with the following location: '<PATH>/build/resources/main'. Reason: Task ':diffCoverage' uses this output of task ':processResources' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4/userguide/validation_problems.html#implicit_dependency for more details about this problem.
Fail on violations: false. Found violations: 0.
It would be nice to have a specific setting which specifies the files which should be thrown out of coverage check. This helps in cases when @Data
from lombok library is used. One could argue that those methods should still be tested, but it would still be a nice feature.
I suggest adding something like
diffCoverageReport {
diffSource.git.compareWith 'refs/remotes/origin/develop'
violationRules.failIfCoverageLessThan 0.8
reports {
html = true
}
exclusions = "**/MyClass.java", "**/model/*.java" # // <-- This is the setting I'm talking about
}
@SurpSG could you please provide your opinion on this matter? I think I can implement the necessary code myself, but I want to get your confirmation first.
UPD: It looks like this option is present in maven version of this plugin, it means that this should not be a problem to implement it for gradle as well.
I applied the plugin (v 0.9.5) in the root's build.gradle
. After generating the reports, diff.patch
is not correct compared to the result from git diff
. Looks like it doesn't include diff in submodules.
Even if I tried configuring the report as below , it still doesn't work as expected.
diffCoverageReport {
...
jacocoExecFiles = files(...)
srcDirs = files(...)
classesDirs = files(...)
}
It'd be great if you could provide an example for multi-module setup.
Describe the bug
If you add just a blank line, or a comment, but no new instructions or functions to a class under test, the coverage violations will fail and say you have not met the threshold. In this case there is no new instructions, just comments and some extra blank lines, so code coverage should be the same as it was before.
We have instruction coverage to be a minimum of 0.7 percent, and branch coverage for 0.5 percent. The branch coverage is passing. The instruction coverage fails
Min Line coverage is 0.0.
diffCoverageExtension.violationRules{
minBranches = 0.5 // Optional. Default `0.0`
minInstructions = 0.7 // Optional. Default `0.0`
failOnViolation = true // Optional. Default `false`
}
Desktop (please complete the following information):
To Reproduce
If possible, provide your configuration of the plugin, for example:
diffCoverageReport {
diffSource.file = 'diff.patch'
violationRules.failIfCoverageLessThan 0.9
}
// Some comment in a source file
Expected behavior
Since no instruction coverage changed this should still pass and meet the original thresholds.
I have configured the project to run correctly locally using git
configuration to get the diff
.
This is my configuration:
diffCoverageReport {
def targetBranch = project.getProperties().get("targetBranch") ?: "development"
diffSource {
git.compareWith targetBranch
}
jacocoExecFiles = files(jacocoTestReport.executionData)
classesDirs = files(jacocoTestReport.classDirectories)
srcDirs = files(jacocoTestReport.sourceDirectories)
reports {
html = true
xml = true
}
violationRules {
minBranches = 1
minLines = 1
minInstructions = 1
failOnViolation = true
}
}
However, when I run inside Gitlab CI/CD, the execution fails because it cannot create diff.patch
. I believe the issue is becuase the folder where it wants to create it, build/reports/jacoco/
, because if I pre-create this folder empty, then the plugin finishes successfully.
This is the exception:
Caused by: java.io.FileNotFoundException: /builds/android/<REPO>/build/reports/jacoco/diff.patch (No such file or directory)
at kotlin.io.FilesKt__FileReadWriteKt.writeBytes(FileReadWrite.kt:108)
at kotlin.io.FilesKt__FileReadWriteKt.writeText(FileReadWrite.kt:134)
at kotlin.io.FilesKt__FileReadWriteKt.writeText$default(FileReadWrite.kt:134)
at com.form.coverage.tasks.git.GitDiffSource.saveDiffTo(DiffSource.kt:67)
at com.form.coverage.tasks.DiffCoverageTask.obtainUpdatesInfo(DiffCoverageTask.kt:109)
at com.form.coverage.tasks.DiffCoverageTask.executeAction(DiffCoverageTask.kt:61)
at com.form.coverage.tasks.DiffCoverageTask$executeAction.call(Unknown Source)
I verified that /builds/android/<REPO>
exists and it is the root of my project. I also verified that simply running mkdir -p ./build/reports/jacoco
before running my gradlew
command fixes it.
Can you help me identify why the folder would be successfully created when running locally but fails when running inside CI?
Describe the bug
I could see two items for each Scala class in the HTMP report. One is correct and another is not.
Desktop (please complete the following information):
To Reproduce
If possible, provide your configuration of the plugin, for example:
diffCoverageReport {
diffSource.file = 'diff.patch'
violationRules.failIfCoverageLessThan 0.9
}
Expected behavior
A clear and concise description of what you expected to happen.
Logs
If applicable, add stacktrace, Gradle output.
Additional context
Add any other context about the problem here.
Could not set unknown property 'reportDir'
diff-coverage-gradle/README.md
Line 168 in 502a2b4
Seems the correct property is baseReportDir
and the default ends with jacoco
(it appends the diffCoverage
subdirectory to the base path).
Describe the bug
Java: openjdk 21.
Gradle: 8.4
I hope the project still receives support π
Describe the bug
When filtering the classDirectories used in the jacoco coverage analysis, gradle fails with 'diffCoverageReport.classesDirs' is not configured
. When removing the afterEvaluate
section, everything works as intended.
Desktop (please complete the following information):
To Reproduce
Since this occurred in a larger project, I created a small reproduction project:
https://github.com/julian-christl/diffCoverageRepro
chore/repro
gradle clean test jacocoTestReport diffCoverage
Expected behavior
The tests run through, and the reports get created.
Logs
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':diffCoverage'.
> 'diffCoverageReport.classesDirs' is not configured.
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 63ms
Couldn't parse file relative path: +++ "......./\043\043\043 Fresh Video.json.withOption"
Hi,
I have configured the project to correctly run locally with multiple sub-projects.
However, when running inside Gitlab CI, then the task fails with:
Execution failed for task ':common-server:diffCoverage'.
> repo.resolve(name) must not be null
raised inside of:
private fun getTreeIterator(repo: Repository, name: String): AbstractTreeIterator {
val id: ObjectId = repo.resolve(name)
.
.
.
}
I wonder if this can be avoided by handling the null-case in any way?
subprojects {
apply plugin: 'jacoco'
apply plugin: 'com.form.diff-coverage'
diffCoverageReport {
diffSource {
git.compareWith 'master'
}
jacocoExecFiles = files(project.projectDir.path + '/build/jacoco/test.exec')
srcDirs = files(project.projectDir.path + '/src/main/java')
classesDirs = files(project.projectDir.path + '/build/classes/')
reports {
html = true
xml = true
baseReportDir = project.projectDir.path + '/build/reports/'
fullCoverageReport = false
}
violationRules.failIfCoverageLessThan 0.9
}
}
Gradle: 7.0
Kotlin: 1.4.31
Groovy: 3.0.7
diff-coverage-gradle: 0.8.0
jacocoTestReport
generates the code coverage report. However, diffCoverage
generates html file with "No class files specified." I suspect the issue is with classesDirs
and srcDirs
but unable to get proper report after trying multiple different approaches.
jacocoTestReport {
reports {
xml {
enabled true
destination file("${buildDir}/coverage-report/jacoco-report.xml")
}
html {
enabled true
destination file("${buildDir}/coverage-report")
}
}
afterEvaluate {
classDirectories.from = files(classDirectories.files.collect {
fileTree(dir: it, exclude: [
'**/generated/**'
])
})
}
}
diffCoverageReport {
diffSource {
git.compareWith 'refs/remotes/origin/main'
}
jacocoExecFiles = files(jacocoTestReport.executionData)
classesDirs = files(jacocoTestReport.classDirectories)
srcDirs = files(jacocoTestReport.sourceDirectories)
reports {
html = true
baseReportDir = "${buildDir}/coverage-report"
}
}
Describe the bug
When running a task like:
./gradlew clean testDebugUnitTestCoverage diffCoverage --no-build-cache
And configuring where the location of the class files can be found. Diff Coverage will through an error:
'diffCoverageReport.classesDirs' file collection is empty.
This is becuase the clean will have wiped out the location of the files and the configuration happens before the files are loaded.
Currently:
calls collectFilesOrThrow which eagerly collects the files instead of lazily doing it after the configuration phase has completed.
Ideally these should take Providers instead of FileCollections directly, so that when the task is executing it can get the files at that particular time instead of eagerly doing it whenever the get method is called.
That will always throw an error if clean is used. If clean is not used and the coverage has run before as a seperate step it'll pass.
Ideally a FileCollectionProvider should be used and read from the ReportGenerator.
Desktop (please complete the following information):
To Reproduce
./gradlew clean jacocoReport diffCoverage
Works if:
./gradlew clean jacocoReport
./gradlew diffCoverage
Expected behavior
./gradlew clean jacocoReport diffCoverage
should work without crashing
A clear and concise description of what you expected to happen.
Logs
Could not determine the dependencies of task ':lib:diffCoverage'.
'diffCoverageReport.classesDirs' file collection is empty.
Is it possible to use the csv or xml output with https://github.com/tomasbjerre/violation-comments-to-gitlab-gradle-plugin?
Would be nice to have the violations as comments in our GitLab ;)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.