Skip to content

Instantly share code, notes, and snippets.

@iurysza
Last active April 28, 2024 12:58
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iurysza/005c08ff7f1892097c2823b1786ac087 to your computer and use it in GitHub Desktop.
Save iurysza/005c08ff7f1892097c2823b1786ac087 to your computer and use it in GitHub Desktop.
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.

@talhahasanzia
Copy link

@PhilippNowak96 thanks !

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