diff --git a/detekt.gradle b/detekt.gradle index a9a42e51..d1cd0f06 100644 --- a/detekt.gradle +++ b/detekt.gradle @@ -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() } diff --git a/scripts/conventional-pre-commit.sh b/scripts/conventional-pre-commit.sh new file mode 100755 index 00000000..f2d39bd1 --- /dev/null +++ b/scripts/conventional-pre-commit.sh @@ -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 \ No newline at end of file diff --git a/scripts/pre-commit.sh b/scripts/pre-commit.sh new file mode 100755 index 00000000..5f57afec --- /dev/null +++ b/scripts/pre-commit.sh @@ -0,0 +1,3 @@ +#!/bin/bash +echo "Running detekt check" +./gradlew detekt