k8s.io/registry.k8s.io@v0.3.1/hack/make-rules/shellcheck.sh (about) 1 #!/usr/bin/env bash 2 3 # Copyright 2022 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 # CI script to run shellcheck 18 set -o errexit 19 set -o nounset 20 set -o pipefail 21 22 # cd to the repo root 23 REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." &> /dev/null && pwd -P)" 24 cd "${REPO_ROOT}" 25 26 # we will be installing under bin_dir if necessary, and re-using if possible 27 bin_dir="${REPO_ROOT}/bin" 28 export PATH="${bin_dir}:${PATH}" 29 30 # required version for this script, if not installed on the host already we will 31 # install it under bin/ 32 SHELLCHECK_VERSION="0.8.0" 33 34 # Find all shell scripts excluding: 35 # - Anything git-ignored - No need to lint untracked files. 36 # - ./.git/* - Ignore anything in the git object store. 37 # - ./hack/third_party/* - Ignore vendored scripts. 38 # - ./bin/* - No need to lint output directories. 39 all_shell_scripts=() 40 while IFS=$'\n' read -r script; 41 do git check-ignore -q "$script" || all_shell_scripts+=("$script"); 42 done < <(grep -irl '#!.*sh' . | grep -Ev '^(\./\.git/)|(\./hack/third_party/)|(\./bin/)') 43 44 # common arguments we'll pass to shellcheck 45 SHELLCHECK_OPTIONS=( 46 # allow following sourced files that are not specified in the command, 47 # we need this because we specify one file at a time in order to trivially 48 # detect which files are failing 49 '--external-sources' 50 # disabled lint codes 51 # 2330 - disabled due to https://github.com/koalaman/shellcheck/issues/1162 52 '--exclude=2230' 53 # 2126 - disabled because grep -c exits error when there are zero matches, 54 # unlike grep | wc -l 55 '--exclude=2126' 56 # set colorized output 57 '--color=auto' 58 ) 59 60 # detect if the host machine has the required shellcheck version installed 61 # if so, we will use that instead. 62 HAVE_SHELLCHECK=false 63 if command -v shellcheck &>/dev/null; then 64 detected_version="$(shellcheck --version | grep 'version: .*')" 65 if [[ "${detected_version}" = "version: ${SHELLCHECK_VERSION}" ]]; then 66 HAVE_SHELLCHECK=true 67 fi 68 fi 69 70 # install shellcheck to bin/ if missing or the wrong version 71 if ! ${HAVE_SHELLCHECK}; then 72 echo "Installing shellcheck v${SHELLCHECK_VERSION} under bin/ ..." >&2 73 # in CI we can install xz so we can untar the upstream release 74 # otherwise tell the user they must install xz or shellcheck 75 if ! command -v xz &>/dev/null; then 76 if [[ -n "${PROW_JOB_ID}" ]]; then 77 export DEBIAN_FRONTEND=noninteractive 78 apt-get -qq update 79 DEBCONF_NOWARNINGS="yes" apt-get -qq install --no-install-recommends xz-utils >/dev/null 80 else 81 echo "xz is required to install shellcheck in bin/!" >&2 82 echo "either install xz or install shellcheck v${SHELLCHECK_VERSION}" >&2 83 exit 1 84 fi 85 fi 86 os=$(uname | tr '[:upper:]' '[:lower:]') 87 arch=$(uname -m) 88 # TODO: shellcheck currently only has x86_64 binaries on macOS, but those will work on M1 89 if [[ "${os}" == 'darwin' ]]; then 90 arch='x86_64' 91 fi 92 mkdir -p "${bin_dir}" 93 # download and untar shellcheck into bin_dir 94 curl -sSL "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION?}/shellcheck-v${SHELLCHECK_VERSION?}.${os}.${arch}.tar.xz" \ 95 | tar -C "${bin_dir}" --strip-components=1 -xJ -f - "shellcheck-v${SHELLCHECK_VERSION}/shellcheck" 96 # debug newly setup version 97 shellcheck --version >&2 98 fi 99 100 101 # lint all scripts 102 res=0 103 shellcheck "${SHELLCHECK_OPTIONS[@]}" "${all_shell_scripts[@]}" >&2 || res=$? 104 # print a message based on the result 105 if [ $res -eq 0 ]; then 106 echo 'Congratulations! All shell files are passing lint :-)' 107 else 108 { 109 echo 110 echo 'Please review the above warnings. You can test via "./hack/verify/shellcheck.sh"' 111 echo 'If the above warnings do not make sense, you can exempt this warning with a comment' 112 echo ' (if your reviewer is okay with it).' 113 echo 'In general please prefer to fix the error, we have already disabled specific lints' 114 echo ' that the project chooses to ignore.' 115 echo 'See: https://github.com/koalaman/shellcheck/wiki/Ignore#ignoring-one-specific-instance-in-a-file' 116 echo 117 } >&2 118 exit 1 119 fi 120 121 # preserve the result 122 exit $res