diff --git a/development.markdown b/development.markdown index ad06ed6ae5..078b4824ca 100644 --- a/development.markdown +++ b/development.markdown @@ -20,6 +20,14 @@ To get cracking with Unison: On startup, Unison prints a url for the codebase UI. If you did step 3 above, then visiting that URL in a browser will give you a nice interface to your codebase. +## Git hooks + +There are some Git hooks provided by Unison. If you want to use them, you can run + +``` bash +./scripts/install-hooks.bash +``` + ## Autoformatting your code with Ormolu We use Ormolu (see [the specific version](./nix/versions.nix)) and CI will add an extra commit, if needed, to autoformat your code. diff --git a/scripts/install-hooks.bash b/scripts/install-hooks.bash index f87c63cd7d..373c8b9d72 100755 --- a/scripts/install-hooks.bash +++ b/scripts/install-hooks.bash @@ -1,9 +1,39 @@ #!/usr/bin/env bash +set -euo pipefail +SCRIPTNAME="$(readlink -f -- "${BASH_SOURCE[0]}")" +SCRIPTDIR="$(dirname -- "$SCRIPTNAME")" -GIT_DIR=$(git rev-parse --git-dir) +function usage { + echo "Usage: $SCRIPTNAME [-f] [-h]" + echo + echo " -f Overwrite hooks if they already exist" + echo " -h Show this usage message" +} + +trap "echo; usage" ERR + +force=("-n") +while getopts ':fh' OPTION; do + case "$OPTION" in + f) + force=("-f") + ;; + h) + usage + exit 0 + ;; + \?) + usage + exit 1 + ;; + esac +done + +hooks_dir=$(git rev-parse --git-path hooks) echo "Installing hooks..." +mkdir -p "$hooks_dir" # this command creates symlink to our pre-commit script -ln -s ../../scripts/pre-commit.bash $GIT_DIR/hooks/pre-commit -ln -s ../../scripts/pre-push.bash $GIT_DIR/hooks/pre-push +cp "${force[@]}" "$SCRIPTDIR/pre-commit.bash" "$hooks_dir/pre-commit" +cp "${force[@]}" "$SCRIPTDIR/pre-push.bash" "$hooks_dir/pre-push" echo "Done!" diff --git a/scripts/pre-commit.bash b/scripts/pre-commit.bash index cc6b5851ff..0686d8e47d 100755 --- a/scripts/pre-commit.bash +++ b/scripts/pre-commit.bash @@ -1,10 +1,9 @@ #!/usr/bin/env bash +set -euo pipefail -echo "Running pre-commit hook from "`pwd` -./scripts/test.sh +echo "Running pre-commit hook from $(pwd)" -# $? stores exit value of the last command -if [ $? -ne 0 ]; then - echo "Tests must pass before commit!" - exit 1 +if ! ./scripts/test.sh; then + echo "Tests must pass before commit!" + exit 1 fi diff --git a/scripts/pre-push.bash b/scripts/pre-push.bash index 4ea16b3b20..c4b123edfa 100755 --- a/scripts/pre-push.bash +++ b/scripts/pre-push.bash @@ -1,18 +1,16 @@ #!/bin/bash -# Run the following command in the root of your project to install this pre-push hook: -# cp git-hooks/pre-push .git/hooks/pre-push; chmod 700 .git/hooks/pre-push +set -euo pipefail + +# Run `./install-hooks.bash` to install this pre-push hook. # Check if we actually have commits to push -commits=`git log @{u}..` +commits=$(git log "@{u}..") if [ -z "$commits" ]; then exit 0 fi CMD="./scripts/test.sh" -eval $CMD -RESULT=$? -if [ $RESULT -ne 0 ]; then - echo "The git push operation was canceled because \`$CMD\` did not complete successfully." +if ! "$CMD"; then + echo "The git push operation was canceled because ‘$CMD’ did not complete successfully." exit 1 fi -exit 0