Skip to content

Instantly share code, notes, and snippets.

@JCGoran
Created March 28, 2022 11:03
Show Gist options
  • Save JCGoran/3ce6fbc5edb3874dac4fa5ff8171f580 to your computer and use it in GitHub Desktop.
Save JCGoran/3ce6fbc5edb3874dac4fa5ff8171f580 to your computer and use it in GitHub Desktop.
LaTeX project post-commit hook that verifies that a project can be built before pushing it to a remote
#!/usr/bin/env sh
# simple script for checking that a LaTeX project builds after a commit
# USAGE: save this as `.git/hooks/post-commit` in your project, and make it executable using `chmod +x .git/hooks/post-commit`.
# The script will then run after each `git commit` to the repository.
# NOTE: to turn off the check, run `git commit --no-verify` instead.
# REQUIREMENTS: git, latexmk, notify-send (optional)
# notify-send settings
# the time it takes (in seconds) for the notification to disappear
NOTIFY_SEND_TIMEOUT="${NOTIFY_SEND_TIMEOUT:-360000}"
# latexmk settings
# the path to the main file (relative to the root of the git repository)
MAIN_FILE="${MAIN_FILE:-main.tex}"
# the compiler used: set it to your liking, either here, or as an environmental
# variable
# possible values: -pdf, -pdfxe, -pdflua
LATEX_COMPILER="${LATEX_COMPILER:--pdf}"
git_latex_builder(){
# make sure git is installed somewhere
git_location="$(command -v git)"
if [ -z "${git_location}" ]
then
printf "%s" 'ERROR: git is not installed, ' \
'please install it before running this script, ' \
'and make sure the location of the git binary is in your $PATH\n' 1>&2
return 1
fi
# where this directory is
# NOTE if this is ran outside of the git dir, it will fail;
# need to use `git -C "$(basename $0)"` for that, but for a hook
# it will always work
this_dir="$(${git_location} rev-parse --show-toplevel)"
notify_send_location="$(command -v notify-send)"
# keep track of the time (so the log is unique)
current_time="$(date +%s)"
# make temporary directory
build_dir="$(mktemp -d)"
# some safeguards for interrupts
trap 'rm -fr -- "${build_dir}"' INT TERM HUP EXIT
# make another dir for logs
log_dir="$(mktemp -d)"
trap 'rm -fr -- "${log_dir}"' INT TERM HUP EXIT
# clone the current files (on current commit) in the dir
"${git_location}" clone -vv \
"${this_dir}" \
"${build_dir}" > "${log_dir}/build_${current_time}.log" 2>&1
# we build the project
cd "${build_dir}" || ( printf "ERROR: cannot cd to %s\n" "${build_dir}" && return 255 )
if ! latexmk "${LATEX_COMPILER}" -f "${MAIN_FILE}" > "${log_dir}/build_${current_time}.log" 2>&1
then
printf "There were errors building the project, please see the following file for details:\n/tmp/build_%s.log\n" "${current_time}" 1>&2
cp "${log_dir}/build_${current_time}.log" "/tmp/"
if [ -n "${notify_send_location}" ]
then
"${notify_send_location}" \
"Build failed!" \
"<span foreground=\"red\">The project ${this_dir} failed to build</span>\nLook at /tmp/build_${current_time}.log for more details" \
-t ${NOTIFY_SEND_TIMEOUT}
fi
return 2
fi
# we're done
printf "Build completed successfully\n"
# sending the notification
if [ -n "${notify_send_location}" ]
then
"${notify_send_location}" \
"Build successful!" \
"<span foreground=\"#7FFF00\">The project ${this_dir} was built successfully!</span>" \
-t ${NOTIFY_SEND_TIMEOUT}
fi
return 0
}
git_latex_builder_local(){
# where we are currently
this_dir="$(git rev-parse --show-toplevel)"
# we build the project
latexmk "${LATEX_COMPILER}" -f "${MAIN_FILE}" > /dev/null 2>&1
return 0
}
git_latex_builder && git_latex_builder_local
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment