k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/hack/verify-shellcheck.sh (about) 1 #!/usr/bin/env bash 2 3 # Copyright 2018 The Kubernetes Authors. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 # This script lints each shell script by `shellcheck`. 18 # Usage: `hack/verify-shellcheck.sh`. 19 20 set -o errexit 21 set -o nounset 22 set -o pipefail 23 24 KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. 25 source "${KUBE_ROOT}/hack/lib/init.sh" 26 source "${KUBE_ROOT}/hack/lib/util.sh" 27 28 # allow overriding docker cli, which should work fine for this script 29 DOCKER="${DOCKER:-docker}" 30 31 # required version for this script, if not installed on the host we will 32 # use the official docker image instead. keep this in sync with SHELLCHECK_IMAGE 33 SHELLCHECK_VERSION="0.9.0" 34 SHELLCHECK_IMAGE="docker.io/koalaman/shellcheck-alpine:v0.9.0@sha256:e19ed93c22423970d56568e171b4512c9244fc75dd9114045016b4a0073ac4b7" 35 36 # disabled lints 37 disabled=( 38 # this lint disallows non-constant source, which we use extensively without 39 # any known bugs 40 1090 41 # this lint warns when shellcheck cannot find a sourced file 42 # this wouldn't be a bad idea to warn on, but it fails on lots of path 43 # dependent sourcing, so just disable enforcing it 44 1091 45 # this lint prefers command -v to which, they are not the same 46 2230 47 ) 48 # comma separate for passing to shellcheck 49 join_by() { 50 local IFS="$1"; 51 shift; 52 echo "$*"; 53 } 54 SHELLCHECK_DISABLED="$(join_by , "${disabled[@]}")" 55 readonly SHELLCHECK_DISABLED 56 57 # ensure we're linting the k8s source tree 58 cd "${KUBE_ROOT}" 59 60 scripts_to_check=("$@") 61 if [[ "$#" == 0 ]]; then 62 # Find all shell scripts excluding: 63 # - Anything git-ignored - No need to lint untracked files. 64 # - ./_* - No need to lint output directories. 65 # - ./.git/* - Ignore anything in the git object store. 66 # - ./vendor* - Vendored code should be fixed upstream instead. 67 # - ./third_party/*, but re-include ./third_party/forked/* - only code we 68 # forked should be linted and fixed. 69 while IFS=$'\n' read -r script; 70 do git check-ignore -q "$script" || scripts_to_check+=("$script"); 71 done < <(find . -name "*.sh" \ 72 -not \( \ 73 -path ./_\* -o \ 74 -path ./.git\* -o \ 75 -path ./vendor\* -o \ 76 \( -path ./third_party\* -a -not -path ./third_party/forked\* \) \ 77 \)) 78 fi 79 80 # detect if the host machine has the required shellcheck version installed 81 # if so, we will use that instead. 82 HAVE_SHELLCHECK=false 83 if which shellcheck &>/dev/null; then 84 detected_version="$(shellcheck --version | grep 'version: .*')" 85 if [[ "${detected_version}" = "version: ${SHELLCHECK_VERSION}" ]]; then 86 HAVE_SHELLCHECK=true 87 fi 88 fi 89 90 # if KUBE_JUNIT_REPORT_DIR is set, disable colorized output. 91 # Colorized output causes malformed XML in the JUNIT report. 92 SHELLCHECK_COLORIZED_OUTPUT="auto" 93 if [[ -n "${KUBE_JUNIT_REPORT_DIR:-}" ]]; then 94 SHELLCHECK_COLORIZED_OUTPUT="never" 95 fi 96 97 # common arguments we'll pass to shellcheck 98 SHELLCHECK_OPTIONS=( 99 # allow following sourced files that are not specified in the command, 100 # we need this because we specify one file at a time in order to trivially 101 # detect which files are failing 102 "--external-sources" 103 # include our disabled lints 104 "--exclude=${SHELLCHECK_DISABLED}" 105 # set colorized output 106 "--color=${SHELLCHECK_COLORIZED_OUTPUT}" 107 ) 108 109 # tell the user which we've selected and lint all scripts 110 # The shellcheck errors are printed to stdout by default, hence they need to be redirected 111 # to stderr in order to be well parsed for Junit representation by juLog function 112 res=0 113 if ${HAVE_SHELLCHECK}; then 114 echo "Using host shellcheck ${SHELLCHECK_VERSION} binary." 115 shellcheck "${SHELLCHECK_OPTIONS[@]}" "${scripts_to_check[@]}" >&2 || res=$? 116 else 117 echo "Using shellcheck ${SHELLCHECK_VERSION} docker image." 118 "${DOCKER}" run \ 119 --rm -v "${KUBE_ROOT}:${KUBE_ROOT}" -w "${KUBE_ROOT}" \ 120 "${SHELLCHECK_IMAGE}" \ 121 shellcheck "${SHELLCHECK_OPTIONS[@]}" "${scripts_to_check[@]}" >&2 || res=$? 122 fi 123 124 # print a message based on the result 125 if [ $res -eq 0 ]; then 126 echo 'Congratulations! All shell files are passing lint :-)' 127 else 128 { 129 echo 130 echo 'Please review the above warnings. You can test via "./hack/verify-shellcheck.sh"' 131 echo 'If the above warnings do not make sense, you can exempt this warning with a comment' 132 echo ' (if your reviewer is okay with it).' 133 echo 'In general please prefer to fix the error, we have already disabled specific lints' 134 echo ' that the project chooses to ignore.' 135 echo 'See: https://github.com/koalaman/shellcheck/wiki/Ignore#ignoring-one-specific-instance-in-a-file' 136 echo 137 } >&2 138 exit 1 139 fi 140 141 # preserve the result 142 exit $res