diff --git a/Makefile b/Makefile index f319428673..4a37190e82 100644 --- a/Makefile +++ b/Makefile @@ -134,6 +134,8 @@ GO_APIDIFF_BIN := go-apidiff GO_APIDIFF := $(abspath $(TOOLS_BIN_DIR)/$(GO_APIDIFF_BIN)-$(GO_APIDIFF_VER)) GO_APIDIFF_PKG := github.com/joelanford/go-apidiff +SHELLCHECK_VER := v0.9.0 + KPROMO_VER := v4.0.4 KPROMO_BIN := kpromo KPROMO := $(abspath $(TOOLS_BIN_DIR)/$(KPROMO_BIN)-$(KPROMO_VER)) @@ -320,7 +322,6 @@ generate-e2e-templates: ## Generate e2e cluster templates lint: $(GOLANGCI_LINT) ## Lint the codebase $(MAKE) lint-go-full $(MAKE) lint-markdown - $(MAKE) lint-shell GOLANGCI_LINT_EXTRA_ARGS ?= --fast=true .PHONY: lint-go @@ -335,10 +336,6 @@ lint-go-full: lint-go ## Run slower linters to detect possible issues lint-markdown: ## Lint the project's markdown docker run --rm -v "$$(pwd)":/build$(DOCKER_VOL_OPTS) gcr.io/cluster-api-provider-vsphere/extra/mdlint:0.17.0 -- /md/lint -i _releasenotes . -.PHONY: lint-shell -lint-shell: ## Lint the project's shell scripts - docker run --rm -t -v "$$(pwd)":/build:ro gcr.io/cluster-api-provider-vsphere/extra/shellcheck - .PHONY: lint-fix lint-fix: $(GOLANGCI_LINT) ## Lint the codebase and run auto-fixers if supported by the linter GOLANGCI_LINT_EXTRA_ARGS="--fast=false --fix" $(MAKE) lint-go @@ -349,10 +346,10 @@ APIDIFF_OLD_COMMIT ?= $(shell git rev-parse origin/main) apidiff: $(GO_APIDIFF) ## Check for API differences $(GO_APIDIFF) $(APIDIFF_OLD_COMMIT) --print-compatible -ALL_VERIFY_CHECKS = boilerplate modules gen conversions doctoc flavors +ALL_VERIFY_CHECKS = boilerplate shellcheck modules gen conversions doctoc flavors .PHONY: verify -verify: $(addprefix verify-,$(ALL_VERIFY_CHECKS)) lint-markdown lint-shell ## Run all verify-* targets +verify: $(addprefix verify-,$(ALL_VERIFY_CHECKS)) lint-markdown ## Run all verify-* targets .PHONY: verify-modules verify-modules: generate-modules ## Verify go modules are up to date @@ -387,6 +384,10 @@ verify-doctoc: generate-doctoc verify-boilerplate: ## Verify boilerplate text exists in each file TRACE=$(TRACE) ./hack/verify-boilerplate.sh +.PHONY: verify-shellcheck +verify-shellcheck: ## Verify shell files + TRACE=$(TRACE) ./hack/verify-shellcheck.sh $(SHELLCHECK_VER) + .PHONY: verify-container-images verify-container-images: ## Verify container images TRACE=$(TRACE) ./hack/verify-container-images.sh @@ -411,7 +412,6 @@ verify-flavors: $(FLAVOR_DIR) generate-flavors ## Verify generated flavors echo "flavor files in templates directory are out of date"; exit 1; \ fi - ## -------------------------------------- ## Build ## -------------------------------------- diff --git a/docs/release/release-tasks.md b/docs/release/release-tasks.md index 60f6ae2c02..d801c0a6bf 100644 --- a/docs/release/release-tasks.md +++ b/docs/release/release-tasks.md @@ -7,13 +7,13 @@ -- [Prepare main branch for development of the new release](#prepare-main-branch-for-development-of-the-new-release) -- [Remove previously deprecated code](#remove-previously-deprecated-code) -- [[Optional] Bump the Kubernetes version](#optional-bump-the-kubernetes-version) -- [Bump dependencies](#bump-dependencies) -- [Create a release branch](#create-a-release-branch) -- [Cut a release](#cut-a-release) -- [[Continuously] Reduce the amount of flaky tests](#continuously-reduce-the-amount-of-flaky-tests) +- [Release Tasks](#release-tasks) + - [Prepare main branch for development of the new release](#prepare-main-branch-for-development-of-the-new-release) + - [Remove previously deprecated code](#remove-previously-deprecated-code) + - [\[Optional\] Bump the Kubernetes version](#optional-bump-the-kubernetes-version) + - [Bump dependencies](#bump-dependencies) + - [Create a release branch](#create-a-release-branch) + - [\[Continuously\] Reduce the amount of flaky tests](#continuously-reduce-the-amount-of-flaky-tests) diff --git a/hack/check-shell.sh b/hack/check-shell.sh deleted file mode 100755 index db38eb02a8..0000000000 --- a/hack/check-shell.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail - -# Change directories to the parent directory of the one in which this -# script is located. -cd "$(dirname "${BASH_SOURCE[0]}")/.." - -# This file has been deprecated in favor of the Makefile target "lint-shell". -# This file remains as a backwards-compatible stub for the CI tests since -# older release branches still expect this file to exist. -make lint-shell diff --git a/hack/match-release-tag.sh b/hack/match-release-tag.sh deleted file mode 100755 index 96a6688611..0000000000 --- a/hack/match-release-tag.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail - -# Change directories to the parent directory of the one in which this -# script is located. -cd "$(dirname "${BASH_SOURCE[0]}")/.." - -usage() { - cat <&2; exit 1 - ;; - x) - EXAMPLES=1 - ;; - \?) - { echo "invalid option: -${OPTARG}"; usage; } 1>&2; exit 1 - ;; - :) - echo "option -${OPTARG} requires an argument" 1>&2; exit 1 - ;; - esac -done -shift $((OPTIND-1)) - -# The regular expression matches the following strings: -# * v1.0.0-alpha.0 -# * v1.0.0-beta.0 -# * v1.0.0-rc.0 -# * v1.0.0 -# Any occurence of a digit in the above examples may be multiple digits. -REGEX='^[[:space:]]{0,}v[[:digit:]]{1,}\.[[:digit:]]{1,}\.[[:digit:]]{1,}(-(alpha|beta|rc)\.[[:digit:]]{1,}){0,1}[[:space:]]{0,}$' - -# Match the tag against the regular expression for a release tag. -match() { - if [[ ${1} =~ ${REGEX} ]]; then - echo "yay: ${1}" - else - exit_code="${?}" - echo "nay: ${1}" - return "${exit_code}" - fi -} - -# Run examples to illustrate valid and invalid values. -examples() { - local semvers=" \ - v1.0.0-alpha.0 \ - v1.0.0-beta.0 \ - v1.0.0-rc.0 \ - v1.0.0 \ - v10.0.0 \ - v1.10.0 \ - v1.0.10 \ - v10.0.0-alpha.10 \ - v1.10.0-beta.10 \ - v1.0.10-rc.10 \ - 1.0.0 \ - v1.0.0+rc.0 \ - v10a.0.0 \ - 1.1.0-alpha.1 \ - v1.0.0-alpha.0a" - set +o errexit - for v in ${semvers}; do match "${v}"; done - return 0 -} - -main() { - # Get the tag from the remaining arguments or from "git describe --dirty" - [ "${#}" -eq "0" ] || tag="${1}" - [ -n "${tag-}" ] || tag="$(git describe --dirty)" - - # Match the tag against the regular expression for a release tag. - match "${tag}" 1>&2 -} - -{ [ "${EXAMPLES-}" ] && examples; } || main "${@-}" diff --git a/hack/tools/shellcheck/Dockerfile b/hack/tools/shellcheck/Dockerfile deleted file mode 100644 index 483d05be12..0000000000 --- a/hack/tools/shellcheck/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -# syntax=docker/dockerfile:1.4 - -# Copyright 2019 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -################################################################################ -## INSTALL SHELLCHECK ## -################################################################################ -ARG SHELLCHECK_VERSION=v0.6.0 -FROM koalaman/shellcheck:${SHELLCHECK_VERSION} as build - -################################################################################ -## MAIN ## -################################################################################ -FROM debian:stretch-slim -LABEL "maintainer" "Andrew Kutz " -COPY --from=build /bin/shellcheck /bin/ -COPY shellcheck.sh /bin/shellcheck.sh -WORKDIR /build -ENTRYPOINT [ "/bin/shellcheck.sh" ] diff --git a/hack/tools/shellcheck/Makefile b/hack/tools/shellcheck/Makefile deleted file mode 100644 index 0f30c4dc46..0000000000 --- a/hack/tools/shellcheck/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2019 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -all: build - -IMAGE_VERSION ?= v0.6.0 -IMAGE_NAME ?= gcr.io/cluster-api-provider-vsphere/extra/shellcheck -IMAGE_TAG ?= $(IMAGE_NAME):$(IMAGE_VERSION) - -build: - docker build --build-arg SHELLCHECK_VERSION=$(IMAGE_VERSION) -t $(IMAGE_TAG) . -.PHONY: build - -push: - docker push $(IMAGE_TAG) -.PHONY: push diff --git a/hack/tools/shellcheck/shellcheck.sh b/hack/utils.sh old mode 100755 new mode 100644 similarity index 79% rename from hack/tools/shellcheck/shellcheck.sh rename to hack/utils.sh index 472ed15fdd..df96561ad1 --- a/hack/tools/shellcheck/shellcheck.sh +++ b/hack/utils.sh @@ -1,5 +1,4 @@ -#!/bin/bash - +#!/usr/bin/env bash # Copyright 2019 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,8 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -o errexit -set -o nounset -set -o pipefail - -find . -path ./vendor -prune -o -name "*.*sh" -type f -print0 | xargs -0 shellcheck "${@}" +# get_root_path returns the root path of the project source tree +get_root_path() { + git rev-parse --show-toplevel +} diff --git a/hack/verify-shellcheck.sh b/hack/verify-shellcheck.sh new file mode 100755 index 0000000000..e29007bad8 --- /dev/null +++ b/hack/verify-shellcheck.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +if [[ "${TRACE-0}" == "1" ]]; then + set -o xtrace +fi + +if [ $# -ne 1 ]; then + echo 1>&2 "$0: usage: ./verify-shellcheck.sh " + exit 2 +fi + +VERSION=${1} + +OS="unknown" +if [[ "${OSTYPE}" == "linux"* ]]; then + OS="linux" +elif [[ "${OSTYPE}" == "darwin"* ]]; then + OS="darwin" +fi + +# shellcheck source=./hack/utils.sh +source "$(dirname "$0")/utils.sh" +ROOT_PATH=$(get_root_path) + +# create a temporary directory +TMP_DIR=$(mktemp -d) +OUT="${TMP_DIR}/out.log" + +# cleanup on exit +cleanup() { + ret=0 + if [[ -s "${OUT}" ]]; then + echo "Found errors:" + cat "${OUT}" + ret=1 + fi + echo "Cleaning up..." + rm -rf "${TMP_DIR}" + exit ${ret} +} +trap cleanup EXIT + + +SHELLCHECK="./$(dirname "$0")/tools/bin/shellcheck/${VERSION}/shellcheck" + +if [ ! -f "$SHELLCHECK" ]; then + # install buildifier + cd "${TMP_DIR}" || exit + DOWNLOAD_FILE="shellcheck-${VERSION}.${OS}.x86_64.tar.xz" + curl -L "https://github.com/koalaman/shellcheck/releases/download/${VERSION}/${DOWNLOAD_FILE}" -o "${TMP_DIR}/shellcheck.tar.xz" + tar xf "${TMP_DIR}/shellcheck.tar.xz" + cd "${ROOT_PATH}" + mkdir -p "$(dirname "$0")/tools/bin/shellcheck/${VERSION}" + mv "${TMP_DIR}/shellcheck-${VERSION}/shellcheck" "$SHELLCHECK" +fi + +echo "Running shellcheck..." +cd "${ROOT_PATH}" || exit +FILES=$(find . -name "*.sh") +while read -r file; do + "$SHELLCHECK" -x "$file" >> "${OUT}" 2>&1 +done <<< "$FILES"