Closed brahma712 closed 5 years ago
There is no need to define sourceSets if you use the standard source layout. However, src/java is not standard. src/main/java is the standard.
Also, I notice one issue with your build.gradle. You only define dependencies to modules in the root project. The allprojects closure does not apply the dependencies block you have to the subprojects.
This is not a Clover plugin issue, your build is configured incorrectly even without the Clover plugin.
Remove the plugin, get your project building first without Clover. Then add the plugin after you have solved your basic Gradle issues.
I have a src/main/groovy and a src/main/java in all my modules. If I remove the plugin, my project builds fine.
You need to provide more details. I have many multimodule projects where this plugins works just fine. I suspect you have some issue in the project dependencies as you are not giving enough details to figure out what is going on or a specific error that needs to be resolved.
I am inclined to say that your multimodule setup is incomplete because of the observation I made regarding the dependencies that you appear to provide in the root project and not in allprojects.
FYI, you should change the wrapper task definition to avoid redefining the task.
wrapper {
gradleVersion = '4.10.1'
}
That should be sufficient to configure the default wrapper task.
I get groovyc compile errors on my java classes. only one of my modules has java classes. Rest of them don't have any java classes so it only fails on one module.
[groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
[groovyc] C:\.....r\src\main\groovy\org\.....\PlatformComposer.groovy: 36: unable to resolve class xxxxPlatform
[groovyc] @ line 36, column 20.
[groovyc] xxxxPlatform xxxPlatform = mapper.load(xxxPlatform.class, platformIdref)
[groovyc] ^
[groovyc]
The Gradle Clover plugin switches compilation to use the groovyc compiler via Ant task instead of the Gradle CompileGroovy task. This is necessary to invoke the Clover library during compilation and instrument the code. Are you making any complex sourceSet/classpath manipulations in your projects to get this to compile? Where is the definition of the xxxxPlatform class found in your code? Without the full picture I cannot say what you might be doing to trigger this.
All my java classes are under src/main/java.. for the module so the xxxxPlatform class lives under src/main/java too. i.e the java classes and the groovy classes that use the java classes are under the same high level src/main package. Does that help? I can try to include the plugin into a module's build file and see if it works just for that module.
That is strange, this is a very common configuration with Groovy referencing Java classes. It is the case of joint Groovy/Java compilation where the Groovy compiler is doing the compilation for both Java classes and Groovy classes. It is a supported use case.
Can you try the following change? Move the java classes from src/main/java to src/main/groovy keeping their package levels the same. This might explain where the code might have the issue and help work around it.
Do not rename the .java files to .groovy, just move them. The compiler is able to tell the difference by the name.
That actually fixes the issue I had. However, I get a different issue now...
>gradlew clean cloverAggregateReports
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':cloverAggregateReports'.
> You must specify one or more coverage databases to merge using a nested <cloverdb> or <cloverdbset> element.
You cannot run clean and cloverAggregateReports. cloverAggregateReports should be run together with the primary build to aggregate the reports generated by the cloverGenerateReport in check subproject. Clean removed all the data the aggregate task needs to do the work.
I get the same error even without the clean. I ran gradlew build first. and then gradlew cloverAggregateReports. I assume that I should see reports generating under build/reports?
Then your builds are not activating clover correctly. There should be reports generated for each individual subproject. Are you getting clover.db databases created in the subdirectories? In each subproject there should be a build/.clover directory that contains clover.db files. These are what cloverAggregateReports expects to find when it runs and merge their contents into an aggregate database at the root project with the collected coverage information.
I see a .clover folder but I do not see any clover.db databases created. I see a folder called "historypoints" but that's it.
Do I need
clover 'org.openclover:clover:4.3.1'
in all my subprojects build files?
Your allprojects configuration already does the dependency in all your subprojects.
I am not talking about the .clover in the project directory. I am talking about the build/.clover directory in each build subproject directory.
build/.clover directory does not exist under the build directory in my sub modules. Not even in my root project's build file.
I do get a .clover directory under the build directory if I add the configuration in the build file for my submodule and run gradlew cloverGenerateReport from the submodule.
Typical configuration examples for clover are in the functional tests area. Multiproject build.gradle
You should be configuring some of the clover closure parameters although in my experience the default works for most.
Does your root project have java code or is it just a container project for the subprojects?
Just a container for the subprojects. No code in there.
Even with the clover configuration, my build fails with the same error. I believe I am missing something in the build.gradle file. I compared the structure with the file you linked and I think all of that matches except I dont have a sub-projects block.
The allprojects block encompasses the subprojects block. You are not configuring any options for clover in the clover closure which means you get the defaults only. Since your top level project is a container project with no code I would have a subprojects block to configure the code generating projects with appropriate settings and a top level clover configuration in the root project. Also, your root project has no use for the java or groovy plugins and even the dependencies block. There is no code therefore the dependencies are unused.
Sure, but that change didn't fix much.. I am not sure what I am doing wrong.. Below is my revised build.gradle file. I am wondering if this structure would make a difference:
Root Project(container for modules) has a root build.gradle file
|
| _ _ Module1 (container for more modules) This does not have a build.gradle file
|
| _ _ module1 has a build.gradle file
| _ _ module2 has a build.gradle file
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.bmuschko:gradle-clover-plugin:2.2.2'
}
}
allprojects {
apply plugin: 'com.bmuschko.clover'
repositories {
jcenter()
}
dependencies {
clover 'org.openclover:clover:4.3.1'
}
}
subprojects {
apply plugin:'java'
apply plugin: 'groovy'
sourceCompatibility = 1.8
}
task wrapper(type: Wrapper) {
gradleVersion = '4.10.1'
}
I still have the same error:
gradlew cloverAggregateReports
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':cloverAggregateReports'.
> You must specify one or more coverage databases to merge using a nested <cloverdb> or <cloverdbset> element.
Add this to your allprojects block
allprojects {
apply plugin: 'com.bmuschko.clover'
repositories {
jcenter()
}
dependencies {
clover 'org.openclover:clover:4.3.1'
}
clover {
enabled = true
report {
json = true
html = true
pdf = true
}
}
}
See if that makes a difference. Should not be required but might be worth a try.
no luck. I had tried enabling the html reporting but that didnt make a difference either.
Here is some weirdness: I modified the build.gradle file in one of the modules as below:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.bmuschko:gradle-clover-plugin:2.2.2'
}
}
plugins {
id 'groovy'
id 'java'
}
apply plugin: 'com.bmuschko.clover'
group 'Auditd'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
clover {
enabled = true
}
dependencies {
// https://mvnrepository.com/artifact/org.codehaus.groovy/groovy
compile group: 'org.codehaus.groovy', name: 'groovy', version: '2.5.3'
// https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-xml
compile group: 'org.codehaus.groovy', name: 'groovy-xml', version: '2.5.3'
// https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-core
compile group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.2.0'
// https://mvnrepository.com/artifact/org.spockframework/spock-core
testCompile group: 'org.spockframework', name: 'spock-core', version: '1.2-groovy-2.5'
clover 'org.openclover:clover:4.3.1'
}
When I run gradlew cloverGenerateReport
I get a build/.clover directory with nothing in it.
I have never seen this and cannot help any further. As a last resort you could capture a full debug build log and attach to this issue. I can see if something is evident in the log.
gradlew --debug build > debug.log
Is another option installing open clover manually? Does that work with multi projects?
No, OpenClover does not work by itself. You need a Gradle plugin to drive it. They have a plugin alternative but it is not supporting Groovy.
I cannot see your project performing any unit test work. Does your project have any unit tests? Coverage is a function of the code being executed during unit tests. That is the meaning of coverage. Your code does not actually have unit tests!
It appears you are a bit clueless when it comes to coverage. Clover measures "Unit Test Code Coverage". This means your code must be executed by unit test code written by you with the purpose of testing the code paths within your implementation and verifying correctness. The coverage metric is just a measurement that can show you where you might have missed some conditional testing that must be expanded by additional test conditions in your unit tests.
Yes, my project has tests. They are spock tests under src/test/groovy. They exist for all modules that have the code.
I have used Clover before. And I know that it measures unit test coverage. My tests run when I run gradlew build locally. I will look into it why they aren't specifically "unit" tests Thanks for your help.
For your information, here is what I had to do to fix things:
I had to supply sourceSets for the tests configuration which is in my case src/test/groovy
and src/test/java
. Even though this is standard according to gradle documentation - however clover for some reason could not figure it out.
Here is what I added:
sourceSets {
main {
java {
srcDirs = ['src/main/java', 'src/main/groovy']
}
}
test {
java {
srcDirs = [ 'src/test/groovy', 'src/test/java']
}
}
}
I also had to add the following dependency: testCompile 'junit:junit:4.12'
Is this a requirement for the plugin? I did not see any documentation anywhere that states that.
thank you for your time on this.
The issue is not with this plugin. The issue is with your project. Your projects acted as if there were no unit tests at all. At least that is what the debug log claimed. For each one of the test
tasks the log claimed there were no matching sources and therefore they were skipped. In my opinion your unit tests were somehow not seen by the defaults. The most weird part is that your source sets actually match what should be the defaults.
Here is what the debug log states for each of your test
tasks prior to your fix which made me assume you had no unit tests defined.
13430: 17:59:06.480 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Workflow:OptimusSCAPExporter:test'
14016: 17:59:06.725 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:UnixLinux:Auditd:test'
14703: 17:59:08.438 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:UnixLinux:KernelModule:test'
15279: 17:59:08.679 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:AccessToken:test'
15855: 17:59:08.911 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:AuditEventPolicySubcategories:test'
16431: 17:59:09.151 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:LockoutPolicy:test'
17007: 17:59:09.379 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:PasswordPolicy:test'
17583: 17:59:09.608 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:RSOPSecuritySettingBoolean:test'
18159: 17:59:09.840 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:Registry:test'
18735: 17:59:10.076 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:RegistryUser:test'
19311: 17:59:10.313 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:User:test'
19895: 17:59:10.548 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:UserRightsAssignment:test'
20471: 17:59:10.775 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:UserRightsAssignmentDeny:test'
21066: 17:59:11.017 [DEBUG] [org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository] No discovered inputs for task ':Transforms:Windows:UserSID55:test'
I suspect that your multilevel nesting structure of this is causing the allprojects/subprojects blocks to apply partially to the subprojects. It is very likely that you did not actually configure each project as you might think causing them to fail this way.
Not having the rest of your project build files I cannot make any more assumptions.
As for the junit dependency, that is a requirement of Spock. Spock is a JUnit derivative and should have that as a transitive dependency. I commonly add junit as well as Spcok in all my projects. Again, nothing relating to this plugin, just missing or incomplete project layout configuration in your multilevel project structure.
It is extremley weird that I need to specify those sourceSets - I agree. Another strange part is that I get report generation for one module.. but not the others.. and what you saw in the logs is probably why its not generating reports for the other modules.. This is so strange.. I cant seem to be able to tell how the structure of the gradle build does not make sense.
Your unit tests are not found and not executed as far as I can tell.
Its very strange.. because I see reports getting populated after I run gradlew clean build. and there is an index.html that is generated under build/reports/tests/test. I am wondering if that means that tells you anything about the sourceSet not being the default. I have generally seen the report under build/reports/test? may be I am wrong.
Newer Gradle versions have changed the reports location for unit tests to exist under build/reports/tests/test. Older versions of Gradle had build/reports/test.
As I said, I do not use any specific sourceSets in my builds but I never nest more than one level either. There is a top container project with all submodules under one top level submodules
directory. So, there may be something tricky about your multilevel subproject builds that requires additional code in the top level to properly handle the layered module directories.
thats the only possibility left .. I have a high level container which contains submodules that are contains which in turn contain more modules and these modules have code.
So for example, root ModuleAcontains modules ModuleBand ModuleC. ModuleB is a container with modules X and Y. X and Y have modules in them but these have source code and tests within src/main and src/test and have their own build.gradle files. ModuleChas one single module Z. And the clover configuration works for that. I wonder if changing ModuleB to have less layers would change anything?
There is one root build.gradle file which is in ModuleA. But ModuleB and ModuleC don't have their own build.gradle files.
Does the above structure make sense? May be because of this structure, additional sourceSets are required? Or some other configuration that I don't know of.
I suspect your plugins are not applied uniformly because of the multilayer submodules. I have not tried to experiment with this level of nesting before, I may do a quick example project like yours to better understand the issue. It does seem to be related to the nesting level.
To satisfy my own curiosity I created a super simple project with a build.gradle and settings.gradle like these:
build.gradle
println 'All Projects'
allprojects { proj ->
println proj
}
println 'Subprojects'
subprojects { proj ->
println proj
}
settings.gradle
rootProject.name = 'rootProj'
include 'modules:projA:projB'
include 'modules:projA:projC'
include 'modules:projD:projE'
include 'modules:projD:projF'
The results indicate that allprojects and subprojects behave as we expect them to behave.
./gradlew project -q
All Projects
root project 'rootProj'
project ':modules'
project ':modules:projA'
project ':modules:projD'
project ':modules:projA:projB'
project ':modules:projA:projC'
project ':modules:projD:projE'
project ':modules:projD:projF'
Subprojects
project ':modules'
project ':modules:projA'
project ':modules:projD'
project ':modules:projA:projB'
project ':modules:projA:projC'
project ':modules:projD:projE'
project ':modules:projD:projF'
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'rootProj'
\--- Project ':modules'
+--- Project ':modules:projA'
| +--- Project ':modules:projA:projB'
| \--- Project ':modules:projA:projC'
\--- Project ':modules:projD'
+--- Project ':modules:projD:projE'
\--- Project ':modules:projD:projF'
To see a list of the tasks of a project, run gradlew <project-path>:tasks
For example, try running gradlew :modules:tasks
I want to share the dependency tree that I have with you but I cant put the proprietary stuff and classnames on here.. can I share it some other way? Pretty much the same as to what you have..
I do not know if it will help and I do not have more time to sort this out for you. It does not seem like an issue with the plugin and I have other pressing things taking my time.
If you can create a small example project that has simple java classes and Spock tests with the same nesting level and causes the same issue I am willing to investigate it. Make such a project in your Github and post the link to the code here. I do not know when I might find time to dig into it but I will try. This has to be able to prove that there is an issue with the nesting so do the minimum that will mimic the layout you use and your build.gradle files and will see what I can find.
https://github.com/brahma3691/multi-project-test
Pretty similar. I only added tests in one module and did not add in the other but you can assume that other directories have the same structure.
Your structure is quite unusual. Here are some notes.
Perhaps you put this together in a hurry and it is not completely representing your configuration.
Here is a fixed copy of your repository that actually works. https://github.com/Alex-Vol/gradle-clover-multiproject-example
The problem is that you are very inconsistent with your use of Gradle. Do not add gradle wrapper and settings.gradle in submodules. If you must add a gradlew create a script wrapper that calls the top level gradlew instead. Something like this:
@echo off
call ..\..\..\gradlew.bat %*
Thank you so much for taking the time to look at this. My issue roots from IntelliJ auto creating these files! I didn’t realize point#2 that you made about settings.gradle because I haven’t worked a lot with multi module projects. These modules were creators by doing letting IntelliJ set up a new module automatically for you. Thanks again I’m going to implement some changes to my project to get it to work. I appreciate your effort to help me fix this
And my issues are fixed! I removed the gradle wrappers and settings.gradle from each module and merged everything into one single build file at the root. One thing I found additionally is I had groovy and java under each src/main and src/test but the java folder had nothing under it - it was created by IntelliJ with the New Module creation functionality. If I removed that directory, the clover reports were generated but if I had the empty java directories the clover reports were not generating. Which I find strange. But THANK YOU SO MUCH!
I am still having issues resolving Java classes in my project. Here is my build file for reference...
I have a multi-module project and each module has a src/main/groovy and src/main/java. Do I need to define sourceSets in my allProjects closure? Am I missing some configuration? When I run
gradlew clean cloverAggregateReports
it fails to compile my java classes.Originally posted by @brahma3691 in https://github.com/bmuschko/gradle-clover-plugin/issues/131#issuecomment-471575742