Skip to content

Instantly share code, notes, and snippets.

@keeferrourke
Last active December 7, 2018 01:44
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 keeferrourke/389d7ca8faf5994fb9c1e13e156a760b to your computer and use it in GitHub Desktop.
Save keeferrourke/389d7ca8faf5994fb9c1e13e156a760b to your computer and use it in GitHub Desktop.
Quick script that generates some pretty stats about a git repository on a quarter-by-quarter basis. Written for some basic analysis of our many repositories over at https://rightmesh.io
#!/usr/bin/env bash
# exit codes
EX_OK=0
EX_ERR=1
EX_USAGE=64
# default argument values
since_year=2015
until_year=$(date +%Y)
working_directory=$(pwd)
output_directory="$working_directory/git-stats"
node_env_version="7.10.1"
node_env_directory="/tmp/node7"
do_teardown=false
# usage() shows usage information
usage() {
echo "Usage $0 [-s YEAR] [-u YEAR] [-C path] [-h]" 1>&2
echo "Counts git repository statistics by quarter, outputting JSON data"
echo ""
echo "OPTIONS"
echo "-s the year to start counting stats by quarter (default: 1970)"
echo "-u the year to stop counting stats (default: current year)"
echo "-C specify the directory to change into (i.e. the repo)"
}
print_err() {
echo "ERR: $1" 1>&2
}
# setup_env() sets up a Node v7 environment in /tmp/node7 to run the
# stats-gathering tools
setup_env() {
which nodeenv 2>&1 1>/dev/null
if [ $? -ne $EX_OK ]; then
read -p "nodeenv is not installed, install it? [Y/n]" yn
case $yn in
n|N)
echo "run pip install nodeenv to continue"
return $EX_ERR
;;
*)
echo "pip install nodeenv..."
pip install nodeenv
if [ $? -ne $EX_OK ]; then
print_err "could not install nodeenv."
print_err "run pip install nodeenv to continue."
return $EX_ERR
fi
esac
fi
if [ ! -f "$node_env_directory/bin/activate" ]; then
echo "Setting up Node7 environment..."
nodeenv --node=$node_env_version "$node_env_directory" 1>/dev/null
if [ $? -ne $EX_OK ]; then
return $EX_ERR
fi
fi
return $EX_OK
}
# get_emails() gets the list of all contributor emails in the repository,
# delimited by commas
get_emails() {
if [ ! -d ".git" ]; then
print_err "working directory is not a git repository"
return $EX_ERR
fi
echo "$(git shortlog -sne | cut -d\< -f2 | sed 's/>//g' | tr '\n' ',')"
return $?
}
# get_commits() gets the list of all commits for the given date range in the
# repository
get_commits() {
echo "$(git log --all --abbrev-commit --pretty=oneline \
--since="$1" --until="$2")"
return $?
}
# main() is the main body of this script
main() {
# parse arguments
while getopts "s:u:C:hc" opt; do
case "$opt" in
s)
since_year=${OPTARG:-$since_year}
;;
u)
until_year=${OPTARG:-$until_year}
;;
C)
working_directory=${OPTARG:-$working_directory}
;;
c)
do_teardown=true
;;
h)
usage
exit $EX_OK
;;
*)
usage
exit $EX_USAGE
;;
esac
done
shift $((OPTIND - 1))
if [ $working_directory != $(pwd) ]; then
cd $working_directory
fi
# set up the environment, then source it
if [ ! -d "$output_directory" ]; then
mkdir -p "$output_directory"
fi
setup_env || exit $EX_ERR
source "$node_env_directory/bin/activate"
# check that git-stats, git-stats-importer are installed
which git-stats 2>&1 1>/dev/null
if [ $? -ne $EX_OK ]; then
print_err 'git-stats is not installed'
print_err 'run npm i -g git-stats to install it'
exit $EX_ERR
fi
which git-stats-importer 2>&1 1>/dev/null
if [ $? -ne $EX_OK ]; then
print_err 'git-stats-importer is not installed'
print_err 'run npm i -g git-stats-importer'
exit $EX_ERR
fi
# import git stats
emails=`get_emails`
if [ $? -ne $EX_OK ]; then
exit $EX_ERR
fi
git-stats-importer -e "$emails" 2>&1 1>/dev/null
# get stats by quarter
orig_since_year=$since_year
while [ $since_year -le $until_year ]; do
quarter=1
while [ $quarter -le 4 ]; do
out="$output_directory/$since_year-Q$quarter.html"
date1=""
date2=""
case $quarter in
1)
date1="$since_year Jan 1"
date2="$since_year Mar 31"
;;
2)
date1="$since_year Apr 1"
date2="$since_year June 30"
;;
3)
date1="$since_year Jul 1"
date2="$since_year Sept 30"
;;
4)
date1="$since_year Oct 1"
date2="$since_year Dec 31"
;;
esac
# produce the stats graphs
git-stats -g -s "$date1" -u "$date2" --raw \
| tee "${out%.html}.json" \
| git-stats-html -o "$out"
sed -i 's/in the last year/in this quarter/g' $out
# create a list of commits
get_commits "$date1" "$date2" > "${out%.html}_commits.txt"
quarter=$((quarter + 1))
done
since_year=$((since_year +1))
done
# create a histogram with gnuplot
# tear down the environment and exit
deactivate_node
if [ "$do_teardown" == "true" ]; then
rm -r "$node_env_directory"
fi
echo "Stats by quarter for years $orig_since_year-$until_year are available in "\
"$output_directory."
echo "You can view the HTML files in your browser."
}
main $@ || exit $EX_ERR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment