1#!/usr/bin/env bash
2# Copyright (c) 2024 Huawei Device Co., Ltd.
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15set -e
16
17if [[ -z "$1" ]]; then
18    echo "Usage: $0 <sources>"
19    echo "    <sources> path where the sources to be checked are located"
20    echo
21    echo "    The script launches shellcheck and bashate tools against all *sh"
22    echo "    scripts found in the specified folder."
23    echo "    For bashate, all rules are checked by default except E006 and E042"
24    echo "    One can set BASHATE_IGNORE_RULES variable to skip oher rules."
25    echo "    For shellcheck, a prefedined setof rules is checked (see comments in the script)."
26    echo "    One can set SHELLCHECK_INCLLUDE_RULES variable to check custom set of rules"
27    exit 1
28fi
29
30root_dir=$(realpath "$1")
31# For shellcheck, we only enable certain rules
32# - SC1068 - no spaces  round +=/=
33# - SC1106 - correctness of string/arithmetic comparisons
34# - SC1133 - special chars at the beginning of the line
35# - SC2002 - useless cat
36# - SC2003 - use of antique expr
37# - SC2006 - for $(...) usage instead of obsolete ``
38# - SC2010 - avoid 'ls | grep'
39# - SC2024 - sudo redirection
40# - SC2034 - unused variables
41# - SC2041 - usage of strings instead of commands
42# - SC2045 - iterating over ls
43# - SC2064 - quotation in signal trap
44# - SC2066 - stream merge order
45# - SC2067 - find-exec usage
46# - SC2081 - square/single brackets usage
47# - SC2086 - Double quotes for vaiables
48# - SC2088 - Tilde usage
49# - SC2093 - exec usage
50# - SC2115 - safe var usage in rm
51# - SC2142 - aliass can't have parameters
52# - SC2144 - '-e' and globs
53# - SC2148 - requires shebang to be present
54# - SC2152 - func return value between 0 and 255
55# - SC2164 - Safe cd
56# - SC2166 - avoid [ p -a q ]
57# - SC2172 - do not trap by number
58# - SC2173 - do not trap SIGKILL/SIGSTOP
59# - SC2222 - exit code between 0 and 255
60# - SC2253 - Safe chmod
61SHELLCHECK_RULES=${SHELLCHECK_INCLLUDE_RULES:-"SC1068,SC1106,SC1133,\
62SC2002,SC2003,SC2006,SC2010,SC2024,SC2034,SC2041,SC2045,SC2064,SC2066,\
63SC2067,SC2081,SC2086,SC2088,SC2093,SC2115,SC2142,SC2144,SC2148,SC2152,\
64SC2164,SC2166,SC2172,SC2173,SC2222,SC2253"}
65
66# For bashate, we enable all rules and only exclude several ones
67# - E006 is 'Line Too Long' which should be additionally adjusted for us
68# - E042 is 'local definition hides errors'
69BASHATE_RULES=${BASHATE_IGNORE_RULES:-"E006,E042"}
70
71function save_exit_code() {
72    return $(($1 + $2))
73}
74
75set +e
76
77EXIT_CODE=0
78
79skip_options="^${root_dir}/third_party/"
80if [ ! -z "$SKIP_FOLDERS" ]; then
81    for pt in $SKIP_FOLDERS; do
82        skip_options="${skip_options}\|^${root_dir}/${pt}/"
83    done
84fi
85
86while read file_to_check; do
87    bashate-mod-ds -i "${BASHATE_RULES}" "${file_to_check}"
88    save_exit_code ${EXIT_CODE} $?
89    EXIT_CODE=$?
90    shellcheck -i "${SHELLCHECK_RULES}" "${file_to_check}"
91    save_exit_code ${EXIT_CODE} $?
92    EXIT_CODE=$?
93done <<<$(find "${root_dir}" -name "*.sh" -type f | grep -v "${skip_options}")
94
95num_checked=$(find "${root_dir}" -name "*.sh" -type f | grep -c -v "${skip_options}")
96echo "Checked ${num_checked} files"
97
98exit ${EXIT_CODE}
99