Skip to content

Instantly share code, notes, and snippets.

@ggirelli
Last active February 7, 2023 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ggirelli/e6035ae14d55279613e6ce54a446c523 to your computer and use it in GitHub Desktop.
Save ggirelli/e6035ae14d55279613e6ce54a446c523 to your computer and use it in GitHub Desktop.
Provides some states on the conventional commits found in your git repo's log from a certain date.
#! /bin/env bash
sinceDate="2023-02-01"
untilDate=$(date +%Y-%m-%d)
headerPattern='(\w+)(\(\w+\))?!?\: (.*)'
prefixPattern='[a-z0-9]+ [0-9-]+ '
typeGroupPattern='(feat|fix|revert|ci|docs|refactor|style|perf|test|chore)'
if [ ${#@} -gt 0 ]; then sinceDate=$1; fi
if [ ${#@} -gt 1 ]; then untilDate=$2; fi
echo -e "\nConventional commits stats for period $sinceDate:$untilDate"
# Retrieve commits
commits=$(git log --pretty=format:"%h %as %s" --since="$sinceDate" --until="$untilDate")
if [ -z "$commits" ]; then exit 1; fi
# Count bad commits
bad_commits=$(echo "$commits" | grep -vP "^$prefixPattern$typeGroupPattern" | grep -vP "^$prefixPattern$headerPattern\$")
n_bad_commits=$(echo "$bad_commits" | wc -l)
echo -e "\nFound $n_bad_commits commit(s) not complying to conventional commits specs. The most recent are:"
echo "$bad_commits" | sed "s/^/- /" | head -n 5
# Remove prefix
clean_commits=$(echo "$commits" | sed -r 's/^'"$prefixPattern"'//')
# Select compatible commits
ccommits=$(echo "$clean_commits" | grep -P "^$typeGroupPattern" | grep -P "^$headerPattern\$")
if [ -z "$ccommits" ]; then exit 1; fi
n_ccommits=$(echo "$ccommits" | wc -l)
echo -e "\nFound $n_ccommits conventional commit(s)."
# Count breaking changes
breaking=$(echo "$commits" | grep "!:")
if [ -z "$breaking" ]; then echo -e "\nFound 0 breaking changes."; fi
if [ -n "$breaking" ]; then
n_breaking=$(echo "$breaking" | wc -l)
echo -e "\nFound $n_breaking breaking change(s). The most recent are:"
echo "$breaking" | sed "s/^/- /" | head -n 5
fi
# Type counts
echo -e "\n## Type stats:\n"
echo "$ccommits" | sed -r 's/^'"$headerPattern"'$/\1/' | tr -d "()" | sort | uniq -c
# Scope counts
echo -e "\n## Scope stats:\n"
echo "$ccommits" | sed -r 's/^'"$headerPattern"'$/\2/' | tr -d "()" | sed -r 's/^$/*NONE*/' | sort | uniq -c
echo -e ""
@ggirelli
Copy link
Author

ggirelli commented Feb 7, 2023

Usage:

curl -s https://gist.githubusercontent.com/ggirelli/e6035ae14d55279613e6ce54a446c523/raw/abf3895c4194067d588be7262aa5b67fe533aa94/conventional-commits-stats-check.sh > ccstats.sh
chmod +x ccstats

# get stats from hard-coded start date to current date
./ccstats.sh
# get stats from custom start date to current date
./ccstats.sh <from-date-in-YY-MM-DDDD-format>
# get stats from custom start date to custom date
./ccstats.sh <from-date-in-YY-MM-DDDD-format> <to-date-in-YY-MM-DDDD-format>

Alternatively, add an alias to the downloaded file or set a function with curl, like:

function ccstats () {
    bash <(curl -s https://gist.githubusercontent.com/ggirelli/e6035ae14d55279613e6ce54a446c523/raw/abf3895c4194067d588be7262aa5b67fe533aa94/conventional-commits-stats-check.sh) ${@}
}

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