mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 18:20:27 +00:00
f041a74ff Undo some quoting that broke the test script (#160) b1c21a068 Merge pull request #158 from weaveworks/go-1-13 d5c7dd0cd Run shell-lint during CI, and fix warnings 6db1abd14 Update to Go 1.13.1 d6cc704a2 Fix comment 7139116ae Revert "Push comments to the left so they don't appear in scripts" e47e58f7b Push comments to the left so they don't appear in scripts 3945fcec8 Remove nonexistent env var GIT_TAG cd6299284 Merge pull request #156 from weaveworks/drop-quay af0eb5119 Merge pull request #157 from weaveworks/fix-image-tag-prefix-length 0b9aee4f2 Fix image-tag object name prefix length to 8 chars. 813c28fe7 Move from CircleCI 1.0 to 2.0 425cf4ef1 Move from quay.io to Dockerhub 87ccf4fd1 Merge pull request #155 from weaveworks/go-1-12 c31bc2865 Update lint script to work with Go 1.12 ed8e380d7 Update to Go 1.12.1 git-subtree-dir: tools git-subtree-split: f041a74ffbf273b627d6c960f17357108d0dbd1c
268 lines
7.0 KiB
Bash
Executable File
268 lines
7.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# This scipt lints files for common errors.
|
|
#
|
|
# For go files, it runs gofmt and go vet, and optionally golint and
|
|
# gocyclo, if they are installed.
|
|
#
|
|
# For shell files, it runs shfmt. If you don't have that installed, you can get
|
|
# it with:
|
|
# curl -fsSLo shfmt https://github.com/mvdan/sh/releases/download/v1.3.0/shfmt_v1.3.0_linux_amd64
|
|
# chmod +x shfmt
|
|
#
|
|
# 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 -e
|
|
|
|
LINT_IGNORE_FILE=${LINT_IGNORE_FILE:-".lintignore"}
|
|
|
|
IGNORE_LINT_COMMENT=
|
|
IGNORE_SPELLINGS=
|
|
while true; do
|
|
case "$1" in
|
|
-nocomment)
|
|
IGNORE_LINT_COMMENT=1
|
|
shift 1
|
|
;;
|
|
-notestpackage)
|
|
# NOOP, still accepted for backwards compatibility
|
|
shift 1
|
|
;;
|
|
-ignorespelling)
|
|
IGNORE_SPELLINGS="$2,$IGNORE_SPELLINGS"
|
|
shift 2
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
spell_check() {
|
|
local filename="$1"
|
|
local lint_result=0
|
|
|
|
# misspell is completely optional. If you don't like it
|
|
# don't have it installed.
|
|
if ! type misspell >/dev/null 2>&1; then
|
|
return $lint_result
|
|
fi
|
|
|
|
if ! misspell -error -i "$IGNORE_SPELLINGS" "${filename}"; then
|
|
lint_result=1
|
|
fi
|
|
|
|
return $lint_result
|
|
}
|
|
|
|
lint_go() {
|
|
# This function is called on a whole directory containing Go files
|
|
local filename="$1"
|
|
local lint_result=0
|
|
|
|
if [ -n "$(gofmt -s -l "${filename}")" ]; then
|
|
lint_result=1
|
|
echo "${filename}: run gofmt -s -w ${filename}"
|
|
fi
|
|
|
|
go vet "${filename}" || lint_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
|
|
if [ -z "$IGNORE_LINT_COMMENT" ]; then
|
|
lintoutput=$(golint "${filename}")
|
|
else
|
|
lintoutput=$(golint "${filename}" | grep -vE 'comment|dot imports|ALL_CAPS')
|
|
fi
|
|
if [ -n "$lintoutput" ]; then
|
|
lint_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 -r line; do
|
|
echo "${filename}": higher than 25 cyclomatic complexity - "${line}"
|
|
done
|
|
fi
|
|
|
|
return $lint_result
|
|
}
|
|
|
|
lint_sh() {
|
|
local filename="$1"
|
|
local lint_result=0
|
|
|
|
# Skip shfmt validation, if not installed
|
|
if type shfmt >/dev/null 2>&1; then
|
|
if ! diff -u "${filename}" <(shfmt -i 4 "${filename}"); then
|
|
lint_result=1
|
|
echo "${filename}: run shfmt -i 4 -w ${filename}"
|
|
fi
|
|
fi
|
|
|
|
# the shellcheck is completely optional. If you don't like it
|
|
# don't have it installed.
|
|
if type shellcheck >/dev/null 2>&1; then
|
|
shellcheck "${filename}" || lint_result=1
|
|
fi
|
|
|
|
return $lint_result
|
|
}
|
|
|
|
lint_tf() {
|
|
local filename="$1"
|
|
local lint_result=0
|
|
|
|
if ! diff -u <(hclfmt "${filename}") "${filename}"; then
|
|
lint_result=1
|
|
echo "${filename}: run hclfmt -w ${filename}"
|
|
fi
|
|
|
|
return $lint_result
|
|
}
|
|
|
|
lint_md() {
|
|
local filename="$1"
|
|
local lint_result=0
|
|
|
|
for i in '=======' '>>>>>>>'; do
|
|
if grep -q "${i}" "${filename}"; then
|
|
lint_result=1
|
|
echo "${filename}: bad merge/rebase!"
|
|
fi
|
|
done
|
|
|
|
return $lint_result
|
|
}
|
|
|
|
lint_py() {
|
|
local filename="$1"
|
|
local lint_result=0
|
|
|
|
if yapf --diff "${filename}" | grep -qE '^[+-]'; then
|
|
lint_result=1
|
|
echo "${filename} needs reformatting. Run: yapf --in-place ${filename}"
|
|
else
|
|
# Only run flake8 if yapf passes, since they pick up a lot of similar issues
|
|
flake8 "${filename}" || lint_result=1
|
|
fi
|
|
|
|
return $lint_result
|
|
}
|
|
|
|
lint() {
|
|
filename="$1"
|
|
ext="${filename##*\.}"
|
|
local lint_result=0
|
|
|
|
# Don't lint deleted files
|
|
if [ ! -f "$filename" ]; then
|
|
return
|
|
fi
|
|
|
|
# Don't lint specific files
|
|
case "$(basename "${filename}")" in
|
|
static.go) return ;;
|
|
coverage.html) return ;;
|
|
*.pb.go) return ;;
|
|
esac
|
|
|
|
mimetype=$(file --mime-type "${filename}" | awk '{print $2}')
|
|
|
|
case "$mimetype.$ext" in
|
|
text/x-shellscript.*) lint_sh "${filename}" || lint_result=1 ;;
|
|
*.go) ;; # done at directory level
|
|
*.tf) lint_tf "${filename}" || lint_result=1 ;;
|
|
*.md) lint_md "${filename}" || lint_result=1 ;;
|
|
*.py) lint_py "${filename}" || lint_result=1 ;;
|
|
esac
|
|
|
|
# we don't want to spell check tar balls, binaries, Makefile and json files
|
|
case "$mimetype.$ext" in
|
|
*.tar | *.gz | *.json) ;;
|
|
*.req | *.key | *.pem | *.crt) ;;
|
|
application/x-executable.*) ;;
|
|
text/x-makefile.*) ;;
|
|
*) spell_check "${filename}" || lint_result=1 ;;
|
|
esac
|
|
|
|
return $lint_result
|
|
}
|
|
|
|
lint_files() {
|
|
local lint_result=0
|
|
while read -r filename; do
|
|
lint "${filename}" || lint_result=1
|
|
done
|
|
return $lint_result
|
|
}
|
|
|
|
matches_any() {
|
|
local filename="$1"
|
|
local patterns="$2"
|
|
while read -r pattern; do
|
|
# shellcheck disable=SC2053
|
|
# Use the [[ operator without quotes on $pattern
|
|
# in order to "glob" the provided filename:
|
|
[[ "$filename" == $pattern ]] && return 0
|
|
done <<<"$patterns"
|
|
return 1
|
|
}
|
|
|
|
filter_out() {
|
|
local patterns_file="$1"
|
|
if [ -n "$patterns_file" ] && [ -r "$patterns_file" ]; then
|
|
local patterns
|
|
patterns=$(sed '/^#.*$/d ; /^\s*$/d' "$patterns_file") # Remove blank lines and comments before we start iterating.
|
|
[ -n "$DEBUG" ] && echo >&2 "> Filters:" && echo >&2 "$patterns"
|
|
local filtered_out=()
|
|
while read -r filename; do
|
|
matches_any "$filename" "$patterns" && filtered_out+=("$filename") || echo "$filename"
|
|
done
|
|
[ -n "$DEBUG" ] && echo >&2 "> Files filtered out (i.e. NOT linted):" && printf >&2 '%s\n' "${filtered_out[@]}"
|
|
else
|
|
cat # No patterns provided: simply propagate stdin to stdout.
|
|
fi
|
|
}
|
|
|
|
lint_directory() {
|
|
local dirname="$1"
|
|
local lint_result=0
|
|
# This test is just checking if there are any Go files in the directory
|
|
if compgen -G "$dirname/*.go" >/dev/null; then
|
|
lint_go "${dirname}" || lint_result=1
|
|
fi
|
|
find . -maxdepth 1 "$dirname" | filter_out "$LINT_IGNORE_FILE" | lint_files
|
|
return $lint_result
|
|
}
|
|
|
|
lint_directories() {
|
|
local lint_result=0
|
|
while read -r dirname; do
|
|
lint_directory "${dirname}" || lint_result=1
|
|
done
|
|
exit $lint_result
|
|
}
|
|
|
|
list_directories() {
|
|
if [ $# -gt 0 ]; then
|
|
find "$@" \( -name vendor -o -name .git -o -name .cache -o -name .pkg \) -prune -o -type d
|
|
fi
|
|
}
|
|
|
|
if [ $# = 1 ] && [ -f "$1" ]; then
|
|
lint "$1"
|
|
else
|
|
list_directories "$@" | lint_directories
|
|
fi
|