mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 07:26:17 -04:00
Why: * The old way of handling arguments could make it difficult to make non-breaking changes because to be able to handle more arguments than the '--above' argument, the logic would need to be heavily refactored and demand restrictions on argument order. This change addresses the need by: * Parse arguments in a cleaner way * Make the command more future proof with respect to arguments Notable change is the synopsis. Please the see man page.
196 lines
3.4 KiB
Bash
Executable file
196 lines
3.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
tmp=$(git_extra_mktemp)
|
|
above=0
|
|
color=
|
|
|
|
#
|
|
# get dates for the given <commit>
|
|
#
|
|
dates() {
|
|
eval "git log --pretty='format: %ad' --date=short $args_to_git_log \"$1\""
|
|
}
|
|
|
|
#
|
|
# hide cursor
|
|
#
|
|
|
|
hide_cursor() {
|
|
printf '\033[?25l'
|
|
}
|
|
|
|
#
|
|
# show cursor, and remove temporary file
|
|
#
|
|
|
|
show_cursor_and_cleanup() {
|
|
printf '\033[?25h'
|
|
printf '\033[m\n'
|
|
rm "$tmp" > /dev/null 2>&1
|
|
exit 0
|
|
}
|
|
|
|
#
|
|
# get active days for the given <commit>
|
|
#
|
|
|
|
active_days() {
|
|
echo "$1" | uniq | wc -l
|
|
}
|
|
|
|
#
|
|
# set 'color' based on the given <num>
|
|
#
|
|
|
|
color_for() {
|
|
test $1 -gt 10 && color='33'
|
|
test $1 -gt 25 && color='33;1'
|
|
test $1 -gt 50 && color='93'
|
|
test $1 -gt 75 && color='93;1'
|
|
test $1 -gt 100 && color='31'
|
|
test $1 -gt 125 && color='31;1'
|
|
test $1 -gt 150 && color='91'
|
|
test $1 -gt 200 && color='91;1'
|
|
}
|
|
|
|
#
|
|
# compute the effort of the given <path ...>
|
|
#
|
|
|
|
effort() {
|
|
path=$1
|
|
local commit_dates
|
|
commit_dates=`dates "$path"`
|
|
[ $? -gt 0 ] && exit 255
|
|
|
|
# Ensure it's not just an empty line
|
|
if [ -z "`head -c 1 <<<$(echo $commit_dates)`" ]
|
|
then
|
|
exit 0
|
|
fi
|
|
|
|
commits=`wc -l <<<"$(echo "$commit_dates")"`
|
|
color='90'
|
|
|
|
# ignore <= --above
|
|
test $commits -le $above && exit 0
|
|
|
|
# commits
|
|
color_for $(( $commits - $above ))
|
|
len=${#path}
|
|
dot="."
|
|
f_dot="$path"
|
|
i=0 ; while test $i -lt $((45-$len)) ; do
|
|
f_dot=$f_dot$dot
|
|
i=$(($i+1))
|
|
done
|
|
|
|
msg=$(printf " \033[${color}m%s %-10d" "$f_dot" $commits)
|
|
|
|
# active days
|
|
active=`active_days "$commit_dates"`
|
|
color_for $(( $active - $above ))
|
|
msg="$msg $(printf "\033[${color}m %d\033[0m\n" $active)"
|
|
echo "$msg"
|
|
}
|
|
|
|
#
|
|
# print heading
|
|
#
|
|
|
|
heading() {
|
|
echo
|
|
printf " %-45s %-10s %s\n" 'path' 'commits' 'active days'
|
|
echo
|
|
}
|
|
|
|
#
|
|
# output sorted results
|
|
#
|
|
|
|
sort_effort() {
|
|
clear
|
|
echo
|
|
heading
|
|
< $tmp sort -rn -k 2
|
|
}
|
|
|
|
declare -a paths=()
|
|
while [ "${#}" -ge 1 ] ; do
|
|
|
|
case "$1" in
|
|
--above)
|
|
shift
|
|
above=$1
|
|
;;
|
|
--)
|
|
shift
|
|
args_to_git_log=$(printf " %q" "${@:1}")
|
|
break
|
|
;;
|
|
--*)
|
|
echo 1>&2 "error: unknown argument $1"
|
|
echo 1>&2 "error: if that argument was meant for git-log,"
|
|
echo 1>&2 "error: please put it after two dashes ( -- )."
|
|
exit 1
|
|
;;
|
|
*)
|
|
paths+=( "$1" )
|
|
;;
|
|
esac
|
|
|
|
shift
|
|
done
|
|
|
|
# Exit if above-value is not an int
|
|
if [ -z "${above##*[!0-9]*}" ] ; then
|
|
echo "error: argument to --above was not an integer" 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
# remove empty quotes that appear when there are no arguments
|
|
args_to_git_log="${args_to_git_log#\ \'\'}"
|
|
export args_to_git_log
|
|
|
|
# [path ...]
|
|
|
|
if test "${#paths}" -eq 0; then
|
|
save_ifs=$IFS
|
|
IFS=`echo -en "\n\b"`
|
|
paths=(`git ls-files`)
|
|
IFS=$save_ifs
|
|
unset save_ifs
|
|
fi
|
|
|
|
# hide cursor
|
|
|
|
hide_cursor
|
|
trap show_cursor_and_cleanup INT
|
|
|
|
# export functions so subshells can call them
|
|
export -f effort
|
|
export -f color_for
|
|
export -f active_days
|
|
export -f dates
|
|
export above
|
|
export log_args
|
|
|
|
|
|
bash_params=
|
|
# If bash exits sucessfully with --import-functions,
|
|
# then we need to pass it (FreeBSD probably)
|
|
bash --import-functions -c ":" 1>/dev/null 2>&1
|
|
if [ $? -eq 0 ] ; then
|
|
bash_params="--import-functions"
|
|
fi
|
|
|
|
heading
|
|
# send paths to effort
|
|
printf "%s\0" "${paths[@]}" | xargs -0 -n 1 -P 4 -I % bash $bash_params -c "effort \"%\"" | tee $tmp
|
|
|
|
# if more than one path, sort and print
|
|
test "$(wc -l $tmp | awk '{print $1}')" -gt 1 && sort_effort
|
|
echo
|
|
|
|
show_cursor_and_cleanup
|