Skip to content

Instantly share code, notes, and snippets.

@boweeb
Last active July 18, 2019 14:11
Show Gist options
  • Save boweeb/25b3d64319677fac92c8d7fe61ac2049 to your computer and use it in GitHub Desktop.
Save boweeb/25b3d64319677fac92c8d7fe61ac2049 to your computer and use it in GitHub Desktop.
[git-logger.sh] proposed improvements [src](https://gitlab.com/CrazyBaboon/git-logger) #git #bash
#!/usr/bin/env python3
from colour import Color
from x256 import x256
def scale_256(rgb, direction):
factor = 256
new = list()
for value in rgb:
if value == 0:
new.append(value)
elif direction == "up":
new.append(value * factor)
elif direction == "down":
new.append(value / factor)
return tuple(new)
# hot = Color(rgb=(0.9, 0, 0))
hot = Color(rgb=scale_256(x256.to_rgb(196), "down"))
cold = Color(rgb=scale_256(x256.to_rgb(17), "down"))
desired_count = 17
colors = list()
for step in cold.range_to(hot, desired_count):
rgb = step.get_rgb()
rgb256 = scale_256(rgb, "up")
xterm_color = x256.from_rgb(*rgb256)
colors.append(xterm_color)
print("COLORS=(", *colors, ")")
#!/usr/bin/env bash
# git-logger is free software and is licensed under the GNU GPLv2+.
# (C) 2018-2019 Nuno Ferreira
#
# This script works by generating two temporary files in the /tmp folder,
# containing the results of grepping days of the week and the git log pretty format.
# Apparently it is faster to grep a text file than piping greps in a chain.
#
# See the following variables for convenient user config:
# - CELL_SIZE=4
# - COLOR_ONLY=false
# - FG_DARK=0
# - FG_LIGHT=14
#
# TODO:
# - "color-only" doesn't hide "0" cells
# - provide CLI args
#
# References:
# - Upstream Source
# - https://gitlab.com/CrazyBaboon/git-logger
# - Misc/Scratch
# - https://gist.github.com/MicahElliott/719710
# - Follow up on alternative method of generating a gradient
# - https://github.com/chadj2/bash-ui/blob/master/COLORS.md#xterm-colorspaces
# - https://github.com/chadj2/bash-ui/blob/master/test/grad-demo.sh
trap clean_up EXIT
# ============================================================================
# ENVIRONMENT
if [[ "${OSTYPE}" == darwin* ]]; then
# brew install coreutils grep
_date="gdate"
_grep="ggrep"
_wc="gwc"
elif [[ "${OSTYPE}" == linux* ]]; then
_date="date"
_grep="grep"
_wc="wc"
fi
# Programmatically generate HOURS array (because it's cooler that way ;) )
# HOURS=( 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 )
mapfile -t HOURS < <(seq -f "%02g" 1 23); HOURS+=( "00" )
HOURS_COUNT="${#HOURS[@]}"
TMP_ALL=$(mktemp)
TMP_DAY=$(mktemp)
# Construct i18n short day names
days_=( "monday" "tuesday" "wednesday" "thursday" "friday" "saturday" "sunday" )
declare -a days
for day in "${days_[@]}"; do
days+=( "$($_date -d "${day}" +%a)" )
done
# ----------------------------------------------------------------------------
# TABLE
COL_TOTAL_PAD=14
CELL_SIZE=4 # includes left border
HEAD_CELL_SIZE=$(( CELL_SIZE - 1 ))
TABLE_INSIDE_WIDTH=$(( HOURS_COUNT * CELL_SIZE ))
BORDER_SIZE=$(( TABLE_INSIDE_WIDTH + 1 )) # not + 2 because the cells include left border already
COLS=$(( TABLE_INSIDE_WIDTH + COL_TOTAL_PAD ))
# ----------------------------------------------------------------------------
# COLORS
COLOR_SPACE=$(tput colors)
# COLORS=( 17 21 23 25 27 30 36 39 41 49 51 154 178 172 166 202 196 ) # Original
COLORS=( 17 17 23 24 30 29 29 34 34 34 70 112 184 178 172 202 196 ) # Generated: 17 <--> 196
COLOR_ONLY=false
# COLOR_ONLY=true
FG_DARK=0
FG_LIGHT=14
RESET="$(tput sgr0)"
# ----------------------------------------------------------------------------
# COUNTERS
MAX_HOURLY_COMMIT=0
TOTAL_COMMITS=0
# ============================================================================
# FUNCTIONS
function display_center () {
printf "%*s\n" $(( (${#1} + COLS) / 2)) "$1"
}
# This function saves the hourly commits in memory and finds the max hourly commit value used for plotting
function find_max () {
local hourly_commits
for day in "${days[@]}"; do
$_grep "${day}" "${TMP_ALL}" > "${TMP_DAY}"
for hour in "${HOURS[@]}"; do
hourly_commits=$(get_hourly_commits "${hour}")
if [[ "${hourly_commits}" -gt "${MAX_HOURLY_COMMIT}" ]]; then
MAX_HOURLY_COMMIT="${hourly_commits}"
fi
done
done
}
function get_hourly_commits () {
local hour="${1}"
$_grep "${hour}" "${TMP_DAY}" | $_wc -l | tr -d "[:space:]"
}
function heat () {
local commit_count=${1}
local pre
local post
# Humanize large numbers
if [[ ${commit_count} -lt 10000 && ${commit_count} -gt 999 ]]; then
commit_count="$((commit_count/1000))k"
elif [[ ${commit_count} -gt 9999 ]]; then
commit_count="$((commit_count/1000))k"
fi
# Background color
if [[ "${COLOR_SPACE}" -eq 256 ]];then
color_idx=$(( ( "${#COLORS[@]}" - 1 ) * "${commit_count}" / ( "${MAX_HOURLY_COMMIT}" ) ))
bg_num="${COLORS["${color_idx}"]}"
else
if [[ ${commit_count} -eq 0 ]]; then
bg_num=0 # none
elif [[ ${commit_count} -lt 10 ]]; then
bg_num=2 # green
elif [[ ${commit_count} -lt 100 ]]; then
bg_num=3 # yellow
else
bg_num=1 # red
fi
fi
bg="$(tput setab "${bg_num}")"
# Foreground color
fg_dark="$(tput setaf ${FG_DARK})"
fg_light="$(tput setaf ${FG_LIGHT})"
pre+="${RESET}"
if [[ ! ${commit_count} -eq 0 ]]; then
pre+="${bg}"
if [[ $COLOR_ONLY == "true" ]]; then
pre+="$(tput setaf "${bg_num}")"
elif [[ ${bg_num} -lt 28 ]]; then
pre+="${fg_light}"
else
pre+="${fg_dark}"
fi
fi
post+="${RESET}"
# Paint cell
printf "%s%${CELL_SIZE}s%s" "${pre}" "${commit_count}" "${post}"
}
function print_banner () {
display_center "****** Punch card for $(basename "$PWD") ******"
echo
display_center "time of day (hours)"
printf ' %.s' {1..6}; printf '%.s-' $(seq 1 "${BORDER_SIZE}")
echo
# Header row (hours)
echo -n " " # (padding)
for hour in "${HOURS[@]}"; do
# echo -n "| ${hour}"
printf "|%${HEAD_CELL_SIZE}s" "${hour}"
done
echo "| Total"
}
function print_punchcard () {
for day in "${days[@]}"; do
# Populate "day" file
$_grep "${day}" "${TMP_ALL}" > "${TMP_DAY}"
# Row Header
printf " %s _" "${day}"
# Data
total_daily_commits=0
for hour in "${HOURS[@]}"; do
hourly_commits=$(get_hourly_commits "${hour}")
heat "${hourly_commits}"
(( TOTAL_COMMITS += hourly_commits ))
(( total_daily_commits += hourly_commits ))
done
# Row Tally
printf "| %s\n" "${total_daily_commits}"
done
}
function clean_up () {
rm "${TMP_ALL}"
rm "${TMP_DAY}"
}
function main () {
# "%a %H" == "$DAY $HOUR"
git log --pretty=format:"%ad" --date=local --date=format:'%a %H' > "${TMP_ALL}"
print_banner
find_max
print_punchcard
# Tallies
printf "\n\n"
printf "MAX_HOURLY_COMMIT = %s\n" "${MAX_HOURLY_COMMIT}"
printf "TOTAL_COMMITS = %s\n" "${TOTAL_COMMITS}"
}
# ============================================================================
# ENTRYPOINT
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment