utils/shfmt.sh: implement checkers for forbidden styles
This commit is contained in:
parent
03c7a142be
commit
09a16bcea1
@ -83,14 +83,23 @@ fi
|
|||||||
#
|
#
|
||||||
no_tabs() {
|
no_tabs() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
|
local tempfile="$2"
|
||||||
|
local line
|
||||||
|
local num=0
|
||||||
|
local retcode=0
|
||||||
|
local regex_pos='^[[:space:]]+'
|
||||||
|
local regex_neg='^ +'
|
||||||
|
|
||||||
# TODO: use bash built-in regex match syntax instead
|
while IFS='' read -r line
|
||||||
if grep -qE '^\t+' "${file}"
|
do
|
||||||
then
|
num="$((num + 1))"
|
||||||
# TODO: add line number
|
if [[ "${line}" =~ ${regex_pos} && ! "${line}" =~ ${regex_neg} ]]
|
||||||
onoe "Indent by tab detected."
|
then
|
||||||
return 1
|
onoe "Indent by tab detected at \"${file}\", line ${num}."
|
||||||
fi
|
retcode=1
|
||||||
|
fi
|
||||||
|
done <"${file}"
|
||||||
|
return "${retcode}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check pattern:
|
# Check pattern:
|
||||||
@ -98,56 +107,98 @@ no_tabs() {
|
|||||||
# ...; do
|
# ...; do
|
||||||
#
|
#
|
||||||
# Use the followings instead (keep for statements only one line):
|
# Use the followings instead (keep for statements only one line):
|
||||||
# ARRAY=(
|
# ARRAY=(
|
||||||
# ...
|
# ...
|
||||||
# ...
|
# )
|
||||||
# )
|
# for var in "${ARRAY[@]}"
|
||||||
# for var in "${ARRAY[@]}"
|
# do
|
||||||
# do
|
|
||||||
#
|
#
|
||||||
no_multiline_for_statements() {
|
no_multiline_for_statements() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
|
local tempfile="$2"
|
||||||
|
local line
|
||||||
|
local num=0
|
||||||
|
local retcode=0
|
||||||
|
local regex='^ *for [_[:alnum:]]+ in .*\\$'
|
||||||
|
|
||||||
# TODO: use bash built-in regex match syntax instead
|
while IFS='' read -r line
|
||||||
if grep -qE '^\s*for .*\\\(#.*\)\?$' "${file}"
|
do
|
||||||
then
|
num="$((num + 1))"
|
||||||
# TODO: add line number
|
if [[ "${line}" =~ ${regex} ]]
|
||||||
onoe "Multi-line for statement detected."
|
then
|
||||||
return 1
|
onoe "Multiline for statement detected at \"${file}\", line ${num}."
|
||||||
fi
|
cat >&2 <<EOMSG
|
||||||
|
Use the followings instead (keep for statements only one line):
|
||||||
|
ARRAY=(
|
||||||
|
...
|
||||||
|
)
|
||||||
|
for var in "\${ARRAY[@]}"
|
||||||
|
do
|
||||||
|
...
|
||||||
|
done
|
||||||
|
EOMSG
|
||||||
|
retcode=1
|
||||||
|
fi
|
||||||
|
done <"${file}"
|
||||||
|
return "${retcode}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check pattern:
|
# Check pattern:
|
||||||
# IFS=$'\n'
|
# IFS=$'\n'
|
||||||
#
|
#
|
||||||
# Use the followings instead:
|
# Use the followings instead:
|
||||||
# while IFS='' read -r line
|
# while IFS='' read -r line
|
||||||
# do
|
# do
|
||||||
# ...
|
# ...
|
||||||
# done < <(command)
|
# done < <(command)
|
||||||
#
|
#
|
||||||
no_IFS_newline() {
|
no_IFS_newline() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
|
local tempfile="$2"
|
||||||
|
local line
|
||||||
|
local num=0
|
||||||
|
local retcode=0
|
||||||
|
local regex="^[^#]*IFS=\\\$'\\\\n'"
|
||||||
|
|
||||||
# TODO: use bash built-in regex match syntax instead
|
while IFS='' read -r line
|
||||||
if grep -qE "^[^#]*IFS=\\\$'\\\\n'" "${file}"
|
do
|
||||||
then
|
num="$((num + 1))"
|
||||||
# TODO: add line number
|
if [[ "${line}" =~ ${regex} ]]
|
||||||
onoe "Pattern \`IFS=\$'\\\\n'\` detected."
|
then
|
||||||
return 1
|
onoe "Pattern \`IFS=\$'\\n'\` detected at \"${file}\", line ${num}."
|
||||||
fi
|
cat >&2 <<EOMSG
|
||||||
|
Use the followings instead:
|
||||||
|
while IFS='' read -r line
|
||||||
|
do
|
||||||
|
...
|
||||||
|
done < <(command)
|
||||||
|
EOMSG
|
||||||
|
retcode=1
|
||||||
|
fi
|
||||||
|
done <"${file}"
|
||||||
|
return "${retcode}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Combine all forbidden styles
|
||||||
|
no_forbiddens() {
|
||||||
|
local file="$1"
|
||||||
|
local tempfile="$2"
|
||||||
|
|
||||||
|
no_tabs "${file}" "${tempfile}" || return 1
|
||||||
|
no_multiline_for_statements "${file}" "${tempfile}" || return 1
|
||||||
|
no_IFS_newline "${file}" "${tempfile}" || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Align multiline if condition (indent with 3 spaces or 6 spaces (start with "-"))
|
# Align multiline if condition (indent with 3 spaces or 6 spaces (start with "-"))
|
||||||
# before: after:
|
# before: after:
|
||||||
# if [[ ... ]] || if [[ ... ]] ||
|
# if [[ ... ]] || if [[ ... ]] ||
|
||||||
# [[ ... ]] [[ ... ]]
|
# [[ ... ]] [[ ... ]]
|
||||||
# then then
|
# then then
|
||||||
#
|
#
|
||||||
# before: after:
|
# before: after:
|
||||||
# if [[ -n ... || \ if [[ -n ... || \
|
# if [[ -n ... || \ if [[ -n ... || \
|
||||||
# -n ... ]] -n ... ]]
|
# -n ... ]] -n ... ]]
|
||||||
# then then
|
# then then
|
||||||
#
|
#
|
||||||
align_multiline_if_condition() {
|
align_multiline_if_condition() {
|
||||||
local multiline_if_begin_regex='^( *)(el)?if '
|
local multiline_if_begin_regex='^( *)(el)?if '
|
||||||
@ -188,20 +239,21 @@ align_multiline_if_condition() {
|
|||||||
|
|
||||||
# Wrap `then` and `do` to a separated line
|
# Wrap `then` and `do` to a separated line
|
||||||
# before: after:
|
# before: after:
|
||||||
# if [[ ... ]]; then if [[ ... ]]
|
# if [[ ... ]]; then if [[ ... ]]
|
||||||
# then
|
# then
|
||||||
#
|
#
|
||||||
# before: after:
|
# before: after:
|
||||||
# if [[ ... ]] || if [[ ... ]] ||
|
# if [[ ... ]] || if [[ ... ]] ||
|
||||||
# [[ ... ]]; then [[ ... ]]
|
# [[ ... ]]; then [[ ... ]]
|
||||||
# then
|
# then
|
||||||
#
|
#
|
||||||
# before: after:
|
# before: after:
|
||||||
# for var in ...; do for var in ...
|
# for var in ...; do for var in ...
|
||||||
# do
|
# do
|
||||||
#
|
#
|
||||||
wrap_then_do() {
|
wrap_then_do() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
|
local tempfile="$2"
|
||||||
|
|
||||||
local -a processed
|
local -a processed
|
||||||
local line
|
local line
|
||||||
@ -240,9 +292,9 @@ wrap_then_do() {
|
|||||||
buffer=()
|
buffer=()
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done < <(cat "${file}")
|
done <"${tempfile}"
|
||||||
|
|
||||||
printf "%s\n" "${processed[@]}" >"${file}"
|
printf "%s\n" "${processed[@]}" >"${tempfile}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO: it's hard to align multiline switch cases
|
# TODO: it's hard to align multiline switch cases
|
||||||
@ -250,10 +302,6 @@ align_multiline_switch_cases() {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
no_forbiddens() {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
format() {
|
format() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
if [[ ! -f "${file}" || ! -r "${file}" ]]
|
if [[ ! -f "${file}" || ! -r "${file}" ]]
|
||||||
@ -282,17 +330,16 @@ format() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Fail fast when forbidden patterns detected
|
# Fail fast when forbidden patterns detected
|
||||||
if ! no_tabs "${tempfile}" ||
|
if ! no_forbiddens "${file}" "${tempfile}"
|
||||||
! no_multiline_for_statements "${tempfile}" ||
|
|
||||||
! no_IFS_newline "${tempfile}"
|
|
||||||
then
|
then
|
||||||
return 1
|
return 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Tweak it with custom shell script styles
|
# Tweak it with custom shell script styles
|
||||||
wrap_then_do "${tempfile}"
|
wrap_then_do "${file}" "${tempfile}"
|
||||||
|
align_multiline_switch_cases "${file}" "${tempfile}"
|
||||||
|
|
||||||
if ! diff -q "${file}" "${tempfile}"
|
if ! diff -q "${file}" "${tempfile}" &>/dev/null
|
||||||
then
|
then
|
||||||
# Show differences
|
# Show differences
|
||||||
diff -d -C 1 --color=auto "${file}" "${tempfile}"
|
diff -d -C 1 --color=auto "${file}" "${tempfile}"
|
||||||
@ -314,9 +361,9 @@ do
|
|||||||
then
|
then
|
||||||
if [[ "$?" == 1 ]]
|
if [[ "$?" == 1 ]]
|
||||||
then
|
then
|
||||||
onoe "${0##*/}: Failed to format file \"${file}\". Function exited with code $?."
|
onoe "${0##*/}: Failed to format file \"${file}\". Function exited with code 1."
|
||||||
else
|
else
|
||||||
onoe "${0##*/}: Bad style for file \"${file}\". Function exited with code $?."
|
onoe "${0##*/}: Bad style for file \"${file}\". Function exited with code 2."
|
||||||
fi
|
fi
|
||||||
onoe
|
onoe
|
||||||
RETCODE=1
|
RETCODE=1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user