From d041bec31507568e41b535ed267499afbd37795a Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 26 Mar 2015 15:14:01 +0000 Subject: [PATCH 1/3] Add lint script, which can also act as an optional presubmit hook. --- bin/lint | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100755 bin/lint diff --git a/bin/lint b/bin/lint new file mode 100755 index 00000000..6bb262d1 --- /dev/null +++ b/bin/lint @@ -0,0 +1,86 @@ +#!/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 + +EXIT_CODE=0 + +function lint_go { + filename=$1 + + if [ "$(gofmt -d $filename)" != "" ]; then + EXIT_CODE=1 + echo "$filename: run gofmt -w $filename!" + fi + + go tool vet ${filename} || EXIT_CODE=$? + + # golint is completely optional. If you don't like it + # don't have it installed. + if [ "$(which golint)" != "" ]; then + # golint doesn't set an exit code it seems + lintoutput=$(golint $filename) + if [ "$lintoutput" != "" ]; then + echo "$lintoutput" + EXIT_CODE=1 + 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 [ "$(which gocyclo)" != "" ]; then + gocyclo -over 25 ${filename} | while read line; do + echo ${filename}: higher than 25 cyclomatic complexity - ${line} + done + fi +} + +function lint { + filename=$1 + ext=${filename##*\.} + + # If this is a directory, then lint the files in it + if [[ -d ${filename} ]]; then + for filename in $(find ${filename} -type f); do + lint ${filename} + done + return + fi + + # Don't lint this script + if [ "${filename}" == "bin/lint" ]; then + return + fi + + case "$ext" in + go) lint_go $filename + ;; + esac +} + +if [ $# -gt 0 ]; then + for filename in $@; do + lint ${filename} + done +else + for filename in $(git diff --cached --name-only); do + if [ ! -e "${filename}" ]; then + continue + fi + + lint ${filename} + done +fi + +exit $EXIT_CODE From 9e63b4e8c7210ed52776667139f8f011cb93531b Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 26 Mar 2015 18:08:30 +0000 Subject: [PATCH 2/3] Feedback on lint script --- bin/lint | 69 ++++++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/bin/lint b/bin/lint index 6bb262d1..3a42aea8 100755 --- a/bin/lint +++ b/bin/lint @@ -13,74 +13,69 @@ set -eu -EXIT_CODE=0 - function lint_go { - filename=$1 + filename="$1" + result=0 - if [ "$(gofmt -d $filename)" != "" ]; then - EXIT_CODE=1 - echo "$filename: run gofmt -w $filename!" + if [ -n "$(gofmt -l "${filename}")" ]; then + result=1 + echo "${filename}: run gofmt -w ${filename}!" fi - go tool vet ${filename} || EXIT_CODE=$? + go tool vet ${filename} || result=$? # golint is completely optional. If you don't like it # don't have it installed. - if [ "$(which golint)" != "" ]; then + if type golint >/dev/null 2>&1; then # golint doesn't set an exit code it seems - lintoutput=$(golint $filename) + lintoutput=$(golint "${filename}") if [ "$lintoutput" != "" ]; then + result=1 echo "$lintoutput" - EXIT_CODE=1 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 [ "$(which gocyclo)" != "" ]; then - gocyclo -over 25 ${filename} | while read line; do - echo ${filename}: higher than 25 cyclomatic complexity - ${line} + 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##*\.} - - # If this is a directory, then lint the files in it - if [[ -d ${filename} ]]; then - for filename in $(find ${filename} -type f); do - lint ${filename} - done - return - fi + filename="$1" + ext="${filename##*\.}" # Don't lint this script - if [ "${filename}" == "bin/lint" ]; then + if [ "${filename}" = "bin/lint" ]; then return fi case "$ext" in - go) lint_go $filename + go) lint_go "${filename}" ;; esac } -if [ $# -gt 0 ]; then - for filename in $@; do - lint ${filename} +function lint_files { + result=0 + while read filename; do + lint "${filename}" || result=1 done -else - for filename in $(git diff --cached --name-only); do - if [ ! -e "${filename}" ]; then - continue - fi + exit $result +} - lint ${filename} - done -fi +function list_files { + if [ $# -gt 0 ]; then + find "$@" -type f + else + git diff --cached --name-only + fi +} -exit $EXIT_CODE +list_files "$@" | lint_files From dde179f861ed2dc124ed139404d9a7d5fd865fb2 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Thu, 26 Mar 2015 18:19:02 +0000 Subject: [PATCH 3/3] Quote the last filename --- bin/lint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/lint b/bin/lint index 3a42aea8..9f5d3c89 100755 --- a/bin/lint +++ b/bin/lint @@ -22,7 +22,7 @@ function lint_go { echo "${filename}: run gofmt -w ${filename}!" fi - go tool vet ${filename} || result=$? + go tool vet "${filename}" || result=$? # golint is completely optional. If you don't like it # don't have it installed.