What is the correct way to configure an Android project with submodules for use with the sonarqube gradle plugin? Google has not been my friend, but I may have missed something basic. (I search for sonarqube issues related to the android build directories and submodules. No useful results.)
At a very high level, I am working with an Android project with the following structure.
git_repository
|----- android_project
|--- app
|--- SDK
|- api
The git_repository contains the README.md and other top level files including the android_project. The android_project contains the the app, as well as a git submodule in SDK. This git submodules contains the api code that app needs to run.
The problem is that when I try to run sonarqube, it seems to be looking for files/directories that do not exist. I do not have this problem with a simpler minimal project. I plan to set up a minimal project that uses submodules on Monday, but I want to get this question out the door before I leave for the weekend.
$ ./gradlew clean sonarqube
* snip *
:sonarqube
Invalid value for sonar.java.test.libraries
:sonarqube FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':sonarqube'.
> No files nor directories matching '/Users/my_username/git_repository/android_project/app/build/intermediates/dependency-cache/debug'
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or -- debug option to get more log output.
BUILD FAILED
Total time: 9.897 secs
$
This gradle task is fail on a MacOS/Android Studio command line setup, but the ultimate goal is to have a configuration that works with Jenkins. My settings.gradle and build.gradle files follow. Clearly I am doing something wrong.
git_repository/android_project/settings.gradle complete listing
include ':app', ':api'
project(':api').projectDir = new File('SDK/api')
git_repository/android_project/build.gradle complete listing
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
apply plugin: 'org.sonarqube'
allprojects {
repositories {
jcenter()
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
}
//subprojects {
// sonarqube {
// properties {
// // property "sonar.sources", "src"
// }
// }
//}
//sonarqube {
// properties {
//// property "sonar.exclusions", "file:**/SDK/**"
// }
//}
subprojects {
sonarqube {
properties {
property "sonar.sourceEncoding","UTF-8"
property "sonar.sources","src/main/java"
property "sonar.java.binaries", "./build/"
property "sonar.tests","src/androidTest"
// property "sonar.exclusions","build,build/**,**/*.png"
property "sonar.import_unknown_files", true
property "sonar.android.lint.report", "./build/outputs/lint-results.xml"
}
}
}
project(":api") {
sonarqube {
skipProject = true
}
}
yes its a bit tricky for a project with multiple modules,its achieved using proper wildcards.
follow these steps:
in the master module which contains all the sub-modules place the sonarqube.gradle file
in the build.gradle file of the master module add the maven plugin and class dependencies
here is an example of two above mentioned files:
sonarqube.gradle
apply plugin: "org.sonarqube"
sonarqube {
//noinspection GroovyAssignabilityCheck
properties {
//noinspection GroovyAssignabilityCheck
property "sonar.projectName", "appar"
//noinspection GroovyAssignabilityCheck
property "sonar.projectVersion", "1.0"
//noinspection GroovyAssignabilityCheck
property "sonar.analysis.mode", "publish"
//noinspection GroovyAssignabilityCheck
property "sonar.language", "java"
//noinspection GroovyAssignabilityCheck
property 'sonar.sourceEncoding', "UTF-8"
//noinspection GroovyAssignabilityCheck
property "sonar.sources", "./src/main"
// noinspection GroovyAssignabilityCheck
property "sonar.exclusions", "src/main/java/com/appar/model/**, **/*Entity.java"
//noinspection GroovyAssignabilityCheck
property "sonar.host.url", "http://192.168.21.33:9000"
//noinspection GroovyAssignabilityCheck
property "sonar.login", "admin"
//noinspection GroovyAssignabilityCheck
property "sonar.profile", "fulllint"
//noinspection GroovyAssignabilityCheck
property 'sonar.import_unknown_files', true
//noinspection GroovyAssignabilityCheck
property "sonar.android.lint.report", "./build/outputs/lint-results-debug.xml"
//noinspection GroovyAssignabilityCheck
property "sonar.password", "admin"
//noinspection GroovyAssignabilityCheck
property "sonar.java.binaries", "build/"
}
}
build.gradle
buildscript {
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.0.1"
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
}
}
allprojects {
repositories {
jcenter()
}
}
then apply from sonarqube.gradle in build.gradle of separate modules
here is an example of build.gradle of one of the sub modules:
apply plugin: 'com.android.library'
apply from: '../sonarqube.gradle'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 21
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
testCoverageEnabled = true
}
}
}
dependencies {
compile project(':java-library')
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.1.4"
}
just put this line along with all other apply lines as shown in the above file
apply from: '../sonarqube.gradle'
after you apply sonarqube.gradle to all the build.gradle files in the sub modules.
just run the command
./gradlew sonarqube
trust me the project will successfully get build and get pushed into sonarqube server and the error results will get shown
if you are using findbugs make the project before pushing or else build will fail because the findbugs needs the bytecode to analyse.
And dont use the property
//noinspection GroovyAssignabilityCheck
property "sonar.projectKey", "appar_app"
This sonar.projectKey property. This is used by SonarQube to identify each project (or module) in sonar database. So if all your modules have same projectKey value, SonarQube will update one single project in its database. Don't worry, this property is automatically set with the folder name of each module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With