diff --git a/Library/Homebrew/style.rb b/Library/Homebrew/style.rb index 5ea6f3d47e..2f98c357c5 100644 --- a/Library/Homebrew/style.rb +++ b/Library/Homebrew/style.rb @@ -65,12 +65,16 @@ module Homebrew run_shellcheck(shell_files, output_type) end - run_shfmt(shell_files, fix: fix) if ruby_files.none? || shell_files.any? + shfmt_result = if ruby_files.any? && shell_files.none? + true + else + run_shfmt(shell_files, fix: fix) + end if output_type == :json Offenses.new(rubocop_result + shellcheck_result) else - rubocop_result && shellcheck_result + rubocop_result && shellcheck_result && shfmt_result end end diff --git a/Library/Homebrew/utils/shfmt.sh b/Library/Homebrew/utils/shfmt.sh index 5b00521c13..01a6401454 100755 --- a/Library/Homebrew/utils/shfmt.sh +++ b/Library/Homebrew/utils/shfmt.sh @@ -49,6 +49,7 @@ do SHFMT_ARGS+=("${arg}") shift done +unset arg FILES=() for file in "$@" @@ -66,6 +67,7 @@ do exit 1 fi done +unset file if [[ "${#FILES[@]}" == 0 ]] then @@ -76,6 +78,32 @@ fi ### Custom shell script styling ### +# Check for specific patterns and prompt messages if detected +no_forbidden_patten() { + local file="$1" + local tempfile="$2" + local subject="$3" + local message="$4" + local regex_pos="$5" + local regex_neg="${6:-}" + local line + local num=0 + local retcode=0 + + while IFS='' read -r line + do + num="$((num + 1))" + if [[ "${line}" =~ ${regex_pos} ]] && + [[ -z "${regex_neg}" || ! "${line}" =~ ${regex_neg} ]] + then + onoe "${subject} detected at \"${file}\", line ${num}." + [[ -n "${message}" ]] && onoe "${message}" + retcode=1 + fi + done <"${file}" + return "${retcode}" +} + # Check pattern: # '^\t+' # @@ -84,22 +112,12 @@ fi no_tabs() { local file="$1" local tempfile="$2" - local line - local num=0 - local retcode=0 - local regex_pos='^[[:space:]]+' - local regex_neg='^ +' - while IFS='' read -r line - do - num="$((num + 1))" - if [[ "${line}" =~ ${regex_pos} && ! "${line}" =~ ${regex_neg} ]] - then - onoe "Indent by tab detected at \"${file}\", line ${num}." - retcode=1 - fi - done <"${file}" - return "${retcode}" + no_forbidden_patten "${file}" "${tempfile}" \ + "Indent with tab" \ + 'Replace tabs with 2 spaces instead.' \ + '^[[:space:]]+' \ + '^ +' } # Check pattern: @@ -116,18 +134,10 @@ no_tabs() { no_multiline_for_statements() { local file="$1" local tempfile="$2" - local line - local num=0 - local retcode=0 local regex='^ *for [_[:alnum:]]+ in .*\\$' - - while IFS='' read -r line - do - num="$((num + 1))" - if [[ "${line}" =~ ${regex} ]] - then - onoe "Multiline for statement detected at \"${file}\", line ${num}." - cat >&2 <&2 <"${tempfile}" } -# TODO: it's hard to align multiline switch cases +# TODO: It's hard to align multiline switch cases align_multiline_switch_cases() { true } format() { local file="$1" + local tempfile if [[ ! -f "${file}" || ! -r "${file}" ]] then onoe "File \"${file}\" is not readable." return 1 fi - # shellcheck disable=SC2155 - local tempfile="$(dirname "${file}")/.${file##*/}.temp" - + tempfile="$(dirname "${file}")/.${file##*/}.temp" trap 'rm -f "${tempfile}" 2>/dev/null' RETURN cp -af "${file}" "${tempfile}" @@ -325,15 +335,12 @@ format() { # Format with `shfmt` first if ! "${SHFMT}" -w "${SHFMT_ARGS[@]}" "${tempfile}" then - onoe "Failed to run \`shfmt\`" + onoe "Failed to run \`shfmt\` for file \"${file}\"." return 1 fi - # Fail fast when forbidden patterns detected - if ! no_forbiddens "${file}" "${tempfile}" - then - return 2 - fi + # Fail fast when forbidden styles detected + ! no_forbidden_styles "${file}" "${tempfile}" && return 2 # Tweak it with custom shell script styles wrap_then_do "${file}" "${tempfile}" @@ -357,13 +364,15 @@ format() { RETCODE=0 for file in "${FILES[@]}" do - if ! format "${file}" + format "${file}" + retcode="$?" + if [[ "${retcode}" != 0 ]] then - if [[ "$?" == 1 ]] + if [[ "${retcode}" == 1 ]] then - onoe "${0##*/}: Failed to format file \"${file}\". Function exited with code 1." + onoe "${0##*/}: Failed to format file \"${file}\". Formatter exited with code 1." else - onoe "${0##*/}: Bad style for file \"${file}\". Function exited with code 2." + onoe "${0##*/}: Bad style for file \"${file}\". Formatter exited with code 2." fi onoe RETCODE=1