用子模块配置Android项目以与sonarqube gradle插件一起使用的正确方法是什么? [英] What is the correct way to configure an Android project with submodules for use with the sonarqube gradle plugin?

查看:88
本文介绍了用子模块配置Android项目以与sonarqube gradle插件一起使用的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

从高度上讲,我正在使用具有以下结构的Android项目.

git_repository
|----- android_project
  |--- app
  |--- SDK
    |- api

git_repository包含README.md和其他顶级文件,包括android_project. android_project包含应用程序以及SDK中的git子模块.该git子模块包含应用程序需要运行的api代码.

问题在于,当我尝试运行声纳分析仪时,似乎正在寻找不存在的文件/目录.我没有一个更简单的最小项目的问题.我计划在星期一建立一个最小的项目,该项目使用子模块,但是我想在周末前解决这个问题.

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

在MacOS/Android Studio命令行设置中,此gradle任务失败,但最终目标是拥有与Jenkins一起使用的配置. 接下来是我的settings.gradle和build.gradle文件.显然我做错了.

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

解决方案

对于具有多个模块的项目,使用适当的通配符即可实现.

请按照以下步骤操作:

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

  2. 在主模块的build.gradle文件中的
  3. 中添加maven插件,然后 类依赖

这是上述两个文件的示例:

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

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

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"
}

只需将此行与上面文件中显示的所有其他应用行放在一起

apply from: '../sonarqube.gradle'

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

只需运行命令

./gradlew sonarqube 

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

如果您使用的是findbug,请在推送之前进行项目开发,否则构建将失败,因为findbug需要字节码进行分析.

不要使用该属性

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

此sonar.projectKey属性. SonarQube使用它来识别声纳数据库中的每个项目(或模块). 因此,如果所有模块都具有相同的projectKey值,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.)

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:

  1. in the master module which contains all the sub-modules place the sonarqube.gradle file

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

这篇关于用子模块配置Android项目以与sonarqube gradle插件一起使用的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆