Last active
July 18, 2019 14:11
-
-
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
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 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, ")") |
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 | |
# 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