Skip to content

Instantly share code, notes, and snippets.

@iurysza
Last active November 3, 2023 13:53
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Gradle task that runs detekt only over changed files
configurations { detekt }
dependencies { detekt "io.gitlab.arturbosch.detekt:detekt-cli:$detektVersion" }
task detektCi(type: JavaExec, group: "verification") {
description = "Run Kotlin static analysis on changed files."
group = "CI"
main = "io.gitlab.arturbosch.detekt.cli.Main"
classpath = configurations.detekt
doFirst {
def changedFilesList = getDiffedFilesFromBranch("main")
if (changedFilesList.isEmpty()) {
println("No kotlin files changed! Skipping task...")
// forces detekt to ignore all files
changedFilesList = "$rootDir/gradle"
} else {
println("Running detekt on the changed files:")
println(changedFilesList)
}
def reportDir = "${buildDir}/reports/detekt"
def params = [
"--input", "$changedFilesList",
"--excludes", "!**/src/**/*Test.kt, **/spotless.kt",
"--config", "$rootDir/ci-cd/detekt-config.yml",
"--report", "xml:$reportDir/detekt-checkstyle.xml",
"--report", "html:$reportDir/report.html"
]
args(params)
}
}
private static String getDiffedFilesFromBranch(String branch) {
def outputStream = new ByteArrayOutputStream()
def cmd = "git diff --diff-filter=d --name-only origin/$branch --relative | grep '\\.kt\\?\$'"
execute(cmd, outputStream)
if (outputStream.toString().isEmpty()) return ""
// get comma separated string of files
return outputStream.toString()
.trim()
.replace("\n", ",")
}
private static def execute(cmd, output) {
['sh', '-c', cmd].execute().waitForProcessOutput(output, System.err)
}
@PhilippNowak96
Copy link

PhilippNowak96 commented Oct 20, 2022

Thank you for this nice little task! :) Just wanted to mention that some CIs only shallow clone and therefore git diff doesn't work. The result looks like:

fatal: ambiguous argument 'origin/main': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

What helped was to fetch the needed branch before:

private static String getDiffedFilesFromBranch(String branch) {
    def outputStream = new ByteArrayOutputStream()
    def fetchCommand = "git fetch origin $branch"
    def diffCommand = "git diff --diff-filter=d --name-only origin/$branch --relative | grep '\\.kt\\?\$'"

    execute(fetchCommand)
    println("Fetched base branch to calculate diff for Detekt")

    execute(diffCommand, outputStream)

    if (outputStream.toString().isEmpty()) return ""
    // get comma separated string of files
    return outputStream.toString()
            .trim()
            .replace("\n", ",")
}

Maybe you like to add it if others stumble upon this problem too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment