Bash Updater

If you’re like me, you probably see the value in keeping your code in GIT repositories. If you’re like me and you also have websites running you probably pull your staged code right from git. It might not be an enterprise-grade solution, but it’s easy, we know where things are, and it’s a fairly natural workflow.

There is an issue though created by my desire for absolute laziness; it can be annoying to cd all the way into a folder, run the pull requests, and possibly do it again if I’ve exited from my ssh session but I had one more push to pull.

Of course, the natural solution is to alias a command that does everything. But it doesn’t feel particularly flexible, and I don’t like having an archive of commands which may or may not be functional. Another solution is to have something like GitHub run webhooks and such to trigger updates as you make them. While this sounds pretty hand and super simple, for me personally, I like to know exactly when my code will go live.

My solution is the below script in tandem with a dead-simple config file, which lets me get the granularity I like without the need for endless aliased commands.

#!/bin/bash

# Updates various git repositories registered in ~/git-update-locations.ini.
# Format is as follows:
# [MyProject]
# firstRepo=/path/to/first/repo
# secondRepo=/path/to/second/repo
# allRepos=/path/to/repos/*
#
# git-update.sh MyProject firstRepo
# git-update.sh MyProject allRepos
#
# If the value of a path ends with "*" it will look at all directories in that
# location, if they have a git repo, it will run the pull.
#
# For example:
# 
# [mywordpresssite.com]
# theme=/var/www/mywordpresssite.com/public_html/wp-content/themes/my-git-theme
# plugins=/var/www/mywordpresssite.com/public_html/wp-content/plugins/*
#
# git-update.sh mywordpresssite.com theme
# -> will update the theme from git.
#
# git-update.sh mywordpresssite.com plugins
# -> will update all plugins found connected to git.

if [ ! -f "$HOME/git-update-locations.ini" ]; then
	"$HOME/git-update-locations.ini not found"
	exit
fi

if [[ -z $1 ]] ; then
	echo "You must specify a registered site"
	exit
fi

if [[ -z $2 ]] ; then
	echo "You must specify a section to update"
	exit
fi

SECTION=${1//[_- ]/.}
TARGET=${2//[._ -]/"-"}
CONFIG="$HOME/git-update-locations.ini"
FOLDER=$(sed -nr "/^\[$SECTION\]/ { :l /^$TARGET[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" "$CONFIG")

if [ "$FOLDER" = "" ]; then
	echo "Target $SECTION $TARGET not found."
	exit
fi

if [[ "$FOLDER" =~ '*'$ ]] ; then 
	echo "Scanning for git repositories"
	for REPO in "${FOLDER::-1}"*; do
		[ -d "$REPO" ] || continue
		cd "$REPO"
		status="$(git rev-parse --is-inside-work-tree 2>/dev/null)"
		[ "$status" = "true" ] || continue
		echo "Updating $REPO"
		git status -s
		git pull --verbose
	done
else
	echo "Updating $FOLDER"
	cd "$FOLDER"
	git status -s
	git pull --verbose
fi

Of course, I’ve aliased this script to git-update.

alias git-update="/path/to/git-updater/git-update.sh"

Below is a portion of my own ini file, with the values used for updating this site and even the updater itself;

[kver.ca]
plugins=/var/www/kver.ca/public_html/wp-content/plugins/*
themes=/var/www/kver.ca/public_html/wp-content/themes/*
kv-design=/var/www/kver.ca/public_html/wp-content/themes/kv-design/

[utils]
updater=/opt/git-updater/

These days when updating my personal websites I just push to git, ssh into the server and have fairly quick access running my updates like so;

# Update my theme
git-update kver.ca theme

#Update all plugins connected to git
git-update kver.ca plugins

#Update the updater
git-update utils updater