Trying out Task
For this site, I’ve been using a Makefile
that automates much of the process
of building, indexing and ultimately uploading the static files to AWS
CloudFront for distribution to you, my dear reader.
Make
has been around for ages. Current incarnations use either BSD or GNU
variants, but for my purposes, GNU is where it’s at. I use in the following
form:
SHELL := bash
.SHELLFLAGS := -eu -o pipefail -c
.ONESHELL:
CLOUDFRONT_DIST_ID = ""
AWS_ACCESS_KEY_ID ?= ""
AWS_SECRET_ACCESS_KEY ?= ""
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
REQUIRED_PROGRAMS = pagefind hugo aws
all: check_dependencies build index upload clean
build: hugo.toml
@echo "Building site"
@hugo build --cleanDestinationDir --quiet
serve: hugo.toml
@echo "Serving local build"
@hugo serve --buildDrafts --disableFastRender
index: public/search/
@echo "Building search index"
@pagefind --root-selector="main" --logfile search-log.log --silent --site public --output-subdir search/pagefind
upload: public/
@echo "Uploading files"
@AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) aws s3 sync public/ s3://degruchy.org --storage-class REDUCED_REDUNDANCY --quiet --delete --exclude "*.csv" --exclude "*.caption" --exclude "*.DS_Store" --exclude ".DS_Store"
@echo "Invalidating caches"
@AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) aws cloudfront create-invalidation --distribution-id $(CLOUDFRONT_DIST_ID) --paths "/*" >/dev/null
clean: search-log.log public/ resources/
@echo "Cleaning up build artefacts"
@rm search-log.log
@rm -r public/
@rm -r resources/
check_dependencies:
@echo "Checking for required programs"
$(foreach prog,$(REQUIRED_PROGRAMS),\
$(if $(shell which $(prog)),,\
$(error "Required program: $(prog) not in PATH")))
.PHONY: check_dependencies
# Local Variables:
# truncate-lines: t
# End:
The problem is that when you start doing stuff that loops, or that makes use of shell incantations you start getting into the weeds. Also, if you close one of your eyes and squint the other, it kind of looks like a YAML file (Note: I have a healthy distaste for YAML files). Which means you can probably just actually make it a YAML file and be done with it.
So, I decided to try out task
as a build runner instead. After a few minutes of fiddling (and no AI help, just the docs) I had the following Taskfile.yaml
working and uploading just fine. Neat!
version: '3'
silent: true
tasks:
default:
cmds:
- task: check_dependencies
- task: build
- task: index
- task: upload
build:
cmds:
- echo "Building site"
- hugo build --cleanDestinationDir --quiet
serve:
cmds:
- echo "Serving local build"
- task: check_dependencies
- task: index
- hugo serve --buildDrafts --disableFastRender
- defer: { task: clean }
index:
cmds:
- echo "Building search index"
- pagefind --root-selector="main" --logfile search-log.log --silent --site public --output-subdir search/pagefind
upload:
env:
AWS_ACCESS_KEY_ID: ""
AWS_SECRET_ACCESS_KEY: ""
CLOUDFRONT_DIST_ID: ""
preconditions:
- test -d public
cmds:
- echo "Uploading files"
- aws s3 sync public/ s3://degruchy.org --storage-class REDUCED_REDUNDANCY --quiet --delete --exclude "*.csv" --exclude "*.caption" --exclude "*.DS_Store" --exclude ".DS_Store"
- defer: { task: clean }
- echo "Invalidating caches"
- aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DIST_ID --paths "/*" >/dev/null
clean:
preconditions:
- test -d public
- test -d resources
- test -f search-log.log
cmds:
- echo "Cleaning up build artefacts"
- rm search-log.log
- rm -r public
- rm -r resources
check_dependencies:
cmds:
- for: ['pagefind', 'hugo', 'aws']
cmd: test -x $(which {{ .ITEM }})
This ends up being slightly easier to read and maintain. Each bit has it’s own section and commands, preconditions and even environments are handled in a purpose-driven way that makes it more clear what that section is for. It’s still YAML, though, so yuck.
However, I think I’ll give this a spin for a while and see how I like it. make
has the ~49 year advantage over task
, but not all new software is bad, it
just has to prove itself. make
has, but it’s grown warts over that time, and
unless you’re doing dead simple stuff, it may be more confusing to write than
YAML. In fact, I had Claude write the loop for me, and some of the other parts
because the syntax is… terse.