#!/bin/bash # This scipt lints go files for common errors. # # Its runs gofmt and go vet, and optionally golint and # gocyclo, if they are installed. # # With no arguments, it lints the current files staged # for git commit. Or you can pass it explicit filenames # (or directories) and it will lint them. # # To use this script automatically, run: # ln -s ../../bin/lint .git/hooks/pre-commit set -eu function lint_go { filename="$1" result=0 if [ -n "$(gofmt -s -l "${filename}")" ]; then result=1 echo "${filename}: run gofmt -s -w ${filename}!" fi go tool vet "${filename}" || result=$? # golint is completely optional. If you don't like it # don't have it installed. if type golint >/dev/null 2>&1; then # golint doesn't set an exit code it seems lintoutput=$(golint "${filename}") if [ "$lintoutput" != "" ]; then result=1 echo "$lintoutput" fi fi # gocyclo is completely optional. If you don't like it # don't have it installed. Also never blocks a commit, # it just warns. if type gocyclo >/dev/null 2>&1; then gocyclo -over 25 "${filename}" | while read line; do echo "${filename}": higher than 25 cyclomatic complexity - "${line}" done fi return $result } function lint { filename="$1" ext="${filename##*\.}" # Don't lint deleted files if [ ! -f "$filename" ]; then return fi # Don't lint this script or static.go case "${filename}" in bin/lint) return;; ./app/static.go) return;; esac case "$ext" in go) lint_go "${filename}" ;; esac } function lint_files { lint_result=0 while read filename; do lint "${filename}" || lint_result=1 done exit $lint_result } function list_files { if [ $# -gt 0 ]; then find "$@" -type f else git diff --cached --name-only fi } list_files "$@" | lint_files