Ktlint: Git Hooked On It

A linting workflow leveraging on git hooks and Ktlint

Preface

The Problem

The Solution

Write code -> Commit in git -> Custom script runs Ktlint -> Code gets formatted/error gets thrown -> IF no error, code gets committed

The Fun Part (Implementation)

Setup

repositories {
...
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
...
classpath("org.jlleitschuh.gradle:ktlint-gradle:9.3.0")
}
allProjects {
...
apply plugin: "org.jlleitschuh.gradle.ktlint"
}

Custom Gradle Task (Script Injection)

repositories {
...
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
...
classpath("org.jlleitschuh.gradle:ktlint-gradle:9.3.0")
}
allProjects {
...
apply plugin: "org.jlleitschuh.gradle.ktlint"
}
task installGitHook(type: Copy) {
def lintingConfigScript = new File(rootProject.rootDir, '.git/hooks/pre-commit')
if (!lintingConfigScript.exists()) {
from new File(rootProject.rootDir, '.githooks/pre-commit')
into { new File(rootProject.rootDir, '.git/hooks') }
fileMode 0777
}
}

tasks.getByPath('app:preBuild').dependsOn installGitHook
#!/bin/bash

# Stash the current index to be used in the event of failure
git stash -q --keep-index

echo "Running Ktlint before git commit is committed"

./gradlew ktlintFormat

RESULT=$?

git stash pop -q

# return 1 exit code if running checks fails
[ $RESULT -ne 0 ] && exit 1

######## KTLINT-GRADLE HOOK START ########

CHANGED_FILES="$(git --no-pager diff --name-status --no-color --cached | awk '$1 != "D" && $2 ~ /\.kts|\.kt/ { print $2}')"

if [ -z "$CHANGED_FILES" ]; then
echo "No Kotlin staged files."
exit 0
fi;

echo "Running ktlint over these files:"
echo "$CHANGED_FILES"

./gradlew --quiet ktlintFormat -PinternalKtlintGitFilter="$CHANGED_FILES"

echo "Completed ktlint run."
echo "$CHANGED_FILES" | while read -r file; do
if [
-f $file ]; then
git add $file
fi
done
echo "Completed ktlint hook."
######## KTLINT-GRADLE HOOK END ########

Wrap Up

References

https://twitter.com/jasonlowdh Full-time Android developer. I write about anything Android/software development, tech, and life’s musings.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store