gradle - 使用 Grade、Jacoco 和 Sonarqube 处理多项目构建
问题描述
到目前为止这是有效的(至少看起来它有效),但我不觉得它是惯用的,或者即使几个月也能经受住时间的考验。有什么办法可以做得更好或更“按书”?
我们在 Gradle 中有一些多项目构建,其中一个项目的测试可能会触及另一个项目的代码,因此即使它不在同一个项目中,但它在同一个多项目中,查看覆盖率也很重要。我可能正在解决不存在的问题,但在早期的 SonarQube 版本中,我必须“jacocoMerge”覆盖结果。
jacocoTestReport {
reports {
executionData (tasks.withType(Test).findAll { it.state.upToDate || it.state.executed })
xml.enabled true
}
}
if(!project.ext.has('jacocoXmlReportPathsForSonar')) {
project.ext.set('jacocoXmlReportPathsForSonar', [] as Set<File>)
}
task setJacocoXmlReportPaths {
dependsOn('jacocoTestReport')
doLast {
project.sonarqube {
properties {
property 'sonar.coverage.jacoco.xmlReportPaths', project.
ext.
jacocoXmlReportPathsForSonar.
findAll { d -> d.exists() }.
collect{ f -> f.path}.
join(',')
}
}
}
}
project.rootProject.tasks.getByName('sonarqube').dependsOn(setJacocoXmlReportPaths)
sonarqube {
properties {
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.tests", []
property "sonar.junit.reportPaths", []
}
}
afterEvaluate { Project evaldProject ->
JacocoReport jacocoTestReportTask = (JacocoReport) evaldProject.tasks.getByName('jacocoTestReport')
evaldProject.ext.jacocoXmlReportPathsForSonar += jacocoTestReportTask.reports.xml.destination
Set<Project> dependentProjects = [] as Set<Project>
List<String> configsToCheck = [
'Runtime',
'RuntimeOnly',
'RuntimeClasspath',
'Compile',
'CompileClasspath',
'CompileOnly',
'Implementation'
]
evaldProject.tasks.withType(Test).findAll{ it.state.upToDate || it.state.executed }.each { Test task ->
logger.debug "JACOCO ${evaldProject.path} test task: ${task.path}"
sonarqube {
properties {
properties["sonar.junit.reportPaths"] += task.reports.junitXml.destination.path
properties["sonar.tests"] += task.testClassesDirs.findAll { d -> d.exists() }
}
}
configsToCheck.each { c ->
try {
Configuration cfg = evaldProject.configurations.getByName("${task.name}${c}")
logger.debug "JACOCO ${evaldProject.path} process config: ${cfg.name}"
def projectDependencies = cfg.getAllDependencies().withType(ProjectDependency.class)
projectDependencies.each { projectDependency ->
Project depProj = projectDependency.dependencyProject
dependentProjects.add(depProj)
}
} catch (UnknownConfigurationException uc) {
logger.debug("JACOCO ${evaldProject.path} unknown configuration: ${task.name}Runtime", uc)
}
}
}
dependentProjects.each { p ->
p.plugins.withType(JacocoPlugin) {
if (!p.ext.has('jacocoXmlReportPathsForSonar')) {
p.ext.set('jacocoXmlReportPathsForSonar', [] as Set<File>)
}
p.ext.jacocoXmlReportPathsForSonar += jacocoTestReportTask.reports.xml.destination
JacocoReport dependentJacocoTestReportTask = (JacocoReport) p.tasks.getByName('jacocoTestReport')
dependentJacocoTestReportTask.dependsOn(jacocoTestReportTask)
setJacocoXmlReportPaths.dependsOn(dependentJacocoTestReportTask)
}
}
}
解决方案
推荐阅读
- python - 使用 python win32com 找不到活动的 excel
- bash - 从 `conda list` 输出安装所有内容
- c# - 如何将 SQLite 数据库中的特定单元格转换为 WinForms 文本框中的字符串?
- python - 在 Kivy 文件和 python 文件中使用 ScreenManager
- asp.net - 我无法从 Docker 上的 IIS 外部访问该站点
- java - 使用jackson从json中删除空格
- python - 在python中的一个公共列上合并两个数据框
- javascript - 加载前如何在前端使用javascript获取外部图像的文件大小
- c++ - C ++:读取文件时如何跳转到下一个立即行?
- python - 为什么我的程序最后打印 None ?