Mono-repo root for all personal projects
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
3.2 KiB

# Command line variable building with check for a project flag specified
build = $(if $(project),/srv/$(project), $(error Provide project name))
# When this Makefile run was called
date = $(shell date +%s)
# Directory for public assets to be placed in for a given build
public = $(build)/public
# How to wait for file-system events
inotifywait = inotifywait -qr -e modify -e attrib -e move -e create -e delete
# Transparently calls other make targets without cluttering up the console
subTask = @make --no-print-directory
# We have a task name that matches the folder it operates on
.PHONY: images
# Clean build directory to prepare for new files
rm -rf $(public)/*
# Developing client and server -----------------------------------------------
# Start a development session with auto-updates
develop: clean
$(subTask) project=$(project) clientFlags="--config config.yaml,config.development.yaml server" -j client server
# Start a client development session
hugo --configDir $(project)/config --destination $(public) --noTimes $(clientFlags)
# Start a server development session
@if [ -f $(project)/server/main/main.go ]; then \
while true; do \
go build -o $(build)/private/server $(project)/server/main/main.go; \
cd $(build)/private && ./server & PID=$$!; \
$(inotifywait) $(project)/server $(project)/shared shared/server; \
kill $$PID; \
done \
# Run server with debug enabled, waiting for debug client to attach
dlv --listen localhost:2345 --headless --api-version=2 debug ./$(project)/server/main
# Releases --------------------------------------------------------------------
# Make sure an environment was supplied on the command line
$(if $(environment),, $(error Provide environment 'primary' or 'secondary'))
# Create a build for release
build: check-environment clean
# Build a client with the given environment
$(subTask) clientFlags="--environment $(environment)" client
# Build a server executable if one exists
if [ -f $(project)/server/main/main.go ]; then \
go build -o $(build)/server $(project)/server/main/main.go; \
# Minimize CSS output (except for UIKit Lightbox and SVG icon strokes)
for file in `find $(public) -type f -name "*.css"`; do \
npx purifycss $${file} $(public)/**/*.{html,js} --info --min --out $${file} --whitelist "*lightbox*" "*stroke*" ; \
# Compress images in parallel on all available cores
find $(public) -type f \( -name "*.png" -o -name "*jpg" \) | parallel ./ {}
# Add unique keys to build source
# Set semi-unique time-based key where desired
find $(public) -type f -exec grep -Iq . {} \; -exec sed -i "s/replaceAtBuildWithDate/$(date)/g" {} \;
# Set more-unique content-based key where desired
cd $(public) && for file in `find . -type f -printf "%P "`; do \
hash="`md5sum $${file} | head -c 16)`" ; \
grep -rlI $$file . | xargs -r sed -i -r "s|$$file\?key=replaceAtBuildWithHash|$$file\?key=$$hash|g" ; \
# Dry-run of transferring build to remote servers
$(subTask) flags="n" transfer
# Transfer builds to remote servers
transfer: check-environment
rsync -aivzO$(flags) --delete --exclude 'analytics.html' --chmod=D775,F664 --chown=:$(project) $(public)/ $(environment):$(build)/public/