What is the correct way to set up an Android project using submodules for use with the sonarqube gradle plugin?
What is the correct way to set up an Android project using submodules for use with the sonarqube gradle plugin? Google wasn't my friend, but I might have missed something basic. (I'm looking for sonarbeb issues related to 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
git_repository contains README.md and other top-level files including android_project. The android_project contains the app as well as the git submodule in the SDK. This git submodule contains the api code for the application to execute.
The problem is when I try to start sonarqube it looks like you are looking for files / directories that don't exist. I don't have this problem with a simpler minimal project. I am planning on creating a minimal project that uses submodules on Monday, but I want this question to go 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 does not work in macOS / Android Studio command line setup, but the end goal is to set up a config that works with Jenkins. My settings.gradle and build.gradle files follow them. It is clear that I am doing something wrong.
git_repository / android_project / settings.gradle full list
include ':app', ':api'
project(':api').projectDir = new File('SDK/api')
git_repository / android_project / build.gradle full list
// 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
}
}
source to share
yes, it is a bit tricky for a multi-module project, which is achieved with appropriate wildcards.
do the following:
-
in the main module which contains all the submodules, the sonarqube.gradle file
-
in build.gradle file of main module add maven plugin and class dependencies
here is an example of the above two 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 with sonarqube.gradle in build.gradle of individual modules
here is an example build.gradle of one of the following 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 applicable lines as shown in the above file
apply from: '../sonarqube.gradle'
after you apply sonarqube.gradle to all build.gradle files in additional modules.
just run the command
./gradlew sonarqube
Trust me that the project will be successfully created and run on the sonarqube server and error results will be shown.
if you are using findbugs to make the project fail before pushing or build fail because findbugs needs bytecode to parse.
And don't use the property
//noinspection GroovyAssignabilityCheck
property "sonar.projectKey", "appar_app"
This is the sonar.projectKey property. This is used by SonarQube to define each project (or module) in the sonar database. Therefore, if all your modules have the same projectKey value, SonarQube will update one separate project in its database. Don't worry, this property is automatically set with the folder name for each module.
source to share