使用 sonarqube gradle 插件配置带有子模块的 Android 项目的正确方法是什么?

使用 sonarqube gradle 插件配置带有子模块的 Android 项目的正确方法是什么?

问题描述:

配置带有子模块的 Android 项目以与 sonarqube gradle 插件一起使用的正确方法是什么?谷歌不是我的朋友,但我可能错过了一些基本的东西.(我搜索与 android 构建目录和子模块相关的 sonarqube 问题.没有有用的结果.)

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.)

在一个非常高的层次上,我正在处理一个具有以下结构的 Android 项目.

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 包含 README.md 和其他*文件,包括 android_project.android_project 包含应用程序,以及 SDK 中的 git 子模块.这个 git 子模块包含应用程序需要运行的 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.

问题是,当我尝试运行 sonarqube 时,它​​似乎在寻找不存在的文件/目录.对于更简单的最小项目,我没有这个问题.我计划在星期一建立一个使用子模块的最小项目,但我想在周末离开之前解决这个问题.

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
$

这个 gradle 任务在 MacOS/Android Studio 命令行设置上失败,但最终目标是有一个适用于 Jenkins 的配置.我的 settings.gradle 和 build.gradle 文件如下.显然我做错了什么.

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完整列表

include ':app', ':api'
project(':api').projectDir = new File('SDK/api')

git_repository/android_project/build.gradle完整列表

// 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.

请按照以下步骤操作:

  1. 在包含所有子模块的主模块中放置sonarqube.gradle 文件

在master模块的build.gradle文件中添加maven插件并类依赖

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()
    }
}

然后从 sonarqube.gradle 应用到单独模块的 build.gradle

then apply from sonarqube.gradle in build.gradle of separate modules

这里是其中一个子模块的 build.gradle 示例:

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'

将 sonarqube.gradle 应用到子模块中的所有 build.gradle 文件之后.

after you apply sonarqube.gradle to all the build.gradle files in the sub modules.

直接运行命令

./gradlew sonarqube 

相信我,该项目将成功构建并推送到 sonarqube 服务器中,并且会显示错误结果

trust me the project will successfully get build and get pushed into sonarqube server and the error results will get shown

如果您使用 findbugs,请在推送之前创建项目,否则构建将失败,因为 findbugs 需要字节码来分析.

if you are using findbugs make the project before pushing or else build will fail because the findbugs needs the bytecode to analyse.

并且不要使用该属性

//noinspection GroovyAssignabilityCheck
            property "sonar.projectKey", "appar_app"

这个 sonar.projectKey 属性.SonarQube 使用它来识别声纳数据库中的每个项目(或模块).因此,如果您的所有模块都具有相同的 projectKey 值,SonarQube 将更新其数据库中的一个项目.不用担心,这个属性会自动设置为每个模块的文件夹名称.

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.