tj.git-extras/bin/git-effort
Dan Jackson d7d6ff2fed Use process-specific tmp file and clean up on exit
Fixes #279 using the suggestion from @hemanth, with some minor tweaks:

- I kept the leading . because I figured there was a reason it was put there originally.
- Changed the show_cursor method that's called when the process exits (prematurely or naturally) to be show_cursor_and_cleanup, and added a line to it that cleans up the tmp file.
2014-11-26 10:23:54 -08:00

144 lines
2 KiB
Bash
Executable file

#!/usr/bin/env bash
tmp="/tmp/.$(basename $0).$$"
above='0'
color=
#
# get date for the given <commit>
#
date() {
git log --pretty='format: %ai' $1 | cut -d ' ' -f 2
}
#
# 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 1
}
#
# get active days for the given <commit>
#
active_days() {
date $1 | uniq | awk '
{ sum += 1 }
END { print sum }
'
}
#
# 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 <file ...>
#
effort() {
for file in "$@"; do
commits=`git log --oneline "$file" | wc -l`
color='90'
# ignore <= --above
test $commits -le $above && continue
# commits
color_for $commits
len=${#file}
dot="."
f_dot="$file"
i=0 ; while test $i -lt $((45-$len)) ; do
f_dot=$f_dot$dot
i=$(($i+1))
done
printf " \033[${color}m%s %-10d" $f_dot $commits
# active days
active=`active_days "$file"`
color_for $active
printf "\033[${color}m %d\033[0m\n" $active
done
}
#
# print heading
#
heading() {
echo
printf " %-45s %-10s %s\n" 'file' 'commits' 'active days'
echo
}
#
# output sorted results
#
sort_effort() {
clear
echo
heading
cat $tmp | sort -rn -k 2
}
# --above <n-commits>
if test "$1" = "--above"; then
shift; above=$1
shift
fi
# [file ...]
declare -a files=()
if test $# -ge 1; then
files=("$@")
else
save_ifs=$IFS
IFS=`echo -en "\n\b"`
files=(`git ls-files`)
IFS=$safe_ifs
unset save_ifs
fi
# hide cursor
hide_cursor
trap show_cursor_and_cleanup INT
# loop files
heading
effort "${files[@]}" | tee $tmp && sort_effort
echo
show_cursor_and_cleanup