...

Text file src/k8s.io/kubernetes/hack/verify-shellcheck.sh

Documentation: k8s.io/kubernetes/hack

     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
    20set -o errexit
    21set -o nounset
    22set -o pipefail
    23
    24KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
    25source "${KUBE_ROOT}/hack/lib/init.sh"
    26source "${KUBE_ROOT}/hack/lib/util.sh"
    27
    28# allow overriding docker cli, which should work fine for this script
    29DOCKER="${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
    33SHELLCHECK_VERSION="0.9.0"
    34SHELLCHECK_IMAGE="docker.io/koalaman/shellcheck-alpine:v0.9.0@sha256:e19ed93c22423970d56568e171b4512c9244fc75dd9114045016b4a0073ac4b7"
    35
    36# disabled lints
    37disabled=(
    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
    49join_by() {
    50  local IFS="$1";
    51  shift;
    52  echo "$*";
    53}
    54SHELLCHECK_DISABLED="$(join_by , "${disabled[@]}")"
    55readonly SHELLCHECK_DISABLED
    56
    57# ensure we're linting the k8s source tree
    58cd "${KUBE_ROOT}"
    59
    60scripts_to_check=("$@")
    61if [[ "$#" == 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    \))
    78fi
    79
    80# detect if the host machine has the required shellcheck version installed
    81# if so, we will use that instead.
    82HAVE_SHELLCHECK=false
    83if 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
    88fi
    89
    90# if KUBE_JUNIT_REPORT_DIR is set, disable colorized output.
    91# Colorized output causes malformed XML in the JUNIT report.
    92SHELLCHECK_COLORIZED_OUTPUT="auto"
    93if [[ -n "${KUBE_JUNIT_REPORT_DIR:-}" ]]; then
    94  SHELLCHECK_COLORIZED_OUTPUT="never"
    95fi
    96
    97# common arguments we'll pass to shellcheck
    98SHELLCHECK_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
   112res=0
   113if ${HAVE_SHELLCHECK}; then
   114  echo "Using host shellcheck ${SHELLCHECK_VERSION} binary."
   115  shellcheck "${SHELLCHECK_OPTIONS[@]}" "${scripts_to_check[@]}" >&2 || res=$?
   116else
   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=$?
   122fi
   123
   124# print a message based on the result
   125if [ $res -eq 0 ]; then
   126  echo 'Congratulations! All shell files are passing lint :-)'
   127else
   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
   139fi
   140
   141# preserve the result
   142exit $res

View as plain text