Last active
December 7, 2018 01:44
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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