From 2de421d3f9eff3b3130702d91c3019af07dd0f2a Mon Sep 17 00:00:00 2001 From: adamopolous Date: Thu, 7 Nov 2019 13:17:06 -0500 Subject: [PATCH] added gradle dependencies for jacoco tasks --- Ghidra/Features/ByteViewer/build.gradle | 2 +- Ghidra/Features/MicrosoftDmang/build.gradle | 2 +- Ghidra/Processors/HCS12/build.gradle | 1 - gradle/jacocoProject.gradle | 42 +-- gradle/root/jacoco.gradle | 277 ++++---------------- 5 files changed, 70 insertions(+), 254 deletions(-) diff --git a/Ghidra/Features/ByteViewer/build.gradle b/Ghidra/Features/ByteViewer/build.gradle index 1572d8f7bc..7a790643e9 100644 --- a/Ghidra/Features/ByteViewer/build.gradle +++ b/Ghidra/Features/ByteViewer/build.gradle @@ -11,4 +11,4 @@ dependencies { compile project(':Base') helpPath project(path: ':Base', configuration: 'helpPath') // this module's help has links to Base help files -} +} \ No newline at end of file diff --git a/Ghidra/Features/MicrosoftDmang/build.gradle b/Ghidra/Features/MicrosoftDmang/build.gradle index 2274d04c30..87a2a0dd15 100644 --- a/Ghidra/Features/MicrosoftDmang/build.gradle +++ b/Ghidra/Features/MicrosoftDmang/build.gradle @@ -1,6 +1,6 @@ apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle" apply from: "$rootProject.projectDir/gradle/javaProject.gradle" -apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle" +//apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle" apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle" apply plugin: 'eclipse' diff --git a/Ghidra/Processors/HCS12/build.gradle b/Ghidra/Processors/HCS12/build.gradle index 05c969dca1..b94a40a68d 100644 --- a/Ghidra/Processors/HCS12/build.gradle +++ b/Ghidra/Processors/HCS12/build.gradle @@ -1,6 +1,5 @@ apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle" apply from: "$rootProject.projectDir/gradle/javaProject.gradle" -apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle" apply from: "$rootProject.projectDir/gradle/processorProject.gradle" apply plugin: 'eclipse' diff --git a/gradle/jacocoProject.gradle b/gradle/jacocoProject.gradle index 930022113a..27f4760a08 100644 --- a/gradle/jacocoProject.gradle +++ b/gradle/jacocoProject.gradle @@ -1,29 +1,35 @@ /***************************************************************************************** - This file is a "mix-in" gradle script that individual gradle projects that should be included - when running jacoco + This file is a "mix-in" gradle script that individual gradle projects that should be included + when running jacoco - A gradle project can add itself to the jacoco run by adding the following to its build.gradle - file: + A gradle project can add itself to the jacoco run by adding the following to its build.gradle + file: - apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle" + apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle" + + IMPORTANT!!!!! If you include this script in your project, you must have source + sets for both test and test.slow in your project, or jacoco will + fail. *****************************************************************************************/ // Apply jacoco plugin to subprojects. This will create coverage files for each java Test task. -if (rootProject.ext.jacocoEnabled) { - apply plugin:'jacoco' -} +apply plugin:'jacoco' +dependencies { + jacocoAnt 'org.jacoco:org.jacoco.ant:0.8.2' + jacocoAgent 'org.jacoco:org.jacoco.agent:0.8.2' +} + // Clean any jacoco files that may have been left behind previously. clean { - doFirst{ - logger.debug("Deleting subproject jacoco execution data directory: $buildDir/jacoco/") - file("$buildDir/jacoco/").deleteDir() // delete jacoco executionData files in individual subprojects + doFirst{ + logger.debug("Deleting subproject jacoco execution data directory: $buildDir/jacoco/") + file("$buildDir/jacoco/").deleteDir() // delete jacoco executionData files in individual subprojects - logger.debug("Deleting root project jacoco execution data directory: $rootProject.buildDir/jacoco/") - file("$rootProject.buildDir/jacoco/").deleteDir() // delete jacocoMerge task output - - logger.debug("Deleting jacoco report directory: $rootProject.buildDir/reports/jacoco/") - file("$rootProject.buildDir/reports/jacoco/").deleteDir() // delete jacocoReport, jacocoBranchReport output - } -} + logger.debug("Deleting root project jacoco execution data directory: $rootProject.buildDir/jacoco/") + file("$rootProject.buildDir/jacoco/").deleteDir() // delete jacocoMerge task output + logger.debug("Deleting jacoco report directory: $rootProject.buildDir/reports/jacoco/") + file("$rootProject.buildDir/reports/jacoco/").deleteDir() // delete jacocoReport, jacocoBranchReport output + } +} \ No newline at end of file diff --git a/gradle/root/jacoco.gradle b/gradle/root/jacoco.gradle index 9ee464546d..d789c30d79 100644 --- a/gradle/root/jacoco.gradle +++ b/gradle/root/jacoco.gradle @@ -1,245 +1,56 @@ -// Used for jacocoBranchReport task. Cmd line param to specify branch origin. Defaults to master. -def jacoco_origin = project.hasProperty('jacoco.origin') ? project.getProperty('jacoco.origin') : "master" - import groovy.io.FileType; -// 'jacocoEnabled' will enable jacocoMerge, jacocoBranchReport and jacocoReport if these tasks are -// specified on the cmd line. -// Applying jacoco plugin will create coverage files for each java Test task. This extra analysis -// slows down the overall Test task, so only enable jacoco when specified on the cmd line. -rootProject.ext.jacocoEnabled = (rootProject.gradle.startParameter.taskNames.contains('jacocoMerge') || - rootProject.gradle.startParameter.taskNames.contains('jacocoBranchReport') || - rootProject.gradle.startParameter.taskNames.contains('jacocoReport')) -if (project.jacocoEnabled) { +apply plugin:'jacoco' - // jacoco plugin needs to be in the root-level to get the jacocoAnt and jacocoAgent dependencies below - // and any subproject (via jacocoProject.gradle) - apply plugin:'jacoco' +dependencies { + jacocoAnt 'org.jacoco:org.jacoco.ant:0.8.2' + jacocoAgent 'org.jacoco:org.jacoco.agent:0.8.2' +} - // set classpath dependency for root-level tasks defined in this file. - dependencies { - jacocoAnt 'org.jacoco:org.jacoco.ant:0.8.2' - jacocoAgent 'org.jacoco:org.jacoco.agent:0.8.2' - } +def String jacocoRootExecPath = "$buildDir/jacoco/jacocoMerge.exec" - def String jacocoRootExecPath = "$buildDir/jacoco/jacocoMerge.exec" - def numFoundExecutionFiles = 0 // number of jacoco data files found in subprojects - - delete new File(jacocoRootExecPath) // If the merged exec file (output from jacocoMerge) exists, - // jacocoReport & jacocoBranchReport tasks are skipped and - // the report is not generated. - // So always delete the merged file before the determination - // to skip a task is made. - -List excludesList = generateExcludesList() +delete new File(jacocoRootExecPath) // If the merged exec file (output from jacocoMerge) exists, + // jacocoReport & jacocoBranchReport tasks are skipped and + // the report is not generated. + // So always delete the merged file before the determination + // to skip a task is made. /********************************************************************************* - * Task to merge multiple jacoco execution data files into one. + * Task to merge multiple jacoco execution data files into one *********************************************************************************/ - task jacocoMerge(type: JacocoMerge) { - description = 'Task to merge multiple jacoco execution data files into one.' - destinationFile = new File(jacocoRootExecPath) - - // Make this collection of execution data files empty during the configuration phase. - // There may be new exec files generated during the execution phase - // (ex: gradle test jacocoReport). So gather up these files in the execution phase - // via doFirst below. - executionData = project.files([]) - - // Before Task runs, update executionData by searching for files in each subproject. - doFirst { - logger.debug("jacocoMerge: Searching in " + subprojects.size() + " subproject(s)") - subprojects.each { p -> - logger.debug("jacocoMerge: Searching $p.name subproject in directory: $p.buildDir/jacoco/") - File jacocoExecDir = new File("$p.buildDir/jacoco/") - - if (jacocoExecDir.exists()) { - jacocoExecDir.eachFileRecurse (FileType.FILES) { file -> - numFoundExecutionFiles++ - logger.debug("jacocoMerge: Adding $p.name: $file") - executionData file - } - } - } - println "jacocoMerge: Added $numFoundExecutionFiles execution data files to $destinationFile" - } - } - -/********************************************************************************* - * Task to create a jacoco report based on changes from current branch and origin. - * Default origin is 'master'. Specify -Pjacoco.origin=value to change the value of origin. - *********************************************************************************/ - task jacocoBranchReport(type: JacocoReport, group: 'Coverage reports') { - description = 'Generates a Jacoco report based on changes from current branch and origin.' - dependsOn ":jacocoMerge" - - executionData new File(jacocoRootExecPath) - - // Get current branch name - String[] cmd = ["/bin/bash", "-c", "git rev-parse --abbrev-ref HEAD"] - ProcessBuilder builder = new ProcessBuilder(); - builder.command(cmd); - Process process = builder.start(); - def branchName = process.in.text - process.waitFor(); - branchName = branchName.trim() - logger.debug("jacocoBranchReport: Current branchName is $branchName") - - // Find commit in origin before branching. See: https://stackoverflow.com/q/1527234 - cmd = ["/bin/bash", "-c", "diff -u <(git rev-list --first-parent $branchName) <(git rev-list --first-parent $jacoco_origin) | sed -ne 's/^ //p' | head -1"] - builder = new ProcessBuilder(); - builder.command(cmd); - process = builder.start(); - def lastRevision = process.in.text - process.waitFor(); - lastRevision = lastRevision.trim() - logger.debug("jacocoBranchReport: last revision before branching from $jacoco_origin is $lastRevision") - - // Find the files that were changed in the branch. - builder = new ProcessBuilder(); - cmd = ["/bin/bash", "-c", "git diff --name-only $lastRevision"] - builder.command(cmd); - process = builder.start(); - def filesChanged = process.in.text - process.waitFor(); - logger.debug("jacocoBranchReport: files changed are:" + filesChanged) - - List filesToInclude = new ArrayList() - filesChanged.split().each{ fileName -> - // Filter out files not in src/main/java and create an inclusion pattern. - if(fileName.endsWith(".java") && fileName.contains("/src/main/java/")) { - String fqName = fileName.split("/src/main/java/")[1] - fqName = fqName.replace(".java", ".class") - filesToInclude.add(fqName) - } - } - - // Turn on html reports, 'doFirst' may disable this later on. - reports { - html.enabled = true - xml.enabled = false - } - - doFirst { - - // Only report on subprojects with Java sourceSets - // This configuration in doFirst to let all subprojects configuration to evaluate. - def subprojectsWithJava = [] - subprojects { p -> - p.plugins.withType(JavaPlugin) { - subprojectsWithJava += p - } - } - - sourceDirectories = files(subprojectsWithJava.sourceSets.main.allSource.srcDirs) - classDirectories = files(subprojectsWithJava.sourceSets.main.output) - - logger.debug("jacocoBranchReport: Files to include: " + filesToInclude) - - // Only include these src/main/java files in the report - if (filesToInclude.size() > 0) { - classDirectories = files(classDirectories.files.collect { - fileTree(dir: it, - include: filesToInclude.toArray(new String[filesToInclude.size()])) - }) - } - - println "jacocoBranchReport: Found $filesToInclude.size Java files to filter on branch '$branchName' and revision $lastRevision from origin '$jacoco_origin'" - println "jacocoBranchReport: Number of jacoco execution data files found from jacocoMerge: $numFoundExecutionFiles" - // Turn off reports if no files to report or no jacoco data files found. Otherwise the jacoco task will create empty report. - if (filesToInclude.size() == 0 || numFoundExecutionFiles == 0) { - reports { - html.enabled = false - xml.enabled = false - } - println "jacocoBranchReport: Empty filter or no jacoco execution data found. Not writing report." - } else { - println "jacocoBranchReport: Writing report to file://$reports.html.destination/index.html" - } - } - } - -/********************************************************************************* - * Task to generate an aggregate jacoco report from subprojects with Java sourceSets. - *********************************************************************************/ - task jacocoReport(type: JacocoReport, group: 'Coverage reports') { - description = 'Generates an aggregate Jacoco report from all subprojects' - dependsOn ":jacocoMerge" - executionData new File(jacocoRootExecPath) - - reports { - html.enabled = true - xml.enabled = false - html.destination = new File(project.ext.reportDir + "/jacocoReport") - } - - doFirst { - - // Only report on subprojects with Java sourceSets - // This configuration in doFirst to let all subprojects configuration to evaluate. - def subprojectsWithJava = [] - subprojects { p -> - p.plugins.withType(JavaPlugin) { - subprojectsWithJava += p - } - } - - sourceDirectories = files(subprojectsWithJava.sourceSets.main.allSource.srcDirs) - classDirectories = files(subprojectsWithJava.sourceSets.main.output) - classDirectories = files(classDirectories.files.collect { - fileTree(dir: it, exclude: excludesList) - }) - - - if (numFoundExecutionFiles == 0) { - println "jacocoReport: No execution data files found." - println "jacocoReport: No report written to $reports.html.destination.absolutePath." - reports { - html.enabled = false - xml.enabled = false - } - } else { - println "jacocoReport: Writing report to $reports.html.destination.absolutePath" - } - } - } +task jacocoMerge(type: JacocoMerge) { + description = 'Task to merge multiple jacoco execution data files into one.' + destinationFile = new File(jacocoRootExecPath) + dependsOn { subprojects.findAll { p -> p.plugins.hasPlugin('jacoco') }.test } + dependsOn { subprojects.findAll { p -> p.plugins.hasPlugin('jacoco') }.integrationTest } + executionData fileTree(rootDir) { + include '**/*.exec' + } } /********************************************************************************* - * Generate the Jacoco excludes list from file (this will strip out comments and - * whitespace). - * - * This uses 'gradle/support/jacoco.excludes.src.txt' to generate list of - * class exclusions for the 'jacocoReport' task. - * + * Task to generate an aggregate jacoco report from subprojects with + * Java sourceSets *********************************************************************************/ -def String[] generateExcludesList() { - - File inputFile = new File(rootProject.projectDir, "gradle/support/jacoco.excludes.src.txt") - - def lines = inputFile.readLines() - .findAll({ line -> - !shouldIgnoreLine(line) - }) - .collect() - - println "Returning ${lines.size()} exclusion line(s) for jacocoReport." - return lines -} - -/* An ignorable line is one that is only whitespace or that starts with a comment marker */ -def shouldIgnoreLine(line) { - if (line.startsWith('#')){ - return true - } - - if (line.startsWith("//")) { - return true - } - - if (line.trim().isEmpty()) { - return true - } - - return false -} +task jacocoReport(type: JacocoReport, group: 'Coverage reports') { + description = 'Generates an aggregate Jacoco report from all subprojects' + dependsOn 'jacocoMerge' + executionData new File(jacocoRootExecPath) + + // Setting these source/class dirs MUST be done in the configuration phase (we used + // to do it in a doFirst block but that was deprecated in later gradle builds). However, + // we have to delay evaluation of the subprojects (using the '{ }' notation) to wait for + // some project attributes (eg: 'sourceSets') to be made available. + additionalSourceDirs files({ subprojects.findAll { p -> p.plugins.hasPlugin('jacoco') }.sourceSets.main.java.srcDirs }) + additionalClassDirs files({ subprojects.findAll { p -> p.plugins.hasPlugin('jacoco') }.sourceSets.main.output }) + + reports { + html { + enabled true + destination new File(rootDir.absolutePath + "/jacocoReport") + } + xml { + enabled false + } + } +} \ No newline at end of file