Compare commits

..

2 Commits

Author SHA1 Message Date
arzzen
3cce04ddad Merge pull request #174 from tomice/master 2024-10-06 16:04:25 +02:00
Tom Ice
d4e56cf557 Adjust commitsByYear() to support multiple dates
* commitsByYear() previously could only support Default-style
  dates for git log. However, a user can use a variety of different
  date formats such as relative, default, iso, rfc, short, and raw.

  This change modifies commitsByYear() to handle multiple different
  date strings

Fixes #172
2024-10-01 20:43:39 -04:00

View File

@@ -17,7 +17,7 @@ _since=${_GIT_SINCE:-}
if [[ -n "${_since}" ]]; then
_since="--since=$_since"
else
_since="--since=$(git log --reverse --format='%ad' | head -n1)"
_since="--since=$(git log --reverse --format='%ad' --date=iso | head -n1)"
fi
# End of git log date. Respects all git datetime formats
@@ -761,6 +761,47 @@ function commitsPerDay() {
--date=short --format='%ad' $_log_options $_pathspec | sort | uniq -c
}
################################################################################
# DESC: Convert a timestamp to a date string to handle git's date formats
# ARGS: $1: Timestamp
# OUTS: Echoes a four-digit year
################################################################################
function parse_year() {
local date_str="$1"
local year
local timestamp
local default_git_date_regex
# Handle the raw UNIX timestamp format i.e. 1697375696 +0000
if [[ "$date_str" =~ ^[0-9]+(\ [+-][0-9]{4})?$ ]]; then
timestamp=$(echo "$date_str" | awk '{print $1}')
year=$(date -d "@$timestamp" '+%Y' 2>/dev/null)
else
# Default case can get funky. We need to create a clever regex to
# handle the default case which is like Mon Oct 15 12:34:56 2023 +0000
# Let's make this explicit for future devs to follow along.
default_git_date_regex='^' # Start from the beginning of the string
default_git_date_regex+='[A-Za-z]{3}\ ' # Day abbrev
default_git_date_regex+='[A-Za-z]{3}\ ' # Month abbrev
default_git_date_regex+='[0-9]{1,2}\ ' # Day of the month
default_git_date_regex+='[0-9]{2}:[0-9]{2}:[0-9]{2}\ ' # Time HH:MM:SS
default_git_date_regex+='[0-9]{4}\ ' # Year
default_git_date_regex+='[+-][0-9]{4}$' # Timezone offset
if [[ "$date_str" =~ $default_git_date_regex ]]; then
# Move the year before the time to match a format that Date can parse
date_str=$(echo "$date_str" | awk '{print $1, $2, $3, $5, $4, $6}')
elif [[ "$date_str" =~ ^[0-9]{1,2}/[0-9]{1,2}/[0-9]{2,4} ]]; then
# Handle DD/MM/YYYY format
date_str=$(echo "$date_str" | awk -F'/' '{print $2"/"$1"/"$3}')
fi
# Extract the final date
year=$(date -d "$date_str" '+%Y' 2>/dev/null)
fi
echo "$year"
}
################################################################################
# DESC: Displays a horizontal bar graph based on total commits per year
# ARGS: None
@@ -769,30 +810,38 @@ function commitsPerDay() {
function commitsByYear() {
optionPicked "Git commits by year:"
local year startYear endYear __since __until
startYear=$(echo "$_since" | sed -E 's/^.* ([0-9]{4})( .*)?$/\1/')
endYear=$(echo "$_until" | sed -E 's/^.* ([0-9]{4})( .*)?$/\1/')
# Extract the date strings from $_since and $_until
since_date="${_since#--since=}"
until_date="${_until#--until=}"
# Grab the four digit year from $_since and $_until
startYear=$(parse_year "$since_date")
endYear=$(parse_year "$until_date")
echo -e "\tyear\tsum"
for year in $(seq "$startYear" "$endYear")
do
if [ "$year" = "$startYear" ]
then
__since=$_since
__until="--until=$year-12-31"
elif [ "$year" = "$endYear" ]
then
__since="--since=$year-01-01"
__until=$_until
# Add time strings to make these a touch more robust
for year in $(seq "$startYear" "$endYear"); do
if [[ "$year" = "$startYear" ]]; then
__since=$_since
__until="--until=$year-12-31 23:59:59"
elif [[ "$year" = "$endYear" ]]; then
__since="--since=$year-01-01 00:00:00"
__until=$_until
else
__since="--since=$year-01-01"
__until="--until=$year-12-31"
__since="--since=$year-01-01 00:00:00"
__until="--until=$year-12-31 23:59:59"
fi
echo -en "\t$year\t"
git -c log.showSignature=false shortlog -n $_merges --format='%ad %s' \
"$__since" "$__until" $_log_options | grep -cE \
" \w\w\w [0-9]{1,2} [0-9][0-9]:[0-9][0-9]:[0-9][0-9] $year " \
|| continue
# Count commits directly using git rev-list instead of git log
commit_count=$(
git rev-list --count $_merges \
"$__since" "$__until" HEAD $_log_options
)
echo -e "\t$year\t$commit_count"
# TODO: The bar graph can get funky when there are only a handful of
# commits. We can set a max length to try to fix this, but this is a
# bit of a problem across all the bar graphs.
done | awk '{
count[$1] = $2
total += $2
@@ -986,8 +1035,8 @@ function suggestReviewers() {
checkUtils
# Check if we are currently in a git repo.
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo "Not inside a git repository."
if ! git rev-parse --is-inside-work-tree > /dev/null; then
echo "ERROR: You need to be inside a git repo to parse stats!"
usage
exit 1
fi