Skip to content

feat: add git pre-commit hooks for detekt and conventional commit #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions detekt.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
apply plugin: 'io.gitlab.arturbosch.detekt'

detekt {
buildUponDefaultConfig = true // preconfigure defaults
allRules = false // activate all available (even unstable) rules.
config = files("$rootDir/detekt-config.yml") // point to your custom config defining rules to run, overwriting default behavior
buildUponDefaultConfig = true // preconfigure defaults
allRules = false // activate all available (even unstable) rules.
config = files("$rootDir/detekt-config.yml")
// point to your custom config defining rules to run, overwriting default behavior
}

task createDetektPreCommitHook() {
def gitHooksDirectory = new File("$project.rootDir/.git/hooks/")
if (!gitHooksDirectory.exists()) gitHooksDirectory.mkdirs()
new File("$project.rootDir/.git/hooks", "pre-commit").text = """
#!/bin/bash
echo "Running detekt check"
./scripts/pre-commit.sh
"""
"chmod +x .git/hooks/pre-commit".execute()
}

task createConventionalMessagePreCommitHook() {
def gitHooksDirectory = new File("$project.rootDir/.git/hooks/")
if (!gitHooksDirectory.exists()) gitHooksDirectory.mkdirs()
new File("$project.rootDir/.git/hooks", "commit-msg").text = """
#!/bin/bash
echo "Running Conventional Commit check"
commit_message="\$1"
./scripts/conventional-pre-commit.sh "\$commit_message"
"""
"chmod +x .git/hooks/commit-msg".execute()
}
51 changes: 51 additions & 0 deletions scripts/conventional-pre-commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash

# list of Conventional Commits types
cc_types=("feat" "fix")
default_types=("build" "chore" "ci" "docs" "${cc_types[@]}" "perf" "refactor" "revert" "style" "test")
types=( "${cc_types[@]}" )

if [ $# -eq 1 ]; then
types=( "${default_types[@]}" )
else
# assume all args but the last are types
while [ $# -gt 1 ]; do
types+=( "$1" )
shift
done
fi

# the commit message file is the last remaining arg
msg_file="$1"

# join types with | to form regex ORs
r_types="($(IFS='|'; echo "${types[*]}"))"
# optional (scope)
r_scope="(\([[:alnum:] \/-]+\))?"
# optional breaking change indicator and colon delimiter
r_delim='!?:'
# subject line, body, footer
r_subject=" [[:alnum:]].+"
# the full regex pattern
pattern="^$r_types$r_scope$r_delim$r_subject$"

# Check if commit is conventional commit
if grep -Eq "$pattern" "$msg_file"; then
exit 0
fi

echo "[Commit message] $( cat "$msg_file" )"
echo "
Your commit message does not follow Conventional Commits formatting
https://www.conventionalcommits.org/
Conventional Commits start with one of the below types, followed by a colon,
followed by the commit message:
$(IFS=' '; echo "${types[*]}")
Example commit message adding a feature:
feat: implement new API
Example commit message fixing an issue:
fix: remove infinite loop
Optionally, include a scope in parentheses after the type for more context:
fix(account): remove infinite loop
"
exit 1
3 changes: 3 additions & 0 deletions scripts/pre-commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
echo "Running detekt check"
./gradlew detekt