From d559d3ff46f374c73d4fb20a8a31ed09477c0b12 Mon Sep 17 00:00:00 2001 From: XuehaiPan Date: Thu, 16 Sep 2021 23:16:07 +0800 Subject: [PATCH 1/3] utils/shfmt.sh: reuse similar code fragments --- Library/Homebrew/utils/shfmt.sh | 112 ++++++++++++++++---------------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/Library/Homebrew/utils/shfmt.sh b/Library/Homebrew/utils/shfmt.sh index 5b00521c13..dcae0f0c9d 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 </dev/null' RETURN cp -af "${file}" "${tempfile}" @@ -325,15 +330,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}" From 065c5b79fe48180c9e1c32782153e9eab6c739ff Mon Sep 17 00:00:00 2001 From: XuehaiPan Date: Thu, 16 Sep 2021 23:26:23 +0800 Subject: [PATCH 2/3] utils/shfmt.sh: refactor function `align_multiline_if_condition` --- Library/Homebrew/utils/shfmt.sh | 39 +++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/Library/Homebrew/utils/shfmt.sh b/Library/Homebrew/utils/shfmt.sh index dcae0f0c9d..01a6401454 100755 --- a/Library/Homebrew/utils/shfmt.sh +++ b/Library/Homebrew/utils/shfmt.sh @@ -202,18 +202,23 @@ no_forbidden_styles() { # then then # # before: after: -# if [[ -n ... || \ if [[ -n ... || \ +# if [[ -n ... || if [[ -n ... || # -n ... ]] -n ... ]] # then then # align_multiline_if_condition() { - local multiline_if_begin_regex='^( *)(el)?if ' - local multiline_then_end_regex='^(.*)\; (then( *#.*)?)$' - local within_test_regex='^( *)(((! )?-[fdrwxes])|([^\[]+ == ))' - local base_indent='' - local extra_indent='' local line local lastline='' + local base_indent='' # indents before `if` + local extra_indent='' # 2 extra spaces for `elif` + local multiline_if_begin_regex='^( *)(el)?if ' + local multiline_then_end_regex='^(.*)\; (then( *#.*)?)$' + local within_test_regex='^( *)(((! )?-[fdLrwxeszn] )|([^\[]+ == ))' + + trim() { + [[ "$1" =~ [^[:space:]](.*[^[:space:]])? ]] + printf "%s" "${BASH_REMATCH[0]}" + } if [[ "$1" =~ ${multiline_if_begin_regex} ]] then @@ -234,9 +239,9 @@ align_multiline_if_condition() { fi if [[ "${line}" =~ ${within_test_regex} ]] then - echo " ${extra_indent}${line}" + echo "${base_indent}${extra_indent} $(trim "${line}")" else - echo " ${extra_indent}${line}" + echo "${base_indent}${extra_indent} $(trim "${line}")" fi done @@ -250,7 +255,7 @@ align_multiline_if_condition() { # # before: after: # if [[ ... ]] || if [[ ... ]] || -# [[ ... ]]; then [[ ... ]] +# [[ ... ]]; then [[ ... ]] # then # # before: after: @@ -261,13 +266,13 @@ wrap_then_do() { local file="$1" local tempfile="$2" - local -a processed + local -a processed=() + local -a buffer=() local line local singleline_then_regex='^( *)(el)?if (.+)\; (then( *#.*)?)$' local singleline_do_regex='^( *)(for|while) (.+)\; (do( *#.*)?)$' local multiline_if_begin_regex='^( *)(el)?if ' local multiline_then_end_regex='^(.*)\; (then( *#.*)?)$' - local -a buffer=() while IFS='' read -r line do @@ -303,7 +308,7 @@ wrap_then_do() { printf "%s\n" "${processed[@]}" >"${tempfile}" } -# TODO: it's hard to align multiline switch cases +# TODO: It's hard to align multiline switch cases align_multiline_switch_cases() { true } @@ -359,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 From 966189d07db604c953855e97c97377006e4ce8dd Mon Sep 17 00:00:00 2001 From: XuehaiPan Date: Thu, 16 Sep 2021 23:42:30 +0800 Subject: [PATCH 3/3] style: add shfmt exit status to `brew style` --- Library/Homebrew/style.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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