The Meat Grinder#

Git makes it possible for me to only have to worry about my MarkDown files. Or, someday I will only have to worry about MarkDown files. But it is not this day.

Hugo templates are fussy tools. They’re awesome when they work, but getting to that point is maddening. And Git might as well be black magic for how well I understand it. Once I push my MD files up to the remote repo, the git hook calls ‘stage.sh’ and IT’S SAUSAGIN TIME!. The following is my cobbled together shell script to eat MD and vomit up websites. I should probably use python or something, but I am too jacked up on Mountain Dew to take on another growth opportunity.

Script 1: stage.sh#

stage.sh is an abomination. It’s cobbled together from countless Bash scripting websites. I want to use this script for multiple sites, so that when I push the MD files to the staging server, git runs the staging script with hugo. I want to be able to use different templates for each site, so once I get the bugs worked out of this one, I get the bugs worked out for all my other sites.

  1. The first order on the agenda is to abort the script if I type the wrong thing. I just want the script to accept a domain name for the site I am publishing to, and to stop working if there are any typos. The script takes one and only one argument. One, no more, no less. One shall be the number of arguments thou passes, and the number of the counting shall be . Two shalt thou not pass. Three is right out. Once the single argument, being the first number, be reached, then lobbest thou thy stage.sh script at thy foe.

    
    #  Strict bash, kills the script if anything goes wrong
    set -euo pipefail
    
    # You are supposed to "stage.sh example1.com"
    # if you put anything other than 1 argument, exit
    if [[ $# -ne 1 ]]; then
    echo "Usage: $0 <repo-name>"
    exit 1
    fi
    
  2. Now that we are sure that an argument was passed on the commandline, let’s make sure that the argument matches one of our bare git repos, if not right to jail. Also, if you are messing around creating your git repos and you forgot you created a foo.git, this part will work. Be sure to prune the ~/git/ directory for extraneous repos.

  
  # the source exists? no? exit
  if [[ ! -d "${SRC}" ]]; then
    echo "Source repo not found: ${SRC}"
    exit 1
  fi
  1. Now we are sure there is no way to do this on a non-existent git repo, IT’S CLONIN TIME!! But first, make sure that the directory you want to clone to is gone. After cloning, delete the .git folder so it doesn’t get accidentally cloned to the web server folder. Yes I know you can set Caddy to ingnore .git directories. This is mostly so that the directory doesn’t get copied over and over.

	# delete the markdown folder, git clone hates existing files
	rm -rf "${MARKDOWN}"

	# clone repo to markdown directory
	git clone "${SRC}" "${MARKDOWN}"
	rm "${MARKDOWN}/ship"
	rm -rf "${MARKDOWN}/.git"
  1. Now that the MD files are in a clean directory, let’s get them into the Hugo build environment. Hugo has a bunch of stuff that I decided should not go into Git because either Git or Hugo ate something important one too many times. I could probably save space by using ‘mv’ instead of ‘rsync’, but I figured out the flags for rsync, so that’s how it’s gonna be for now.

	# sync markdown/example.com build/example.com/content
	rsync -rvh "${MARKDOWN}/" "${CONTENT}/"
  1. Hugo has its own deploy thing, which I will look at at some point, but right now I am still having feelings about the behavior of these goddamned Hugo templates. I don’t render the site into the ‘public’ folder of the Hugo build environment, because who knows what will happen. Instead I have Hugo build into an empty folder every time. The –baseURL flag renders the site so that the navigation is relatve. Meaning, all the site navigation is set up for http://192.168.1.X/example.com/ and not for https://example.com. That way you can test navigation on the testing web server.
	
	# Hugo processes ~/build/example.com and builds in /preview/example.com
	hugo --cleanDestinationDir -s "${BUILD}" --baseURL="/${REPO_NAME}/" --destination="${PREVIEW}"
  1. Speaking of Hugo template behavior, each template has its own ‘personality’. Sometimes overriding CSS with your own entries works, sometimes it doesn’t. Sometimes it doesn’t work on the staging server, but it does work on the production web server, even though both servers are Caddy. I dunno man. One of my templates makes an empty page subdirectory everywhere. I have fiddled with CSS, layouts/partials files, and so much more. But “rm -rf” never fails to zap nuisance directories.

	# sync preview/example.com to /var/www/example.com
	rsync -rvh --chown=caddy:caddy "${PREVIEW}/" "/var/www/${REPO_NAME}"
	rm -rf "/var/www/${REPO_NAME}/posts/page" # weird hugo pagination thing
	rm -rf "/var/www/${REPO_NAME}/page" # weird hugo pagination thing

I am reluctant to put this script any place public like GitHub because it’s an embarrassment in its current form. Also there’s a decent chance that once I get it working, I’ll just move on to something else. Remember: this deploys the rendered site to the staging server, and not the production VPS.