blob: f49a027b4759fc9b489d720bd847b9d3d4bda933 [file] [log] [blame]
Andrew Geissler9b0105c2018-01-10 10:58:35 -08001#!/bin/bash
Patrick Williamsc1513c82022-11-27 17:37:08 -06002set -e
Andrew Geissler9b0105c2018-01-10 10:58:35 -08003
Patrick Williamsc1513c82022-11-27 17:37:08 -06004# This script reformats source files using various formatters and linters.
Andrew Geissler9b0105c2018-01-10 10:58:35 -08005#
6# Files are changed in-place, so make sure you don't have anything open in an
7# editor, and you may want to commit before formatting in case of awryness.
8#
9# This must be run on a clean repository to succeed
10#
Patrick Williamsc1513c82022-11-27 17:37:08 -060011function display_help()
12{
Patrick Williams816c7cc2022-12-08 05:51:57 -060013 echo "usage: format-code.sh [-h | --help] [--no-diff] [--list-tools]"
14 echo " [--disable <tool>] [--enable <tool>] [<path>]"
Patrick Williamsc1513c82022-11-27 17:37:08 -060015 echo
16 echo "Format and lint a repository."
17 echo
18 echo "Arguments:"
Patrick Williams147f37a2022-12-04 14:57:10 -060019 echo " --list-tools Display available linters and formatters"
20 echo " --no-diff Don't show final diff output"
21 echo " --disable <tool> Disable linter"
Patrick Williams816c7cc2022-12-08 05:51:57 -060022 echo " --enable <tool> Enable only specific linters"
Patrick Williams26d9d2c2022-12-05 15:03:07 -060023 echo " --allow-missing Run even if linters are not all present"
Patrick Williams147f37a2022-12-04 14:57:10 -060024 echo " path Path to git repository (default to pwd)"
Patrick Williamsc1513c82022-11-27 17:37:08 -060025}
Andrew Geissler9b0105c2018-01-10 10:58:35 -080026
Patrick Williams147f37a2022-12-04 14:57:10 -060027LINTERS_ALL=( \
Patrick Williams0b1b8ec2023-12-25 14:19:10 -060028 commit_gitlint \
29 commit_spelling \
30 beautysh \
31 beautysh_sh \
32 black \
33 clang_format \
Patrick Williamsc675d082025-06-09 09:30:46 -040034 clang_tidy \
Patrick Williams0b1b8ec2023-12-25 14:19:10 -060035 eslint \
36 flake8 \
37 isort \
38 markdownlint \
Patrick Williams1ef5c602025-02-01 08:31:27 -050039 meson \
Patrick Williams0b1b8ec2023-12-25 14:19:10 -060040 prettier \
41 shellcheck \
Patrick Williams147f37a2022-12-04 14:57:10 -060042 )
43LINTERS_DISABLED=()
44LINTERS_ENABLED=()
Patrick Williams785327a2022-12-05 16:20:43 -060045declare -A LINTERS_FAILED=()
Patrick Williams147f37a2022-12-04 14:57:10 -060046
Patrick Williams816c7cc2022-12-08 05:51:57 -060047eval set -- "$(getopt -o 'h' --long 'help,list-tools,no-diff,disable:,enable:,allow-missing' -n 'format-code.sh' -- "$@")"
Patrick Williamsc1513c82022-11-27 17:37:08 -060048while true; do
49 case "$1" in
50 '-h'|'--help')
51 display_help && exit 0
52 ;;
Andrew Geissler9b0105c2018-01-10 10:58:35 -080053
Patrick Williams147f37a2022-12-04 14:57:10 -060054 '--list-tools')
55 echo "Available tools:"
56 for t in "${LINTERS_ALL[@]}"; do
57 echo " $t"
58 done
59 exit 0
60 ;;
61
Patrick Williamsd27ab4c2022-11-27 17:51:35 -060062 '--no-diff')
63 OPTION_NO_DIFF=1
64 shift
65 ;;
66
Patrick Williams147f37a2022-12-04 14:57:10 -060067 '--disable')
68 LINTERS_DISABLED+=("$2")
69 shift && shift
70 ;;
71
Patrick Williams816c7cc2022-12-08 05:51:57 -060072 '--enable')
73 LINTERS_ENABLED+=("$2")
74 shift && shift
75 ;;
76
Patrick Williams26d9d2c2022-12-05 15:03:07 -060077 '--allow-missing')
78 ALLOW_MISSING=yes
79 shift
80 ;;
81
Patrick Williamsc1513c82022-11-27 17:37:08 -060082 '--')
83 shift
84 break
85 ;;
86
87 *)
88 echo "unknown option: $1"
89 display_help && exit 1
90 ;;
91 esac
92done
93
94# Detect tty and set nicer colors.
95if [ -t 1 ]; then
96 BLUE="\e[34m"
97 GREEN="\e[32m"
98 NORMAL="\e[0m"
99 RED="\e[31m"
100 YELLOW="\e[33m"
101else # non-tty, no escapes.
102 BLUE=""
103 GREEN=""
104 NORMAL=""
105 RED=""
106 YELLOW=""
107fi
108
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600109# Allow called scripts to know which clang format we are using
Patrick Williams0b1b8ec2023-12-25 14:19:10 -0600110export CLANG_FORMAT="clang-format"
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600111
Patrick Williamsc1513c82022-11-27 17:37:08 -0600112# Path to default config files for linters.
113CONFIG_PATH="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)/config"
Patrick Williamsc675d082025-06-09 09:30:46 -0400114TOOLS_PATH="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)/tools"
115
Patrick Williamsc1513c82022-11-27 17:37:08 -0600116
117# Find repository root for `pwd` or $1.
118if [ -z "$1" ]; then
119 DIR="$(git rev-parse --show-toplevel || pwd)"
120else
121 DIR="$(git -C "$1" rev-parse --show-toplevel)"
122fi
Patrick Williamsbc85b712022-12-05 15:16:27 -0600123if [ ! -e "$DIR/.git" ]; then
124 echo -e "${RED}Error:${NORMAL} Directory ($DIR) does not appear to be a git repository"
Patrick Williamsc1513c82022-11-27 17:37:08 -0600125 exit 1
126fi
Andrew Jeffery0cce8482018-04-30 11:37:01 +0930127
Manojkiran Edae6f120a2021-03-20 11:13:43 +0530128cd "${DIR}"
Patrick Williamsc1513c82022-11-27 17:37:08 -0600129echo -e " ${BLUE}Formatting code under${NORMAL} $DIR"
Andrew Geissler9b0105c2018-01-10 10:58:35 -0800130
Patrick Williams3d294942022-12-05 14:58:15 -0600131# Config hashes:
132# LINTER_REQUIRE - The requirements to run a linter, semi-colon separated.
133# 1. Executable.
134# 2. [optional] Configuration file.
135# 3. [optional] Global fallback configuration file.
136#
137# LINTER_IGNORE - An optional set of semi-colon separated ignore-files
138# specific to the linter.
139#
140# LINTER_TYPES - The file types supported by the linter, semi-colon separated.
141#
142# LINTER_CONFIG - The config (from LINTER_REQUIRE) chosen for the repository.
143#
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600144declare -A LINTER_REQUIRE=()
Patrick Williams71b73242022-12-02 21:07:52 -0600145declare -A LINTER_IGNORE=()
Patrick Williams71b73242022-12-02 21:07:52 -0600146declare -A LINTER_TYPES=()
Patrick Williams3d294942022-12-05 14:58:15 -0600147declare -A LINTER_CONFIG=()
Manojkiran Eda87111bb2021-08-14 11:26:16 +0530148
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600149LINTER_REQUIRE+=([commit_spelling]="codespell")
Patrick Williams71b73242022-12-02 21:07:52 -0600150LINTER_TYPES+=([commit_spelling]="commit")
Ed Tanous910732c2024-01-02 10:23:03 -0800151
152commit_filename="$(mktemp)"
153function clean_up_file() {
154 rm "$commit_filename"
155}
156trap clean_up_file EXIT
157
Manojkiran Edac0fab5e2024-09-09 13:50:49 +0530158function find_codespell_dict_file() {
159 local python_codespell_dict
160 # @formatter:off
161 python_codespell_dict=$(python3 -c "
162import os.path as op
163import codespell_lib
164codespell_dir = op.dirname(codespell_lib.__file__)
165codespell_file = op.join(codespell_dir, 'data', 'dictionary.txt')
166print(codespell_file if op.isfile(codespell_file) else '', end='')
167" 2> /dev/null)
168 # @formatter:on
169
170 # Return the path if found, otherwise return an empty string
171 echo "$python_codespell_dict"
172}
173
Patrick Williams38515a32022-11-27 06:58:56 -0600174function do_commit_spelling() {
Ed Tanous910732c2024-01-02 10:23:03 -0800175 # Write the commit message to a temporary file
Jonathan Doman1d5e00d2024-01-11 18:33:54 -0800176 git log --format='%B' -1 > "$commit_filename"
Ed Tanous910732c2024-01-02 10:23:03 -0800177
178 # Some names or emails appear as false-positive misspellings, remove them
179 sed -i "s/Signed-off-by.*//" "$commit_filename"
180
Manojkiran Edac0fab5e2024-09-09 13:50:49 +0530181 # Get the path to the dictionary.txt file
182 local codespell_dict
183 codespell_dict=$(find_codespell_dict_file)
Ed Tanous910732c2024-01-02 10:23:03 -0800184
Manojkiran Edac0fab5e2024-09-09 13:50:49 +0530185 # Check if the dictionary file was found
186 if [[ -z "$codespell_dict" ]]; then
187 echo "Error: Could not find dictionary.txt file"
188 exit 1
189 fi
Patrick Williams38515a32022-11-27 06:58:56 -0600190
Manojkiran Edac0fab5e2024-09-09 13:50:49 +0530191 # Run the codespell with codespell dictionary on the patchset
192 echo -n "codespell-dictionary - misspelling count >> "
193 codespell -D "$codespell_dict" -d --count "$commit_filename"
194
195 # Run the codespell with builtin dictionary on the patchset
Patrick Williams71b73242022-12-02 21:07:52 -0600196 echo -n "generic-dictionary - misspelling count >> "
Ed Tanous910732c2024-01-02 10:23:03 -0800197 codespell --builtin clear,rare,en-GB_to_en-US -d --count "$commit_filename"
Patrick Williams38515a32022-11-27 06:58:56 -0600198}
199
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600200LINTER_REQUIRE+=([commit_gitlint]="gitlint")
Patrick Williams71b73242022-12-02 21:07:52 -0600201LINTER_TYPES+=([commit_gitlint]="commit")
Patrick Williams38515a32022-11-27 06:58:56 -0600202function do_commit_gitlint() {
Patrick Williams71b73242022-12-02 21:07:52 -0600203 gitlint --extra-path "${CONFIG_PATH}/gitlint/" \
Patrick Williamsc1513c82022-11-27 17:37:08 -0600204 --config "${CONFIG_PATH}/.gitlint"
Patrick Williams38515a32022-11-27 06:58:56 -0600205}
206
Patrick Williamsc5969592022-12-06 09:50:25 -0600207# We need different function style for bash/zsh vs plain sh, so beautysh is
208# split into two linters. "function foo()" is not traditionally accepted
209# POSIX-shell syntax, so shellcheck barfs on it.
210LINTER_REQUIRE+=([beautysh]="beautysh")
211LINTER_IGNORE+=([beautysh]=".beautysh-ignore")
212LINTER_TYPES+=([beautysh]="bash;zsh")
213function do_beautysh() {
214 beautysh --force-function-style fnpar "$@"
215}
216LINTER_REQUIRE+=([beautysh_sh]="beautysh")
217LINTER_IGNORE+=([beautysh_sh]=".beautysh-ignore")
218LINTER_TYPES+=([beautysh_sh]="sh")
219function do_beautysh_sh() {
220 beautysh --force-function-style paronly "$@"
221}
222
Patrick Williamse795dfe2022-12-06 10:07:02 -0600223LINTER_REQUIRE+=([black]="black")
224LINTER_TYPES+=([black]="python")
225function do_black() {
Patrick Williams45b21522023-02-14 16:39:20 -0600226 black -l 79 "$@"
Patrick Williamse795dfe2022-12-06 10:07:02 -0600227}
228
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600229LINTER_REQUIRE+=([eslint]="eslint;.eslintrc.json;${CONFIG_PATH}/eslint-global-config.json")
Patrick Williams71b73242022-12-02 21:07:52 -0600230LINTER_IGNORE+=([eslint]=".eslintignore")
231LINTER_TYPES+=([eslint]="json")
Patrick Williams38515a32022-11-27 06:58:56 -0600232function do_eslint() {
Patrick Williams71b73242022-12-02 21:07:52 -0600233 eslint --no-eslintrc -c "${LINTER_CONFIG[eslint]}" \
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600234 --ext .json --format=stylish \
235 --resolve-plugins-relative-to /usr/local/lib/node_modules \
Patrick Williams71b73242022-12-02 21:07:52 -0600236 --no-error-on-unmatched-pattern "$@"
Patrick Williams38515a32022-11-27 06:58:56 -0600237}
Manojkiran Eda87111bb2021-08-14 11:26:16 +0530238
Patrick Williamsc5ad7ff2022-12-05 10:21:40 -0600239LINTER_REQUIRE+=([flake8]="flake8")
240LINTER_IGNORE+=([flake8]=".flake8-ignore")
241LINTER_TYPES+=([flake8]="python")
242function do_flake8() {
243 flake8 --show-source --extend-ignore=E203,E501 "$@"
244 # We disable E203 and E501 because 'black' is handling these and they
245 # disagree on best practices.
Patrick Williams38515a32022-11-27 06:58:56 -0600246}
James Feistf1665d62019-11-22 09:06:33 -0800247
Patrick Williamse795dfe2022-12-06 10:07:02 -0600248LINTER_REQUIRE+=([isort]="isort")
249LINTER_TYPES+=([isort]="python")
250function do_isort() {
251 isort --profile black "$@"
252}
253
Patrick Williams7d41f6d2022-12-06 10:19:43 -0600254LINTER_REQUIRE+=([markdownlint]="markdownlint;.markdownlint.yaml;${CONFIG_PATH}/markdownlint.yaml")
255LINTER_IGNORE+=([markdownlint]=".markdownlint-ignore")
256LINTER_TYPES+=([markdownlint]="markdown")
257function do_markdownlint() {
Patrick Williams7d27a5b2025-06-25 10:19:51 -0400258 markdownlint --config "${LINTER_CONFIG[markdownlint]}" -- "$@"
Patrick Williams7d41f6d2022-12-06 10:19:43 -0600259}
260
Patrick Williams1ef5c602025-02-01 08:31:27 -0500261LINTER_REQUIRE+=([meson]="meson;meson.build")
262LINTER_TYPES+=([meson]="meson")
263function do_meson() {
264 meson format -i "$@"
265}
266
Patrick Williamsb08ddf72022-12-06 08:56:31 -0600267LINTER_REQUIRE+=([prettier]="prettier;.prettierrc.yaml;${CONFIG_PATH}/prettierrc.yaml")
268LINTER_IGNORE+=([prettier]=".prettierignore")
269LINTER_TYPES+=([prettier]="json;markdown;yaml")
270function do_prettier() {
271 prettier --config "${LINTER_CONFIG[prettier]}" --write "$@"
272}
273
Patrick Williamse0df3052022-12-05 10:22:00 -0600274LINTER_REQUIRE+=([shellcheck]="shellcheck")
275LINTER_IGNORE+=([shellcheck]=".shellcheck-ignore")
Patrick Williams71b73242022-12-02 21:07:52 -0600276LINTER_TYPES+=([shellcheck]="bash;sh")
Patrick Williams38515a32022-11-27 06:58:56 -0600277function do_shellcheck() {
Patrick Williams71b73242022-12-02 21:07:52 -0600278 shellcheck --color=never -x "$@"
Patrick Williams38515a32022-11-27 06:58:56 -0600279}
James Feistf1665d62019-11-22 09:06:33 -0800280
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600281LINTER_REQUIRE+=([clang_format]="clang-format;.clang-format")
Patrick Williams71b73242022-12-02 21:07:52 -0600282LINTER_IGNORE+=([clang_format]=".clang-ignore;.clang-format-ignore")
283LINTER_TYPES+=([clang_format]="c;cpp")
Patrick Williams476a7e92022-12-06 09:52:53 -0600284function do_clang_format() {
Patrick Williams71b73242022-12-02 21:07:52 -0600285 "${CLANG_FORMAT}" -i "$@"
286}
Patrick Williams38515a32022-11-27 06:58:56 -0600287
Patrick Williamsc675d082025-06-09 09:30:46 -0400288LINTER_REQUIRE+=([clang_tidy]="true")
289LINTER_TYPES+=([clang_tidy]="clang-tidy-config")
290function do_clang_tidy() {
291 "${TOOLS_PATH}/config-clang-tidy" format
292}
293
Patrick Williams71b73242022-12-02 21:07:52 -0600294function get_file_type()
295{
296 case "$(basename "$1")" in
297 # First to early detect template files.
298 *.in | *.meson) echo "meson-template" && return ;;
299 *.mako | *.mako.*) echo "mako" && return ;;
Patrick Williamsd535ecb2022-12-02 14:54:18 -0600300
Patrick Williams71b73242022-12-02 21:07:52 -0600301 *.ac) echo "autoconf" && return ;;
302 *.[ch]) echo "c" && return ;;
303 *.[ch]pp) echo "cpp" && return ;;
304 *.json) echo "json" && return ;;
305 *.md) echo "markdown" && return ;;
306 *.py) echo "python" && return ;;
Patrick Williams5095cbe2022-12-08 06:50:34 -0600307 *.tcl) echo "tcl" && return ;;
Patrick Williams71b73242022-12-02 21:07:52 -0600308 *.yaml | *.yml) echo "yaml" && return ;;
Patrick Williamsd535ecb2022-12-02 14:54:18 -0600309
Patrick Williams71b73242022-12-02 21:07:52 -0600310 # Special files.
311 .git/COMMIT_EDITMSG) echo "commit" && return ;;
Patrick Williamsc675d082025-06-09 09:30:46 -0400312 .clang-format) echo "clang-format-config" && return ;;
313 .clang-tidy) echo "clang-tidy-config" && return ;;
Patrick Williams71b73242022-12-02 21:07:52 -0600314 meson.build) echo "meson" && return ;;
Patrick Williams1ef5c602025-02-01 08:31:27 -0500315 meson.options) echo "meson" && return ;;
Patrick Williams71b73242022-12-02 21:07:52 -0600316 esac
317
318 case "$(file "$1")" in
319 *Bourne-Again\ shell*) echo "bash" && return ;;
320 *C++\ source*) echo "cpp" && return ;;
321 *C\ source*) echo "c" && return ;;
322 *JSON\ data*) echo "json" && return ;;
323 *POSIX\ shell*) echo "sh" && return ;;
324 *Python\ script*) echo "python" && return ;;
Patrick Williamsd5d63952022-12-07 17:55:03 -0600325 *python3\ script*) echo "python" && return ;;
Patrick Williams71b73242022-12-02 21:07:52 -0600326 *zsh\ shell*) echo "zsh" && return ;;
327 esac
328
329 echo "unknown"
Patrick Williams38515a32022-11-27 06:58:56 -0600330}
331
Patrick Williams816c7cc2022-12-08 05:51:57 -0600332LINTERS_AVAILABLE=()
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600333function check_linter()
334{
335 TITLE="$1"
336 IFS=";" read -r -a ARGS <<< "$2"
337
Patrick Williams147f37a2022-12-04 14:57:10 -0600338 if [[ "${LINTERS_DISABLED[*]}" =~ $1 ]]; then
339 return
340 fi
341
Patrick Williams816c7cc2022-12-08 05:51:57 -0600342 if [ 0 -ne "${#LINTERS_ENABLED[@]}" ]; then
343 if ! [[ "${LINTERS_ENABLED[*]}" =~ $1 ]]; then
344 return
345 fi
346 fi
347
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600348 EXE="${ARGS[0]}"
349 if [ ! -x "${EXE}" ]; then
350 if ! which "${EXE}" > /dev/null 2>&1 ; then
351 echo -e " ${YELLOW}${TITLE}:${NORMAL} cannot find ${EXE}"
Patrick Williams26d9d2c2022-12-05 15:03:07 -0600352 if [ -z "$ALLOW_MISSING" ]; then
353 exit 1
354 fi
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600355 return
356 fi
357 fi
358
359 CONFIG="${ARGS[1]}"
360 FALLBACK="${ARGS[2]}"
361
362 if [ -n "${CONFIG}" ]; then
363 if [ -e "${CONFIG}" ]; then
364 LINTER_CONFIG+=( [${TITLE}]="${CONFIG}" )
365 elif [ -n "${FALLBACK}" ] && [ -e "${FALLBACK}" ]; then
366 echo -e " ${YELLOW}${TITLE}:${NORMAL} cannot find ${CONFIG}; using ${FALLBACK}"
367 LINTER_CONFIG+=( [${TITLE}]="${FALLBACK}" )
368 else
369 echo -e " ${YELLOW}${TITLE}:${NORMAL} cannot find config ${CONFIG}"
370 return
371 fi
372 fi
373
Patrick Williams816c7cc2022-12-08 05:51:57 -0600374 LINTERS_AVAILABLE+=( "${TITLE}" )
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600375}
376
Patrick Williams71b73242022-12-02 21:07:52 -0600377# Check for a global .linter-ignore file.
378GLOBAL_IGNORE=("cat")
379if [ -e ".linter-ignore" ]; then
380 GLOBAL_IGNORE=("${CONFIG_PATH}/lib/ignore-filter" ".linter-ignore")
381fi
382
383# Find all the files in the git repository and organize by type.
384declare -A FILES=()
Ed Tanous910732c2024-01-02 10:23:03 -0800385FILES+=([commit]=".git")
386
Patrick Williams71b73242022-12-02 21:07:52 -0600387while read -r file; do
388 ftype="$(get_file_type "$file")"
389 FILES+=([$ftype]="$(echo -ne "$file;${FILES[$ftype]:-}")")
Patrick Williamsf0584402023-07-11 11:27:33 -0500390done < <(git ls-files | xargs realpath --relative-base=. | "${GLOBAL_IGNORE[@]}")
Patrick Williams71b73242022-12-02 21:07:52 -0600391
392# For each linter, check if there are an applicable files and if it can
393# be enabled.
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600394for op in "${LINTERS_ALL[@]}"; do
Patrick Williams71b73242022-12-02 21:07:52 -0600395 for ftype in ${LINTER_TYPES[$op]//;/ }; do
396 if [[ -v FILES["$ftype"] ]]; then
397 check_linter "$op" "${LINTER_REQUIRE[${op}]}"
398 break
399 fi
400 done
Patrick Williamsdad9b7a2022-11-30 13:10:20 -0600401done
402
Patrick Williams71b73242022-12-02 21:07:52 -0600403# Call each linter.
Patrick Williams816c7cc2022-12-08 05:51:57 -0600404for op in "${LINTERS_AVAILABLE[@]}"; do
Patrick Williams71b73242022-12-02 21:07:52 -0600405
406 # Determine the linter-specific ignore file(s).
407 LOCAL_IGNORE=("${CONFIG_PATH}/lib/ignore-filter")
408 if [[ -v LINTER_IGNORE["$op"] ]]; then
409 for ignorefile in ${LINTER_IGNORE["$op"]//;/ } ; do
410 if [ -e "$ignorefile" ]; then
411 LOCAL_IGNORE+=("$ignorefile")
412 fi
413 done
414 fi
415 if [ 1 -eq ${#LOCAL_IGNORE[@]} ]; then
416 LOCAL_IGNORE=("cat")
417 fi
418
419 # Find all the files for this linter, filtering out the ignores.
420 LINTER_FILES=()
421 while read -r file ; do
422 if [ -e "$file" ]; then
423 LINTER_FILES+=("$file")
424 fi
425 done < <(for ftype in ${LINTER_TYPES[$op]//;/ }; do
426 # shellcheck disable=SC2001
427 echo "${FILES["$ftype"]:-}" | sed "s/;/\\n/g"
428 done | "${LOCAL_IGNORE[@]}")
429
430 # Call the linter now with all the files.
Patrick Williams200ec182022-12-06 08:32:03 -0600431 if [ 0 -ne ${#LINTER_FILES[@]} ]; then
432 echo -e " ${BLUE}Running $op${NORMAL}"
433 if ! "do_$op" "${LINTER_FILES[@]}" ; then
434 LINTERS_FAILED+=([$op]=1)
Chris Cain2f5d53b2025-05-06 16:49:32 -0500435 echo -e " ${RED}$op - FAILED${NORMAL}"
Patrick Williams200ec182022-12-06 08:32:03 -0600436 fi
437 else
438 echo -e " ${YELLOW}${op}:${NORMAL} all applicable files are on ignore-lists"
Patrick Williams785327a2022-12-05 16:20:43 -0600439 fi
Patrick Williams38515a32022-11-27 06:58:56 -0600440done
Andrew Jeffery457b6d12018-03-09 15:28:14 +1030441
Patrick Williams785327a2022-12-05 16:20:43 -0600442# Check for failing linters.
443if [ 0 -ne ${#LINTERS_FAILED[@]} ]; then
444 for op in "${!LINTERS_FAILED[@]}"; do
Chris Cain2f5d53b2025-05-06 16:49:32 -0500445 echo -e "$op: ${RED}FAILED${NORMAL} (see prior failure)"
Patrick Williams785327a2022-12-05 16:20:43 -0600446 done
447 exit 1
448fi
449
Patrick Williams71b73242022-12-02 21:07:52 -0600450# Check for differences.
Patrick Williamsd27ab4c2022-11-27 17:51:35 -0600451if [ -z "$OPTION_NO_DIFF" ]; then
452 echo -e " ${BLUE}Result differences...${NORMAL}"
453 if ! git --no-pager diff --exit-code ; then
454 echo -e "Format: ${RED}FAILED${NORMAL}"
455 exit 1
456 else
457 echo -e "Format: ${GREEN}PASSED${NORMAL}"
458 fi
Patrick Williamsc1513c82022-11-27 17:37:08 -0600459fi
460
Andrew Jeffery457b6d12018-03-09 15:28:14 +1030461# Sometimes your situation is terrible enough that you need the flexibility.
462# For example, phosphor-mboxd.
Patrick Williams330b0772022-11-28 06:14:06 -0600463for formatter in "format-code.sh" "format-code"; do
464 if [[ -x "${formatter}" ]]; then
465 echo -e " ${BLUE}Calling secondary formatter:${NORMAL} ${formatter}"
466 "./${formatter}"
467 if [ -z "$OPTION_NO_DIFF" ]; then
468 git --no-pager diff --exit-code
469 fi
Patrick Williamsd27ab4c2022-11-27 17:51:35 -0600470 fi
Patrick Williams330b0772022-11-28 06:14:06 -0600471done