From 1a6893dbb6a05b80e685ba9e48fc95379ce52647 Mon Sep 17 00:00:00 2001
From: Brian Bland <brian.bland@docker.com>
Date: Mon, 15 Dec 2014 15:45:02 -0800
Subject: [PATCH] Adds pre-commit hook, hook config script, and a README

The pre-commit hook will automatically gofmt code in place, warning you
about any changes. It will also fail to commit if either golint or go
vet fails.
---
 project/hooks/README.md          |  6 ++++++
 project/hooks/configure-hooks.sh | 18 ++++++++++++++++++
 project/hooks/pre-commit         | 29 +++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)
 create mode 100644 project/hooks/README.md
 create mode 100755 project/hooks/configure-hooks.sh
 create mode 100755 project/hooks/pre-commit

diff --git a/project/hooks/README.md b/project/hooks/README.md
new file mode 100644
index 000000000..eda886966
--- /dev/null
+++ b/project/hooks/README.md
@@ -0,0 +1,6 @@
+Git Hooks
+=========
+
+To enforce valid and properly-formatted code, there is CI in place which runs `gofmt`, `golint`, and `go vet` against code in the repository.
+
+As an aid to prevent committing invalid code in the first place, a git pre-commit hook has been added to the repository, found in [pre-commit](./pre-commit). As it is impossible to automatically add linked hooks to a git repository, this hook should be linked into your `.git/hooks/pre-commit`, which can be done by running the `configure-hooks.sh` script in this directory. This script is the preferred method of configuring hooks, as it will be updated as more are added.
\ No newline at end of file
diff --git a/project/hooks/configure-hooks.sh b/project/hooks/configure-hooks.sh
new file mode 100755
index 000000000..6afea8a13
--- /dev/null
+++ b/project/hooks/configure-hooks.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+cd $(dirname $0)
+
+REPO_ROOT=$(git rev-parse --show-toplevel)
+RESOLVE_REPO_ROOT_STATUS=$?
+if [ "$RESOLVE_REPO_ROOT_STATUS" -ne "0" ]; then
+	echo -e "Unable to resolve repository root. Error:\n$REPO_ROOT" > /dev/stderr
+	exit $RESOLVE_REPO_ROOT_STATUS
+fi
+
+set -e
+set -x
+
+# Just in case the directory doesn't exist
+mkdir -p $REPO_ROOT/.git/hooks
+
+ln -f -s $(pwd)/pre-commit $REPO_ROOT/.git/hooks/pre-commit
\ No newline at end of file
diff --git a/project/hooks/pre-commit b/project/hooks/pre-commit
new file mode 100755
index 000000000..3ee2e913f
--- /dev/null
+++ b/project/hooks/pre-commit
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+REPO_ROOT=$(git rev-parse --show-toplevel)
+RESOLVE_REPO_ROOT_STATUS=$?
+if [ "$RESOLVE_REPO_ROOT_STATUS" -ne "0" ]; then
+	printf "Unable to resolve repository root. Error:\n%s\n" "$RESOLVE_REPO_ROOT_STATUS" > /dev/stderr
+	exit $RESOLVE_REPO_ROOT_STATUS
+fi
+
+cd $REPO_ROOT
+
+GOFMT_ERRORS=$(gofmt -s -l . 2>&1)
+if [ -n "$GOFMT_ERRORS" ]; then
+	printf 'gofmt failed for the following files:\n%s\n\nPlease run "gofmt -s -l ." in the root of your repository before committing\n' "$GOFMT_ERRORS" > /dev/stderr
+	exit 1
+fi
+
+GOLINT_ERRORS=$(golint ./... 2>&1)
+if [ -n "$GOLINT_ERRORS" ]; then
+	printf "golint failed with the following errors:\n%s\n" "$GOLINT_ERRORS" > /dev/stderr
+	exit 1
+fi
+
+GOVET_ERRORS=$(go vet ./... 2>&1)
+GOVET_STATUS=$?
+if [ "$GOVET_STATUS" -ne "0" ]; then
+	printf "govet failed with the following errors:\n%s\n" "$GOVET_ERRORS" > /dev/stderr
+	exit $GOVET_STATUS
+fi