diff --git a/WORKSPACE b/WORKSPACE index ceae31e31dc..41c437e1b55 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -2,8 +2,14 @@ workspace(name = "com_github_istio_test_infra") git_repository( name = "io_bazel_rules_go", - tag = "0.4.4", remote = "https://github.com/bazelbuild/rules_go.git", + tag = "0.4.4", +) + +git_repository( + name = "com_github_bazelbuild_buildtools", + remote = "https://github.com/bazelbuild/buildtools.git", + tag = "0.4.5", ) load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "new_go_repository") @@ -106,14 +112,19 @@ new_go_repository( importpath = "google.golang.org/genproto", ) +new_go_repository( + name = "org_golang_x_tools", + commit = "3d92dd60033c312e3ae7cac319c792271cf67e37", + importpath = "golang.org/x/tools", +) ## ## docker ## git_repository( name = "io_bazel_rules_docker", - tag = "v0.0.1", # May 5 2017 (0.0.1) remote = "https://github.com/bazelbuild/rules_docker.git", + tag = "v0.0.1", # May 5 2017 (0.0.1) ) new_go_repository( @@ -122,8 +133,8 @@ new_go_repository( importpath = "github.com/docker/distribution", ) - load("@io_bazel_rules_docker//docker:docker.bzl", "docker_repositories", "docker_pull") + docker_repositories() docker_pull( @@ -131,4 +142,4 @@ docker_pull( registry = "gcr.io", repository = "distroless/base", tag = "latest", -) \ No newline at end of file +) diff --git a/scripts/linters.sh b/scripts/linters.sh index 7161303a77b..ad64d6c4e0d 100755 --- a/scripts/linters.sh +++ b/scripts/linters.sh @@ -13,107 +13,109 @@ cd ${ROOT} PARENT_BRANCH='' -while getopts :c: arg; do +while getopts :s: arg; do case ${arg} in - c) PARENT_BRANCH="${OPTARG}";; + s) LAST_GOOD_GITSHA="${OPTARG}";; *) error_exit "Unrecognized argument ${OPTARG}";; esac done prep_linters() { - if ! which codecoroner > /dev/null; then - echo "Preparing linters" - go get -u github.com/alecthomas/gometalinter - go get -u github.com/bazelbuild/buildifier/buildifier - go get -u github.com/3rf/codecoroner - gometalinter --install --vendored-linters >/dev/null - fi - ${BIN_PATH}/bazel_to_go.py + if ! which codecoroner > /dev/null; then + echo "Preparing linters" + go get -u github.com/alecthomas/gometalinter + go get -u github.com/bazelbuild/buildifier/buildifier + go get -u github.com/3rf/codecoroner + go get -u honnef.co/go/tools/cmd/megacheck + gometalinter --install --vendored-linters >/dev/null + fi + ${BIN_PATH}/bazel_to_go.py } go_metalinter() { - local parent_branch="${PARENT_BRANCH}" - if [[ ! -z ${TRAVIS_PULL_REQUEST} ]];then - # if travis pull request only lint changed code. - if [[ ${TRAVIS_PULL_REQUEST} != "false" ]]; then - LAST_GOOD_GITSHA=${TRAVIS_COMMIT_RANGE} + if [[ ! -z ${GITHUB_PR_TARGET_BRANCH} ]]; then + local parent_branch='parent' + git fetch origin "refs/heads/${GITHUB_PR_TARGET_BRANCH}:${parent_branch}" + LAST_GOOD_GITSHA="$(git log ${parent_branch}.. --pretty="%H"|tail -1)" + [[ ! -z ${LAST_GOOD_GITSHA} ]] && LAST_GOOD_GITSHA="${LAST_GOOD_GITSHA}^" + fi + + # default: lint everything. This runs on the main build + PKGS=($(bazel query 'kind("go_library", //...)' | cut -d ':' -f 1 | sort | uniq | sed -e 's,//,./,g')) \ + || PKGS=() + + # convert LAST_GOOD_GITSHA to list of packages. + if [[ ! -z ${LAST_GOOD_GITSHA} ]];then + echo "Using ${LAST_GOOD_GITSHA} to compare files to." + CHANGED_DIRS=($(for fn in $(git diff --name-only ${LAST_GOOD_GITSHA}); do fd="./${fn%/*}"; [ -d ${fd} ] && echo $fd; done | sort | uniq)) + NEW_PKGS=() + for d in ${CHANGED_DIRS[@]}; do + for p in ${PKGS}; do + if [[ ${d} =~ ${p} ]]; then + NEW_PKGS+=(${d}) fi - elif [[ ! -z ${GITHUB_PR_TARGET_BRANCH} ]]; then - parent_branch='parent' - git fetch origin "refs/heads/${GITHUB_PR_TARGET_BRANCH}:${parent_branch}" - fi - - if [[ -z ${LAST_GOOD_GITSHA} ]] && [[ -n "${parent_branch}" ]]; then - LAST_GOOD_GITSHA="$(git log ${parent_branch}.. --pretty="%H"|tail -1)" - [[ ! -z ${LAST_GOOD_GITSHA} ]] && LAST_GOOD_GITSHA="${LAST_GOOD_GITSHA}^" - fi - - # default: lint everything. This runs on the main build - PKGS="./tools/github_helper/... ./toolbox/..." - - # convert LAST_GOOD_GITSHA to list of packages. - if [[ ! -z ${LAST_GOOD_GITSHA} ]];then - echo "Using ${LAST_GOOD_GITSHA} to compare files to." - PKGS=$(for fn in $(git diff --name-only ${LAST_GOOD_GITSHA}); do fd="${fn%/*}"; [ -d ${fd} ] && echo $fd; done | sort | uniq) - else - echo 'Running linters on all files.' - fi - - gometalinter\ - --concurrency=4\ - --enable-gc\ - --vendored-linters\ - --deadline=600s --disable-all\ - --enable=aligncheck\ - --enable=deadcode\ - --enable=errcheck\ - --enable=gas\ - --enable=goconst\ - --enable=gofmt\ - --enable=goimports\ - --enable=golint --min-confidence=0 --exclude=.pb.go --exclude=pkg/config/proto/combined.go --exclude="should have a package comment"\ - --enable=gosimple\ - --enable=ineffassign\ - --enable=interfacer\ - --enable=lll --line-length=160\ - --enable=misspell\ - --enable=staticcheck\ - --enable=structcheck\ - --enable=unconvert\ - --enable=unused\ - --enable=varcheck\ - --enable=vet\ - --enable=vetshadow\ - $PKGS - - # TODO: These generate warnings which we should fix, and then should enable the linters - # --enable=dupl\ - # --enable=gocyclo\ - # - # This doesn't work with our source tree for some reason, it can't find vendored imports - # --enable=gotype\ + done + done + PKGS=${NEW_PKGS[@]} + else + echo 'Running linters on all files.' + fi + + [[ -z ${PKGS} ]] && return + # updated to avoid WARNING: staticcheck, gosimple, and unused are all set, using megacheck instead + gometalinter\ + --concurrency=4\ + --enable-gc\ + --vendored-linters\ + --deadline=600s --disable-all\ + --enable=aligncheck\ + --enable=deadcode\ + --enable=errcheck\ + --enable=gas\ + --enable=goconst\ + --enable=gofmt\ + --enable=goimports\ + --enable=golint --min-confidence=0 --exclude=.pb.go --exclude=pkg/config/proto/combined.go --exclude="should have a package comment"\ + --enable=ineffassign\ + --enable=interfacer\ + --enable=lll --line-length=160\ + --enable=megacheck\ + --enable=misspell\ + --enable=structcheck\ + --enable=unconvert\ + --enable=varcheck\ + --enable=vet\ + --enable=vetshadow\ + ${PKGS} + + # TODO: These generate warnings which we should fix, and then should enable the linters + # --enable=dupl\ + # --enable=gocyclo\ + # + # This doesn't work with our source tree for some reason, it can't find vendored imports + # --enable=gotype\ } run_linters() { - echo Running linters - buildifier -showlog -mode=check $(find . -name BUILD -type f) - go_metalinter - ${BIN_PATH}/check_license.sh - buildifier -showlog -mode=check $(find . -type f \( -name 'BUILD' -or \ - -name 'WORKSPACE' -or \ - -wholename '.*\.bazel' -or \ - -wholename '.*bzl' \) -print ) - - # TODO: Enable this once more of mixer is connected and we don't - # have dead code on purpose - # codecoroner funcs ./... - # codecoroner idents ./... + echo Running linters + buildifier -showlog -mode=check $(find . -name BUILD -type f) + go_metalinter + ${BIN_PATH}/check_license.sh + buildifier -showlog -mode=check $(find . -type f \( -name 'BUILD' -or \ + -name 'WORKSPACE' -or \ + -wholename '.*\.bazel' -or \ + -wholename '.*bzl' \) -print ) + + # TODO: Enable this once more of mixer is connected and we don't + # have dead code on purpose + # codecoroner funcs ./... + # codecoroner idents ./... } prep_linters run_linters -echo Done running linters \ No newline at end of file +echo Done running linters diff --git a/toolbox/BUILD b/toolbox/BUILD new file mode 100644 index 00000000000..68f429c6284 --- /dev/null +++ b/toolbox/BUILD @@ -0,0 +1,11 @@ +package(default_visibility = ["//visibility:public"]) + +sh_binary( + name = "format", + srcs = ["format.sh"], + data = [ + "@com_github_bazelbuild_buildtools//buildifier", + "@io_bazel_rules_go_toolchain//:toolchain", + "@org_golang_x_tools//cmd/goimports", + ], +) diff --git a/toolbox/format.sh b/toolbox/format.sh new file mode 100755 index 00000000000..af669a3ef66 --- /dev/null +++ b/toolbox/format.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Applies requisite code formatters to the source tree + +set -o errexit +set -o nounset +set -o pipefail + +# Prefer gofmt from io_bazel_rules_go_toolchain. +EXTERNAL='bazel-bin/toolbox/format.runfiles' +gofmt="${EXTERNAL}/io_bazel_rules_go_toolchain/bin/gofmt" +goimports="${EXTERNAL}/org_golang_x_tools/cmd/goimports/goimports" +buildifier="${EXTERNAL}/com_github_bazelbuild_buildtools/buildifier/buildifier" + +[[ ! -x "${gofmt}" ]] && gofmt=$(which gofmt) +[[ ! -x "${goimports}" ]] && goimports=$(which goimports) +[[ ! -x "${buildifier}" ]] && buildifier=$(which buildifier) + +GO_FILES=$(git ls-files | grep '.*\.go') +UX=$(uname) + +#remove blank lines so gofmt / goimports can do their job +for fl in ${GO_FILES}; do + if [[ ${UX} == "Darwin" ]];then + sed -i '' -e "/^import[[:space:]]*(/,/)/{ /^\s*$/d;}" $fl + else + sed -i -e "/^import[[:space:]]*(/,/)/{ /^\s*$/d;}" $fl +fi +done + +${gofmt} -s -w ${GO_FILES} +${goimports} -w -local istio.io ${GO_FILES} +${buildifier} -showlog -mode=fix $(git ls-files | grep -e 'BUILD' -e 'WORKSPACE' -e '.*\.bazel' -e '.*\.bzl')