
рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░!
рдореЗрд░рд╛ рдирд╛рдо рдПрд░реНрдЯреЛрдо рдбреЛрдмреНрд░реЛрд╡рд┐рдВрд╕реНрдХреА рд╣реИ, рдореИрдВ рдлрд┐рдирд┐рдЪ рдореЗрдВ рдПрдХ рдПрдВрдбреНрд░реЙрдЗрдб рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реВрдВред
рдПрдХ рдмрд╛рд░, рдПрдХ рдХрдВрдкрдиреА рдХреЗ рдПрдХ рд╕рд╣рдХрд░реНрдореА рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЯреНрд╕ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЗ рдмрд╛рдж, рдЬреЛ рдЗрдЧреЛрд░ рдирд╛рдо рдХреЗ MIGs рдФрд░ рдордЪреНрдЫрд░реЛрдВ рдХреЛ рдмреЗрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдЬреНрдЮрд╛рдкрди рджреЗ рд░рд╣рд╛ рд╣реИ, рд╣рдордиреЗ CI рдореЗрдВ рд╕реНрдЯреЗрдЯрд┐рдХ рдХреЛрдб рдПрдирд╛рд▓рд┐рд╕рд┐рд╕ (рдФрд░ рдХреНрдпрд╛ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВ) рдкрд░ рдЪрд░реНрдЪрд╛ рд╢реБрд░реВ рдХреАред рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рдХреЛ рдЖрд╡рд╛рдЬ рджреА рдЧрдИ рдереА рдХрд┐ рд╡реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢рд╛рдВрдд рдереЗ - рд▓реЗрдХрд┐рди рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдХреЛрдб рдХреА рддрд╛рд░реНрдХрд┐рдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдореЗрдВ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдерд╛ред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдЖрдк рд╕рднреА рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж рд╣реА рдХреЛрдб рд╢реИрд▓реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВред
рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд╕рд╣рдпреЛрдЧреА рдХреЛ рд╕реБрдирдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛ рдХрд┐ рддрд╛рддреНрдХрд╛рд▓рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдкрджрд╛ рдХреЗ рдкреИрдорд╛рдиреЗ рдХреА рдЧрдгрдирд╛ рдХреИрд╕реЗ рдХреА рдЬрд╛рдПред рд╕реЛрдирд╛рд░рдХреНрдмреА рдФрд░ рдЬреИрдХреЛрдХреЛ рдкрд░ рджреГрд╢реНрдп рдЧрд┐рд░ рдЧрдпрд╛ред рд╣реИрд▓реЛ-рд╡рд░реНрд▓реНрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдердорд┐рдХ рд╣реИред рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдЯреВрдЯреЗ рд╣реБрдП, рдЙрдиреНрд╣реЗрдВ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реИред рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЛрдВ рдХреА рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд▓реЗрдЦ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред
Habr├й рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА Sonarqube рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХрд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдЕрдиреБрд╡рд╛рдж рд╣реИ - рд▓реЗрдХрд┐рди рдпрд╣ 2016 рд╕реЗ рд╣реИ, рд╡рд╣рд╛рдВ рдХреБрдЫ рдкреБрд░рд╛рдирд╛ рд╣реИ, рдХреЛрдИ рдХреЛрдЯрд▓рд┐рди рдирд╣реАрдВ рд╣реИ рдФрд░ рдмрд╕ рдореБрдЭреЗ рд╕рднреА рдмрд┐рд▓реНрдбрдЯрд╛рдЗрдк рдХреЗ рдЕрддрд┐рд░реЗрдХ рдХреЗ рд▓рд┐рдП рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдкреАрдврд╝реА рдорд┐рд▓рддреА рд╣реИред
рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛, рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдЙрдирд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реИрдВред
рд╕реЛрдирд╛рд░рдХреНрдмреА рдирд┐рд░рдВрддрд░ рдирд┐рд░реАрдХреНрд╖рдг рдФрд░ рдХреЛрдб рдЧреБрдгрд╡рддреНрддрд╛ рдХреА рдорд╛рдк рдХреЗ рд▓рд┐рдП рдПрдХ рдЦреБрд▓рд╛ рд╕реНрд░реЛрдд рдордВрдЪ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рд╕рдордп рдХреЗ рд╕рд╛рде рддрдХрдиреАрдХреА рдЛрдг рдХреЗ рдЦрд┐рд▓рд╛рдл рд▓рдбрд╝рд╛рдИ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рдпрд╣ рджреЗрдЦрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рддрдХрдиреАрдХреА рдЛрдг рдЬреАрдд рд░рд╣рд╛ рд╣реИ, рдФрд░ рдЖрдк рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред рд╕реЛрдирд╛рд░ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЛрдб, рд╕рдВрднрд╛рд╡рд┐рдд рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЕрддреНрдпрдзрд┐рдХ рдЬрдЯрд┐рд▓рддрд╛ рдкрд░ рднреА рдирдЬрд╝рд░ рд░рдЦрддрд╛ рд╣реИред
рдЬреИрдХреЛрдХреЛ рдЬрд╛рд╡рд╛ рдореЗрдВ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХрд╡рд░реЗрдЬ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдореБрдлреНрдд рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИред рд▓реЗрдХрд┐рди рдХреЛрдЯрд▓рд┐рди рдХреЗ рд╕рд╛рде рд╣рдо рдЙрд╕рдХреЗ рджреЛрд╕реНрдд рдмрдирд╛рдПрдВрдЧреЗред
рд╕реЛрдирд╛рд░рдХреНрдмреА рдФрд░ рдЬреИрдХреЛрдХреЛ рдХреЛ рдХреИрд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдП
рд░реВрдЯ рдореЙрдбреНрдпреВрд▓ рдХреЗ build.gradle рдореЗрдВ, рдирд┐рдореНрди рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ:
apply plugin: 'android.application' apply plugin: 'org.sonarqube' sonarqube { properties { property "sonar.host.url", "%url sonarqube%" property "sonar.login", "%%" property "sonar.projectName", "% %" property "sonar.projectKey", "% %" property "sonar.reportPath", "${project.buildDir}/sonarqube/test.exec" property "sonar.projectBaseDir", "$rootDir" property "sonar.sources", "." property "sonar.tests", "" property "sonar.coverage.exclusions", "**/src/androidTest/**, **/src/test/**" property "sonar.coverage.jacoco.xmlReportPaths", fileTree(include: ['*/*/jacoco*.xml'], dir: "$rootDir/app/build/reports/jacoco").collect() } }
sonar.reportPath
- рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╕реЛрдирд╛рд░ рдХреЛ рдЖрдЧреЗ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рд░рд┐рдкреЛрд░реНрдЯ рдХрд╣рд╛рдВ рд░рдЦрдиреА рдЪрд╛рд╣рд┐рдПред
sonar.projectBaseDir
рдЙрд╕ рдлрд╝реЛрд▓реНрдбрд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ рдЬрд┐рд╕рдореЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╢реБрд░реВ рдореЗрдВ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛; рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ $ rootDir рд╣реИ - рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рд░реВрдЯ рдлрд╝реЛрд▓реНрдбрд░ред
sonar.coverage.exclusions
рдХрд╡рд░реЗрдЬ рдХреА рдЧрдгрдирд╛ рдХреЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ ** рдХреЛрдИ рднреА рдлрд╝реЛрд▓реНрдбрд░ рд╣реИ, * рдПрдХ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдпрд╛ рд╕рдВрдХрд▓реНрдк рд╣реИред
sonar.sources
рд╕реНрд░реЛрдд рдлрд╝реЛрд▓реНрдбрд░ рд╣реИред
sonar.tests
рдпрд╣рд╛рдВ рдПрдХ рдЦрд╛рд▓реА рд▓рд╛рдЗрди рд╣реИ, рддрд╛рдХрд┐ рд╕реЛрдирд╛рд░рдХреНрдмреА рджреНрд╡рд╛рд░рд╛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред
sonar.coverage.exclusions
- рд╣рдо рдкрд░реАрдХреНрд╖рдг рдХрд╡рд░реЗрдЬ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╕реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдмрд╛рд╣рд░ рдХрд░рддреЗ рд╣реИрдВред
sonar.coverage.jacoco.xmlReportPaths
- collect()
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ collect()
рдкрд░реАрдХреНрд╖рдг рдХрд╡рд░реЗрдЬ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреИрдХреЛрдХреЛ рд░рд┐рдкреЛрд░реНрдЯ рдПрдХрддреНрд░ рдХрд░рддреЗ рд╣реИрдВред
рдЬреИрдХреЛрдХреЛ рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ jacoco.gradle
рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдирд╛ рдФрд░ рд╡рд╣рд╛рдВ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рддрд░реНрдХ рд▓рд┐рдЦрдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рдпрд╣ рдЕрдиреНрдп build.gradle рдЕрд╡реНрдпрд╡рд╕реНрдерд╛ рд╕реЗ рдмрдЪрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред
рдкреНрд░рддреНрдпреЗрдХ рд╕рдмрдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдмрд┐рд▓реНрдб.рдЧреНрд░реЗрдб рдореЗрдВ рдЬреИрдХреЛрдХреЛ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рдмрдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреНрд▓реЛрдЬрд░ рдореЗрдВ рдЗрд╕рдХреЗ рдЖрд░рдВрднреАрдХрд░рдг рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред reportsDirPath
рд▓рд┐рдП reportsDirPath
, рд░реВрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВред рд╡рд╣рд╛рдВ рд╕реЗ, рд╕реЛрдирд╛рд░ рд╕рднреА рдЬреИрдХреЛрдХреЛ рд░рд┐рдкреЛрд░реНрдЯ рд▓реЗрдВрдЧреЗред
subprojects { apply plugin: 'jacoco' jacoco { toolVersion = '0.8.5' def reportsDirPath = "${project.rootDir}/app/build/reports/jacoco/${project.name}" reportsDir = file(reportsDirPath) } }
рдЙрд╕реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ, рд╣рдо рдЬреИрдХреЛрдХреЛ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрддреЗ рд╣реИрдВред
рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд▓реЗ рдореИрдВ рдЗрд╕реЗ рд▓рд╛рдКрдВрдЧрд╛ - рдФрд░ рдлрд┐рд░ рдореИрдВ рд╕рдордЭрд╛рдКрдВрдЧрд╛ рдХрд┐ рдЗрд╕рдореЗрдВ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред
def configureJacoco = { project -> def variantName = project.name project.tasks.create(name: "getJacocoReports", type: JacocoReport) { group = "Reporting" description = "Generate Jacoco coverage reports for the $variantName build." reports { html.enabled = true xml.enabled = true } def excludes = [ '**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/AndroidManifest.xml', '**/*Test*.*', 'android/**/*.*', 'androidx/**/*.*', '**/*Fragment.*', '**/*Activity.*', '**/*Api.*', '**/injection/**/*.class', '**/ui/**/*.class', % build- % ] def javaClasses = fileTree(dir: "${project.buildDir}/intermediates/javac", excludes: excludes) def kotlinClasses = fileTree(dir: "${project.buildDir}/tmp/kotlin-classes", excludes: excludes) classDirectories = files([javaClasses, kotlinClasses]) sourceDirectories = files([ "${project.projectDir}/src/main/java", "${project.projectDir}/src/main/kotlin", ]) executionData = files(fileTree(include: ['*.exec'], dir: "${project.buildDir}/jacoco").files) } }
рд╣рдордиреЗ getJacocoReports
рдХрд╛рд░реНрдп, "рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ" рд╕рдореВрд╣ рдмрдирд╛рдпрд╛ред Html рдФрд░ xml рд╕реНрд╡рд░реВрдкреЛрдВ рдореЗрдВ рд░рд┐рдкреЛрд░реНрдЯ рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рдПрдЧреАред рдЕрдкрд╡рд░реНрдЬрд┐рдд рд╕рд░рдгреА рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд▓реЛрдЧреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рднреА рдлрд╛рдЗрд▓реЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЙрддреНрдкрдиреНрди рдПрдВрдбреНрд░реЙрдЗрдб рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВрдиреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╕реЗ рд╕рднреА рдЯреБрдХрдбрд╝реЛрдВ рдФрд░ рдЧрддрд┐рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рд░реЗрдЯреНрд░реЛрдлрд┐рдЯ рдЗрдВрдЯрд░рдлреЗрд╕, рдбреАрдЖрдИ рдХреЗ рд╕рд╛рде рдкреИрдХреЗрдЬ, рдХрд╕реНрдЯрдо рд╡рд┐рдЪрд╛рд░ рдФрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛрдбред
рд╢рд╛рдпрдж рдпрд╣ рд╕реВрдЪреА рд╕рдордп рдХреЗ рд╕рд╛рде рдмрджрд▓ рдЬрд╛рдПрдЧреАред
classDirectories
- рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддред рд╣рдо рдпрд╣рд╛рдВ рдЬрд╛рд╡рд╛ рдФрд░ рдХреЛрдЯрд▓рд┐рди рджреЛрдиреЛрдВ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рддреЗ рд╣реИрдВред
sourceDirectories
- рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ рдЬрд╣рд╛рдВ рдЬреИрдХреЛрдХреЛ рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рджреЗрдЦреЗрдВред
executionData
- рдЬреИрд╕рд╛ рдХрд┐ рд╕реЛрдирд╛рд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрд╡рд░реЗрдЬ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд┐рдкреЛрд░реНрдЯ рдХрд╣рд╛рдБ рдЙрддреНрдкрдиреНрди рд╣реЛрдЧреА, рдЗрд╕рдХрд╛ рдПрдХ рд╕рдВрдХреЗрддред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ jacoco.gradle рдореЗрдВ рдЖрдкрдХреЛ рдЙрдкрд░реЛрдХреНрдд рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рднреА рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
allprojects { project -> configureJacoco(project) project.tasks.withType(Test) { enabled = true jacoco.includeNoLocationClasses = true } }
рдФрд░ рдЙрддреНрдкрдиреНрди рд░рд┐рдкреЛрд░реНрдЯ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдп:
task getJacocoReports() { group = "Reporting" subprojects.forEach { subproject -> subproject.tasks.withType(JacocoReport).forEach { task -> dependsOn task } } }
рд╕реЛрдирд╛рд░рдХреНрдмреА рдХреЛ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рд╛рдирд╛
рдпрд╣ рд╕рд░рд▓ рд░реВрдк рд╕реЗ ./gradlew % % && ./gradlew jacocoAggregateReports && ./gradlew sonarqube
рд╣реИ:ред ./gradlew % % && ./gradlew jacocoAggregateReports && ./gradlew sonarqube
ред рдХрдорд╛рдВрдб рдХреЛ &&
рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкрд┐рдЫрд▓реЗ рдЪрд░рдг рдХреЗ рд╕рдлрд▓ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрди рдмрд╛рдзрд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдКрдкрд░ рджрд┐рдП рдЧрдП рдЖрджреЗрд╢ рдкрд░ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ:
- рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдПрдВ (рдЙрд╕реА рд╕рдордп рд╣рдо рдмрд┐рд▓реНрдб рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдлрд╛рдЗрд▓реЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ)ред
- рдПрдХ рдЬреИрдХреЛрдХреЛ рд░рд┐рдкреЛрд░реНрдЯ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВред
- рд╕реЛрдирд╛рд░рдХреНрдмреА рд▓реЙрдиреНрдЪ рдХрд░реЗрдВред
рдЕрдЧрд▓рд╛ рдЖрдкрдХреЛ рд╕рд╛рдЗрдЯ рдкрд░ рдЬрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЕрд╕рдлрд▓ рдФрд░ рдЖрдкрджрд╛ рдХреЗ рдкреИрдорд╛рдиреЗ рдХреЛ рджреЗрдЦреЗрдВред рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкреГрд╖реНрда рдЕрдВрддрд┐рдо рдЬрд╛рдБрдЪ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджрд┐рдЦрд╛рддрд╛ рд╣реИред
рд╕реЛрдирд╛рд░рдХреНрдмреА рдХреЗ рд╕рд╛рде, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкреВрд░реНрдг рд╣реЛ рд░рд╣рд╛ рд╣реИред рддрдХрдиреАрдХреА рдЛрдг рдмреИрдХрд▓реЙрдЧ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдиреМрд╕рд┐рдЦрд┐рдП рдбреЗрд╡рд▓рдкрд░реНрд╕ рдкрд░ рд▓реЗрдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ (рдкреНрд░рддреНрдпреЗрдХ рд╡рдХреНрд░реЛрдХреНрддрд┐ рд╕реЛрдирд╛рд░рдХреНрдмреА рдореЗрдВ рдПрдХ рддрд░реНрдХ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХреНрдпреЛрдВ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдЗрди рд╕реНрдкрд╖реНрдЯреАрдХрд░рдгреЛрдВ рдХреЛ рдкрдврд╝рдирд╛ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ), рдФрд░ рдмрд╕ ( рдЬреНрдЮрд╛рди рд╢рдХреНрддрд┐ рд╣реИ) ред
рдпрд╣реА рд╕рдм рд╣реИ, рджреЛрд╕реНрддреЛрдВ!
рдкрд╛рдардХреЛрдВ рд╕реЗ рд╕рд╡рд╛рд▓ - рдЖрдк рдХреЛрдб рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд╡рд░реЗрдЬ рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ? рдХреНрдпрд╛ рдЖрдкрдХреЛ рдмрд┐рдВрджреБ рдмрд┐рд▓реНрдХреБрд▓ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ?