Maven Sonar Scanner Exclude a directory - sonarqube

I am trying to exclude a directory of generated source code files from being analyzed by the Maven Sonar Scanner plugin.
My folder structure looks like this:
├── processors
│   └── src
│   └── main
│   └── java
│   └── org
│   └── protobuf
└── schemas
└── src
└── main
└── java
└── org
└── generated
└── models
└── ModelA.java
└── ModelB.java
I'm trying to exclude everything under schemas.
When I run the command I do the following:
mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.3.0.603:sonar
-Dsonar.projectKey=myProjectKey
-Dsonar.projectName=myProjectName
-Dsonar.login=myLoginKey
-Dsonar.password=myPassword
-Dsonar.language=java
-Dsonar.sources=.
-Dsonar.exclusions=schemas/**/*
-Dsonar.junit.reportPaths=target/surefire-reports
-Dsonar.jacoco.reportPaths=target/jacoco-ut.exec
The output says:
[INFO] Excluded sources:
[INFO] schemas/**/*
...
[INFO] 2 files indexed
[INFO] 0 files ignored because of inclusion/exclusion patterns
I'd like to exclude that entire directory, and all of it's contents. How do I get sonar scanner to do this?

Related

Unable to compile code generated using gradle-swagger-generator-plugin

I am facing a problem that code generated using gradle-swagger-generator-plugin is not compiling due to unresolved dependencies.
I have a multimodule gradle project with the following folder structure. parent is the parent project with three subprojects named modules:apis, modules:api-client, and modules:common
.
├── parent
│   ├── build.gradle
│   ├── gbuild
│   ├── gradle
│   │   └── wrapper
│   │   ├── gradle-wrapper.jar
│   │   └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── modules
│   │   ├── apis
│   │   │   ├── build.gradle.kts
│   │   │   ├── gbuild
│   │   │   └── src
│   │   ├── api-client (generated)
│   │   │   ├── README.md
│   │   │   ├── build.gradle
│   │   │   ├── build.sbt
│   │   │   ├── docs
│   │   │   ├── gbuild
│   │   │   ├── git_push.sh
│   │   │   ├── gradle
│   │   │   ├── gradle.properties
│   │   │   ├── gradlew
│   │   │   ├── gradlew.bat
│   │   │   ├── pom.xml
│   │   │   ├── settings.gradle
│   │   │   └── src
│   │   └── common
│   │   ├── build.gradle.kts
│   │   ├── gbuild
│   │   └── src
│   ├── project_version.properties
│   └── settings.gradle.kts
Module :modules:apis is the spring boot REST service for which I want to generate client SDK. Module :modules:api-client is the placeholder project wherein the client code is generated.
Relevant sections from the modules/apis/build.gradle.kts are as given below.
plugins {
// Some plugins omitted for clarity
java
id("org.springframework.boot")
id("io.spring.dependency-management")
id("org.hidetake.swagger.generator") version "2.18.2"
}
dependencies {
// Other dependencies omitted
implementation (Libs.io_swagger_core)
swaggerCodegen("io.swagger.codegen.v3:swagger-codegen-cli:3.0.27")
}
swaggerSources {
create("testcode") {
// File api-spec is already generated and placed at the right location.
setInputFile(file("$projectDir/src/main/resources/swagger/api-spec.json"))
code(
closureOf<org.hidetake.gradle.swagger.generator.GenerateSwaggerCode> {
wipeOutputDir = true
language = "java"
configFile = file("$projectDir/src/main/resources/swagger/api-config.json")
outputDir = file(
"$rootDir/modules/client"
)
}
)
}
}
tasks.named("build") { dependsOn("generateSwaggerCode") }
What works: I can generate client code using gradle clean build in modules\apis and build it using .\gradle.bat clean build or using gradle clean build in modules\api-client.
What does not work: When I build the parent project using .\gradlew build --no-daemon --stacktrace --info in the parent folder, the task :modules:api-client:compileJava fails with compiler errors only for the first run. Compilation fails because gradle fails to resolve dependencies from modules\api-client\build.gradle. Compiler errors can be found in the attached file.
However, subsequent builds using the same command succeed without problem until modules\api-client folder is deleted manually.
Gradle version used by the parent project
\path\to\parent> .\gradlew.bat --version
------------------------------------------------------------
Gradle 6.7
------------------------------------------------------------
Build time: 2020-10-14 16:13:12 UTC
Revision: 312ba9e0f4f8a02d01854d1ed743b79ed996dfd3
Kotlin: 1.3.72
Groovy: 2.5.12
Ant: Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM: 1.8.0_181 (Oracle Corporation 25.181-b13)
OS: Windows 10 10.0 amd64
Gradle version used by :modules:api-client subproject
\path\to\parent\modules\api-client> .\gradlew.bat --version
------------------------------------------------------------
Gradle 2.6
------------------------------------------------------------
Build time: 2015-08-10 13:15:06 UTC
Build number: none
Revision: 233bbf8e47c82f72cb898b3e0a96b85d0aad166e
Groovy: 2.3.10
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM: 1.8.0_181 (Oracle Corporation 25.181-b13)
OS: Windows 10 10.0 amd64
I have tried this with all four combinations of options --build-cache and --no-parallel but got the same result. I am relatively new to gradle and took a wild guess that these two options may be playing role in this problem.
Any help in resolving this issue will be highly appreciated.
Thanks
Anand
You should put the generated classes in the buildDir (since you don't want to modifiy them as they get regenerated at each build) and then you need to add the generated class to your sourceSet.
In your build.gradle.kts add this:
configure<SourceSetContainer> {
named("main") {
java.srcDir("$buildDir/generated/src/main/java")
}
}
With the path being the one you specify in your swagger generation task.
Also on my case I set the dependency on the KotlinCompile task:
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
dependsOn("generateSwaggerCode")
kotlinOptions.jvmTarget = "11"
}
Make sure that this "generateSwaggerCode" does generate the code you need though (./gradlew generateSwaggerCode)

Gradle build: how to set up a multilevel project (3+ levels)?

I am having troubles with seting up 3 level gradle multi-project:
Level_1_Proj
│
├── Level_2_Proj_A
│ │
│ ├── Level_3_Proj_C
│ └── Level_3_Proj_D
│
└── Level_2_Proj_B
│
├── Level_3_Proj_E
└── Level_3_Proj_F
I would like to be able to:
set up dependencies between projects of the same level in the build script, like:
dependencies {
project('Level_2_Proj_A') {
dependencies {
implementation project('Level_2_Proj_B')
}
}
}
also want to be able to build (the subtree) starting the bash command [$gradle build] at any level [then build down the projects' subtree]
I have achieved building from the middle and bottom levels, but I cannot setup the build from the top level. Getting error:
A problem occurred evaluating project ‘Level_2_Proj_A’.
Project with path ‘Level_3_Proj_C’ could not be found in project ‘Level_2_Proj_A’.
Is it possible? If so, how to configure?
Thanks
Alright, here's how I managed to get it working. Given the following directory structure:
.
├── A
│   ├── C
│   │   └── build.gradle.kts
│   ├── D
│   │   └── build.gradle.kts
│   └── build.gradle.kts
├── B
│   ├── E
│   │   └── build.gradle.kts
│   ├── F
│   │   └── build.gradle.kts
│   └── build.gradle.kts
├── build.gradle.kts
├── gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts
The settings.gradle.kts has the following content:
rootProject.name = "multi-module-build"
include(":A")
include(":A:C")
include(":A:D")
include(":B")
include(":B:E")
include(":B:F")
Each build.gradle.kts has a call task that prints the name path of the project, e.g.
Inside the C project:
tasks.register("call") {
println(":A:C")
}
Inside the A project:
tasks.register("call") {
dependsOn(":A:C:call")
dependsOn(":A:D:call")
println(":A")
}
tasks["build"].dependsOn(":A:call")
The tasks["build"].dependsOn(":A:call") tells Gradle to invoke :A:call when building. The two dependsOn inside the call definition for A invoke the subproject call tasks.
There is a similar structure available for B.
When running gradle build at root level, this is the output I get:
:A
:B
:A:C
:A:D
:B:E
:B:F
When running gradle build inside the A subproject, I get:
:A
:A:C
:A:D
When running it inside :A:C, I don't get any output because I haven't specified that C's build task should depend on call, but that could easily be done.
Let me know if this doesn't work for you. I've used the Kotlin DSL for gradle, but you're perfectly free to change it to the Groovy variant.

How to get jacoco code coverage report in gradle project

I'm new to Groovy gradle world, I've written small groovy project with all test cases. I'm trying to generate code coverage report using jacoco plugin. But it generates only test report not code coverage report. Please find my jacoco gradle file config. I'm using gradle 4.5 version and Groovy Version: 2.5.0-rc-2 JVM: 1.8.0_171 Vendor: Oracle Corporation OS: Windows 10
What I'm missing here in order to generate jacoco code coverage report in html format.
Appreciated your help in advance!
My jacoco.gradle
apply plugin: "jacoco"
jacoco {
toolVersion = '0.8.1'
}
jacocoTestReport {
group = "reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled true
html.enabled true
csv.enabled false
html.destination "${buildDir}/jacocoHtml"
}
sourceDirectories = fileTree(dir: 'src/main/myproject')
}
I'm running gradle clean build command to generate build folder under my project repository.
Option 1
Run gradle build jacocoTestReport to generate JaCoCo code coverage report.
Option 2.1
Make tasks dependent in your Gradle scripts:
build.dependsOn jacocoTestReport
and then just run gradle build. JaCoCo report will be generated at each build task execution.
Option 2.2 (proposed by Filip Malczak)
Add to your Gradle scripts:
test.doLast jacocoTestReport.&execute
It works in similar fashion as the previous option, but generates report after every execution of test task. It can be useful if you tend to work by running test instead of build.
My solution is based on Gradle 7.3.2
So, first of all, apply the Jacoco plugin to your gradle project. Below should be in your build.gradle file. If you already have a plugins section, then just add the entry id 'jacoco' in separate line
plugins {
id 'jacoco'
}
This exposes a task named jacocoTestReport and jacocoTestCoverageVerification.
Yo can optionally configure the task to override default values. For e.g. below code will also generate the xml report for coverage, which is mostly needed by SonarQube to analyse the code coverage.
jacocoTestReport {
reports {
xml.required = true
}
}
In order to generate the coverage report you can execute
gralde jacocoTestReport manually
And it will generate reports under
build/reports/jacoco/test folder
However, we would want to execute the coverage report post the gradle test tasks.
So, to achieve this, add below entry in gradle file.
test.finalizedBy(jacocoTestReport)
Now, even if you do gradle test or gradle clean build (test will be implicitly called), you will still see the jacocoTestReport task being executed and reports getting generated.
Below is the jacoco generated report tree structure.
build/reports/jacoco
└── test
├── html
│   ├── index.html
│   ├── jacoco-resources
│   │   ├── branchfc.gif
│   │   ├── branchnc.gif
│   │   ├── branchpc.gif
│   │   ├── bundle.gif
│   │   ├── class.gif
│   │   ├── down.gif
│   │   ├── greenbar.gif
│   │   ├── group.gif
│   │   ├── method.gif
│   │   ├── package.gif
│   │   ├── prettify.css
│   │   ├── prettify.js
│   │   ├── redbar.gif
│   │   ├── report.css
│   │   ├── report.gif
│   │   ├── session.gif
│   │   ├── sort.gif
│   │   ├── sort.js
│   │   ├── source.gif
│   │   └── up.gif
│   └── jacoco-sessions.html
└── jacocoTestReport.xml

Configure Intellij Idea to import generated files

I'm having trouble to import a generated package with Intellij, however without any changes to the default settings it works on Eclipse.
Here is my architechture:
├── build.properties
├── pom.xml
├── README.md
├── src
│   ├── main
│   │   ├── java
│   │      └── mypackage
│   └── test
└── target
├── classes
│ └── mypackage
| └── generated
├── generated-sources
├── generated-test-sources
├── APP.jar
└── test-classes
I have most of my classes in com.mypackage however some of them are generated in
└── target
├── classes
└── mypackage
named as com.mypackage.generated and i have to use these classes in com.mypackage:
├── src
├── main
├── java
└── mypackage
However intellij cannot resolve symbol generated when I'm doing
import com.mypackage.generated
I tried to make it work by looking at the project structure/modules/dependencies menu but it seems to be for external modules. How can I do this ?
Actually it was very simple, I only was about marking classes as sources root. I don't know why marking generated as sources root did not work.

Gradle plugin packaging - Why is plugin unexpectedly applied?

So I have:
buildSrc/
├── build.gradle
└── src
├── main
│   ├── groovy
│   │   └── build
│   │   ├── ExamplePlugin.groovy
│   │   └── ExampleTask.groovy
│   └── resources
│   └── META-INF
│   └── gradle-plugins
│   └── build.ExamplePlugin.properties
└── test
└── groovy
└── build
├── ExamplePluginTest.groovy
└── ExampleTaskTest.groovy
Question:
It seems like build.ExamplePlugin.properties maps directly to the build.ExamplePlugin.groovy. Is this the case? Seems terribly inefficient to have only one property in the file. Does it have to be fully qualified, i.e. does the name have to exactly match the full qualification of the class?
Now in the example, I see:
project.pluginManager.apply 'build.ExamplePlugin'
...however if I have that in my test, I get an error to the effect that the simple task the plugin defines, is already defined.
Why bother with test examples that require 'apply' when that is inappropriate for packaging?

Resources