X-Git-Url: http://git.draconx.ca/gitweb/scripts.git/blobdiff_plain/5d3f16e91969123b8960e6806a9eade8a616f064..d52b809c91a8cf2bf2c95d49bee51180470667d1:/nanoc-post-receive diff --git a/nanoc-post-receive b/nanoc-post-receive new file mode 100755 index 0000000..8b3a31a --- /dev/null +++ b/nanoc-post-receive @@ -0,0 +1,111 @@ +#!/bin/sh +# +# Copyright © 2018 Nick Bowler +# +# Simple git post-receive hook to deploy a nanoc site +# +# License WTFPL2: Do What The Fuck You Want To Public License, version 2. +# This is free software: you are free to do what the fuck you want to. +# There is NO WARRANTY, to the extent permitted by law. + +GIT=/usr/bin/git +worktreedir=/var/cache/git-worktrees + +master_update= +while read old new ref x; do + case $ref in + refs/heads/master) master_update=$new ;; + esac +done + +worktree_remove() { + # welp, git doesn't appear to have a way to ONLY remove worktree tracking + # files, it removes the work tree itself which we don't want to do. So do + # this manually. + + for f in worktrees/*/gitdir; do + exec 3<"$f" || continue + read l <&3 || continue + + if test x"$l" = x"$1/.git"; then + rm -f "$f" + $GIT worktree prune -v + break + fi + done + + exec 3<&- +} + +cd_to_worktree_ () { + tmpfile=`mktemp` + exec 3>"$tmpfile" 4<"$tmpfile" + rm -f "$tmpfile" + + branch=${1##*/} + + repodir=`pwd` + reponame=${repodir##*/} + worktree=/no/where + + # Remove any stale worktrees... + $GIT worktree prune -v + + # First just try to add a new worktree + tmp_worktree=`mktemp -d "${worktreedir%/}/$reponame-$branch-XXXXXXXX"` + $GIT worktree add "$tmp_worktree" "$branch" 2>/dev/null || + rmdir "$tmp_worktree" + + $GIT worktree list --porcelain >&3 + exec 3<&- + + while read a b x <&4; do + case $a in + worktree) worktree=${b:-/no/where} ;; + branch) if test x"$b" = x"refs/heads/$branch"; then + if cd "$worktree"; then + test x"`pwd -P`" != x"$worktree" || { exec 4<&-; return 0; } + cd - + fi + + # Clean up + worktree_remove "$worktree" + fi ;; + esac + done + + # Failed? + exec 4<&- + return 1 +} + +# Usage: cd_to_worktree branch +# +# Change the current working directory to the worktree for the specified +# branch, creating it if necessary. +cd_to_worktree () { + # Try twice: stale entries might be removed by first pass and 2nd will work + if cd_to_worktree_ "$@" || cd_to_worktree_ "$@"; then + printf 'using worktree %s\n' "`pwd -P`" + unset GIT_DIR + fi +} + +deploy_branch () { + printf 'Deploying %s\n' "$1" + ( cd_to_worktree $1 + { flock -w 60 9 || exit + git reset --hard || exit + git clean -qfd -e gitlock || exit + nanoc || exit + nanoc deploy master || exit + } 9>gitlock + ) +} + +ret=true +if test ${master_update:+y}; then + deploy_branch master || ret=false +fi + +$ret