Skip to content

Instantly share code, notes, and snippets.

@someguynamedmatt
Last active January 25, 2018 01:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save someguynamedmatt/2d71e2d1fc74feaf62fe5e6bd9c01d7b to your computer and use it in GitHub Desktop.
Save someguynamedmatt/2d71e2d1fc74feaf62fe5e6bd9c01d7b to your computer and use it in GitHub Desktop.
#!/bin/bash -
#===============================================================================
# FILE: repos.sh
#
# USAGE: Update all the git repos in your ~/code directory. This will
# skip over "dirty" (code changed and uncommited) repos and
# give a warning and, after completion, list those repos.
#
# The script will ask if you want to npm install or npm build
# in the frontend repos, default is "n" (no).
#
# NOTES: Standard git, npm, and nvm output is suppressed! This includes
# errors! If you don't like it, remove the `> /dev/null 2>&1`
#
# If your checked-out branch isn't master _and_ it's clean
# (commited work), the script will switch the branch to master,
# pull it, and switch back to your working branch.
#
# REQUIREMENTS: Run from your ~/code directory
# BUGS: Report to matthew.young@dollarshaveclub.com
# AUTHOR: Matt Young
# ORGANIZATION: Dollar Shave Club
# CREATED: 08/01/2017
# REVISION: 5
#===============================================================================
set -o nounset # Treat unset variables as an error
RED='\033[0;31m'
GREEN='\033[0;32m'
NORMAL='\033[0m'
YELLOW='\033[0;33m'
DIRECTORY_BEING_REFRESHED=""
RET_VALUE=""
DIRTY_REPOS=()
NPM_INSTALL="n"
NPM_BUILD="n"
printf '\n'
echo "************************************************************"
echo -e "${RED}Checking the repositories in your ~/code directory.${NORMAL}"
echo "************************************************************"
printf '\n'
printf "${YELLOW}Would you like this script to install frontend dependencies?: (y/n) ${NORMAL}"
read -n1 NPM_INSTALL
printf '\n'
printf "${YELLOW}Would you like this script to build the frontend repos?: (y/n) ${NORMAL}"
read -n1 NPM_BUILD
printf '\n'
printf '\n'
echo -e "Git checkouts, git pulls, npm installs, and npm builds may take some time. Get coffee!"
printf '\n'
change_to_dir () {
directory=(${1//\// })
DIRECTORY_BEING_REFRESHED=${directory[${#directory[@]}-1]}
cd "$1" || exit
update_repo "$1"
}
update_repo () {
CHECKED_OUT_REPO=$(git symbolic-ref --short -q HEAD)
if [ -n "$(git status --porcelain)" ]; then
DIRTY_REPOS+=("$1")
return
else
if [[ $CHECKED_OUT_REPO != "master" ]]; then
git checkout master > /dev/null 2>&1
git pull origin master > /dev/null 2>&1
if [[ $NPM_INSTALL == "y" ]]; then
nvm use > /dev/null 2>&1
npm i > /dev/null 2>&1
fi
if [[ $NPM_BUILD == "y" ]]; then
npm run build > /dev/null 2>&1
fi
git checkout "$CHECKED_OUT_REPO" > /dev/null 2>&1
else
git pull origin master > /dev/null 2>&1
if [[ $NPM_INSTALL == "y" ]]; then
nvm use > /dev/null 2>&1
npm i > /dev/null 2>&1
fi
if [[ $NPM_BUILD == "y" ]]; then
npm run build > /dev/null 2>&1
fi
fi
fi
cd ~/code || exit
}
BAR_WIDTH=50
BAR_CHAR_START="["
BAR_CHAR_END="]"
BAR_CHAR_EMPTY="."
BAR_CHAR_FULL="="
BRACKET_CHARS=2
LIMIT=100
print_progress_bar() {
# Calculate how many characters will be full.
let "full_limit = ((($1 - $BRACKET_CHARS) * $2) / $LIMIT)"
# Calculate how many characters will be empty.
let "empty_limit = (($1 - $BRACKET_CHARS) - ${full_limit})"
# Prepare the bar.
bar_line="${BAR_CHAR_START}"
for ((j=0; j<full_limit; j++)); do
bar_line="${bar_line}${BAR_CHAR_FULL}"
done
for ((j=0; j<empty_limit; j++)); do
bar_line="${bar_line}${BAR_CHAR_EMPTY}"
done
bar_line="${bar_line}${BAR_CHAR_END}"
RET_VALUE=$(printf " %3d%% %s" $2 ${bar_line})
}
if [[ $PWD == *"code" ]]
then
echo " PROGRESS:"
printf '\n'
DIR_COUNT=$(expr $(find ~/code -maxdepth 1 | wc -l) - 2) # Subtract 2 because it counts the parent director (~/code) twice
DIR_NUM=1
PERCENT_DONE=$(echo $(printf %.0f $(expr "scale=1;1 / ${DIR_COUNT} * 100" | bc -l)) | bc)
for DIR in $(find ~/code -maxdepth 1);
do if test -d "$DIR"; then
if [[ $DIR != *"/code" ]] && [[ $DIR != *"/node_modules" ]]; then
change_to_dir "${DIR}"
DIR_NUM=$(expr $DIR_NUM + 1)
PERCENT_DONE=$(echo $(printf %.0f $(expr "scale=1;${DIR_NUM} / ${DIR_COUNT} * 100" | bc -l)) | bc)
print_progress_bar ${BAR_WIDTH} ${PERCENT_DONE}
tput cuu1
tput el
echo -ne "${RET_VALUE}\n Pulling repo: ${GREEN}${DIRECTORY_BEING_REFRESHED}${NORMAL} \033[0K\r"
fi
fi
done
printf '\n\n'
echo -e "${GREEN}DONE!${NORMAL}"
printf '\n'
if [[ ${#DIRTY_REPOS[@]} -gt 1 ]]; then
echo -e "There were ${RED}${#DIRTY_REPOS[@]}${NORMAL} dirty repos:"
for item in "${DIRTY_REPOS[@]}"
do
echo "$item"
done
fi
if [[ ${#DIRTY_REPOS[@]} == 1 ]]; then
echo -e "There was ${RED}${#DIRTY_REPOS[@]}${NORMAL} dirty repo:"
echo "${DIRTY_REPOS[@]}"
fi
if [[ ${#DIRTY_REPOS[@]} -lt 1 ]]; then
echo "There were ${RED}no${NORMAL} dirty repos. Get back to work."
fi
printf '\n'
exit 0
else
echo -e "${RED}Please run this script from your ~/code directory"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment