From 0ba68dacd273cba1e7f18f686d4d8d492db9a96d Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Fri, 25 Sep 2020 15:24:21 -0700 Subject: [PATCH 01/12] Better shellcheck support Supports --enable=all for optional checks Adds shellcheck directives to properly source files --- .vscode/settings.json | 32 +++ bin/argbash | 272 +++++++++--------- bin/argbash-1to2 | 55 ++-- bin/argbash-init | 139 ++++----- resources/Makefile | 3 +- resources/examples/minimal-raw.m4 | 6 +- resources/examples/minimal.m4 | 7 +- resources/examples/simple-parsing.m4 | 2 +- resources/examples/simple-parsing.sh | 20 +- resources/examples/simple-standalone.m4 | 6 +- resources/examples/simple-standalone.sh | 159 ++++++---- resources/examples/simple-wrapper.m4 | 19 +- resources/examples/simple-wrapper.sh | 41 +-- resources/examples/simple.m4 | 28 +- resources/examples/simple.sh | 31 +- src/argbash-1to2.m4 | 35 +-- src/argbash-init.m4 | 107 +++---- src/argbash.m4 | 230 +++++++-------- src/argument_value_types.m4 | 4 +- src/collectors.m4 | 14 +- src/env_vars.m4 | 2 +- src/function_generators.m4 | 12 +- src/progs.m4 | 10 +- src/stuff.m4 | 46 +-- src/value_validators.m4 | 6 +- tests/regressiontests/Makefile | 6 +- tests/regressiontests/basic.m4 | 2 +- tests/regressiontests/call-salone.m4 | 2 +- tests/regressiontests/gen-test-more.m4 | 1 - .../regressiontests/make/tests/tests-base.m4 | 4 +- .../regressiontests/make/tests/tests-init.m4 | 2 +- tests/regressiontests/reverse | 14 +- tests/regressiontests/test-ddash-old.m4 | 3 +- tests/regressiontests/test-delim-both.m4 | 4 +- tests/regressiontests/test-delim-equals.m4 | 4 +- tests/regressiontests/test-delim-space.m4 | 3 +- tests/regressiontests/test-env-base.m4 | 4 +- tests/regressiontests/test-env-simple.m4 | 2 +- tests/regressiontests/test-group-idx.m4 | 2 +- tests/regressiontests/test-group.m4 | 2 +- .../test-infinity-minimal_call.m4 | 3 +- tests/regressiontests/test-infinity-mixed.m4 | 3 +- .../test-infinity-nodefaults.m4 | 3 +- tests/regressiontests/test-infinity.m4 | 2 +- tests/regressiontests/test-int.m4 | 2 +- tests/regressiontests/test-leftovers.m4 | 6 +- tests/regressiontests/test-more.m4 | 2 +- tests/regressiontests/test-onlyopt.m4 | 2 +- .../regressiontests/test-onlypos-declared.m4 | 2 +- tests/regressiontests/test-onlypos.m4 | 2 +- tests/regressiontests/test-prog.m4 | 2 +- tests/regressiontests/test-progs.m4 | 4 +- tests/regressiontests/test-simple.m4 | 2 +- tests/regressiontests/test-wrapping-excl.m4 | 3 +- tests/regressiontests/test-wrapping-more.m4 | 3 +- .../regressiontests/test-wrapping-otherdir.m4 | 2 +- .../test-wrapping-second_level.m4 | 4 +- tests/regressiontests/test-wrapping.m4 | 2 +- 58 files changed, 710 insertions(+), 680 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8ae007a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,32 @@ +{ + "cSpell.words": [ + "ARGBASH", + "SPURIONS", + "alnum", + "autom", + "browsable", + "changecom", + "chmod", + "commandline", + "defns", + "docopt", + "errstr", + "eval", + "fname", + "infile", + "infname", + "lolo", + "newerfile", + "outfile", + "outfname", + "positionals", + "posix", + "searchdir", + "shfile", + "sortof", + "srcfile", + "srcfiles", + "srcstem", + "thatfile" + ] +} \ No newline at end of file diff --git a/bin/argbash b/bin/argbash index be1270c..c12495f 100755 --- a/bin/argbash +++ b/bin/argbash @@ -4,7 +4,6 @@ # SC2016: Expressions don't expand in single quotes, use double quotes for that. # SC2059 Don't use variables in the printf format string. - # DEFINE_SCRIPT_DIR() # ARG_POSITIONAL_SINGLE([input],[The input template file (pass '-' for stdin)]) # ARG_OPTIONAL_SINGLE([output],[o],[Name of the output file (pass '-' for stdout)],[-]) @@ -44,9 +43,9 @@ content() local _allowed=("none" "user-content" "all") _seeking="$1" for element in "${_allowed[@]}" do - test "$element" = "$_seeking" && echo "$element" && return 0 + test "${element}" = "${_seeking}" && echo "${element}" && return 0 done - die "Value '$_seeking' (of argument '$2') doesn't match the list of allowed values: 'none', 'user-content' and 'all'" 4 + die "Value '${_seeking}' (of argument '$2') doesn't match the list of allowed values: 'none', 'user-content' and 'all'" 4 } @@ -55,9 +54,9 @@ type() local _allowed=("bash-script" "posix-script" "manpage" "manpage-defs" "completion" "docopt") _seeking="$1" for element in "${_allowed[@]}" do - test "$element" = "$_seeking" && echo "$element" && return 0 + test "${element}" = "${_seeking}" && echo "${element}" && return 0 done - die "Value '$_seeking' (of argument '$2') doesn't match the list of allowed values: 'bash-script', 'posix-script', 'manpage', 'manpage-defs', 'completion' and 'docopt'" 4 + die "Value '${_seeking}' (of argument '$2') doesn't match the list of allowed values: 'bash-script', 'posix-script', 'manpage', 'manpage-defs', 'completion' and 'docopt'" 4 } @@ -65,7 +64,7 @@ begins_with_short_option() { local first_option all_short_options='oitcIhv' first_option="${1:0:1}" - test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 + test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0 } # THE DEFAULTS INITIALIZATION - POSITIONALS @@ -110,9 +109,9 @@ parse_commandline() while test $# -gt 0 do _key="$1" - case "$_key" in + case "${_key}" in -o|--output) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_output="$2" shift ;; @@ -129,13 +128,13 @@ parse_commandline() -i*) _arg_in_place="on" _next="${_key##-i}" - if test -n "$_next" -a "$_next" != "$_key" + if test -n "${_next}" -a "${_next}" != "${_key}" then - { begins_with_short_option "$_next" && shift && set -- "-i" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." + { begins_with_short_option "${_next}" && shift && set -- "-i" "-${_next}" "$@"; } || die "The short option '${_key}' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." fi ;; -t|--type) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_type="$(type "$2" "type")" || exit 1 shift ;; @@ -150,7 +149,7 @@ parse_commandline() test "${1:0:5}" = "--no-" && _arg_library="off" ;; --strip) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_strip="$(content "$2" "strip")" || exit 1 shift ;; @@ -168,13 +167,13 @@ parse_commandline() -c*) _arg_commented="on" _next="${_key##-c}" - if test -n "$_next" -a "$_next" != "$_key" + if test -n "${_next}" -a "${_next}" != "${_key}" then - { begins_with_short_option "$_next" && shift && set -- "-c" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." + { begins_with_short_option "${_next}" && shift && set -- "-c" "-${_next}" "$@"; } || die "The short option '${_key}' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." fi ;; -I|--search) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_search+=("$2") shift ;; @@ -185,7 +184,7 @@ parse_commandline() _arg_search+=("${_key##-I}") ;; --debug) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_debug="$2" shift ;; @@ -210,7 +209,7 @@ parse_commandline() ;; *) _last_positional="$1" - _positionals+=("$_last_positional") + _positionals+=("${_last_positional}") _positionals_count=$((_positionals_count + 1)) ;; esac @@ -222,8 +221,8 @@ parse_commandline() handle_passed_args_count() { local _required_args_string="'input'" - test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: $_required_args_string), but got only ${_positionals_count}." 1 - test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: $_required_args_string), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 + test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: ${_required_args_string}), but got only ${_positionals_count}." 1 + test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: ${_required_args_string}), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 } @@ -232,11 +231,11 @@ assign_positional_args() local _positional_name _shift_for=$1 _positional_names="_arg_input " - shift "$_shift_for" + shift "${_shift_for}" for _positional_name in ${_positional_names} do test $# -gt 0 || break - eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 + eval "${_positional_name}=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 shift done } @@ -265,12 +264,11 @@ cleanup() # $1: What (string) to pipe to autom4te run_autom4te() { - printf '%s\n' "$1" \ - | autom4te "${DEBUG[@]}" -l m4sugar -I "$m4dir" + printf '%s\n' "$1" | + autom4te "${DEBUG[@]}" -l m4sugar -I "${m4dir}" return $? } - # TODO: Refactor to associative arrays as soon as the argbash online is sufficiently reliable # We don't use associative arrays due to old bash compatibility reasons autom4te_error_messages=( @@ -291,13 +289,11 @@ interpret_error() # print the error, smart stuff may follow printf '%s\n' "$1" local eof_lineno line_mentioned - for idx in "${!autom4te_error_messages[@]}" - do - eof_lineno="$(printf "%s" "$1" | grep -e "${autom4te_error_messages[$idx]}" | sed -e 's/.*:\([0-9]\+\).*/\1/')" - if test -n "$eof_lineno" - then - line_mentioned="$(printf '%s' "$2" | sed -n "$eof_lineno"p | tr -d '\n\r')" - printf "${argbash_error_response_stem[$idx]}" "$((eof_lineno - $3))" "$line_mentioned" + for idx in "${!autom4te_error_messages[@]}"; do + eof_lineno="$(printf "%s" "$1" | grep -e "${autom4te_error_messages[${idx}]}" | sed -e 's/.*:\([0-9]\+\).*/\1/')" + if test -n "${eof_lineno}"; then + line_mentioned="$(printf '%s' "$2" | sed -n "${eof_lineno}"p | tr -d '\n\r')" + printf "${argbash_error_response_stem[${idx}]}" "$((eof_lineno - $3))" "${line_mentioned}" fi eof_lineno='' done @@ -307,55 +303,56 @@ interpret_error() # $2: The original intended output file define_file_metadata() { - local _defines='' _intended_destination="$ARGBASH_INTENDED_DESTINATION" _input_dirname _output_dirname - test -n "$_intended_destination" || _intended_destination="$2" + ARGBASH_INTENDED_DESTINATION="${ARGBASH_INTENDED_DESTINATION=}" + SPURIONS_OUTPUT_SUFFIX="${SPURIONS_OUTPUT_SUFFIX=}" + local _defines='' _intended_destination="${ARGBASH_INTENDED_DESTINATION}" _input_dirname _output_dirname + test -n "${_intended_destination}" || _intended_destination="$2" _input_dirname="$(dirname "$1")" test "$1" != '-' && _defines="${_defines}m4_define([INPUT_BASENAME], [[$(basename "$1")]])" - _defines="${_defines}m4_define([INPUT_ABS_DIRNAME], [[$(cd "$_input_dirname" && pwd)]])" + _defines="${_defines}m4_define([INPUT_ABS_DIRNAME], [[$(cd "${_input_dirname}" && pwd)]])" - _output_dirname="$(dirname "$_intended_destination")" - test "$_intended_destination" != '-' && _defines="${_defines}m4_define([OUTPUT_BASENAME], [[$(basename "$_intended_destination" "$SPURIONS_OUTPUT_SUFFIX")]])" - _defines="${_defines}m4_define([OUTPUT_ABS_DIRNAME], [[$(cd "$_output_dirname" && pwd)]])" - printf "%s" "$_defines" + _output_dirname="$(dirname "${_intended_destination}")" + test "${_intended_destination}" != '-' && _defines="${_defines}m4_define([OUTPUT_BASENAME], [[$(basename "${_intended_destination}" "${SPURIONS_OUTPUT_SUFFIX}")]])" + _defines="${_defines}m4_define([OUTPUT_ABS_DIRNAME], [[$(cd "${_output_dirname}" && pwd)]])" + printf "%s" "${_defines}" } - +# Yes both tests need to pass or we should throw out an error message +# shellcheck disable=2015 assert_m4_files_are_readable() { - local _argbash_lib="$m4dir/argbash-lib.m4" - test -d "$m4dir" && test -x "$m4dir" || die "The directory '$m4dir' with files needed by Argbash is not browsable. Check whether it exists and review it's permissions." - test -r "$_argbash_lib" && test -f "$_argbash_lib" || die "The '$_argbash_lib' file needed by Argbash is not readable. Check whether it exists and review it's permissions." - test -r "$output_m4" && test -f "$output_m4" || die "The '$output_m4' file needed by Argbash is not readable. Check whether it exists and review it's permissions." + local _argbash_lib="${m4dir}/argbash-lib.m4" + test -d "${m4dir}" && test -x "${m4dir}" || die "The directory '${m4dir}' with files needed by Argbash is not browsable. Check whether it exists and review it's permissions." + test -r "${_argbash_lib}" && test -f "${_argbash_lib}" || die "The '${_argbash_lib}' file needed by Argbash is not readable. Check whether it exists and review it's permissions." + test -r "${output_m4}" && test -f "${output_m4}" || die "The '${output_m4}' file needed by Argbash is not readable. Check whether it exists and review it's permissions." } - # The main function that generates the parsing script body # $1: The input file # $2: The output file # $3: The argument type do_stuff() { - local _pass_also="$_wrapped_defns" input prefix_len _ret - test "$_arg_commented" = on && _pass_also="${_pass_also}m4_define([COMMENT_OUTPUT])" + local _pass_also="${_wrapped_defns}" input prefix_len _ret + test "${_arg_commented}" = on && _pass_also="${_pass_also}m4_define([COMMENT_OUTPUT])" _pass_also="${_pass_also}m4_define([_OUTPUT_TYPE], [[$3]])" - _pass_also="${_pass_also}$(define_file_metadata "$_arg_input" "$2")" - input="$(printf '%s\n' "$_pass_also" | cat - "$m4dir/argbash-lib.m4" "$output_m4")" - prefix_len=$(printf '%s\n' "$input" | wc -l) - input="$(printf '%s\n' "$input" | cat - "$1")" - run_autom4te "$input" 2> "$discard" \ - | grep -v '^#\s*needed because of Argbash -->\s*$' \ - | grep -v '^#\s*<-- needed because of Argbash\s*$' + _pass_also="${_pass_also}$(define_file_metadata "${_arg_input}" "$2")" + input="$(printf '%s\n' "${_pass_also}" | cat - "${m4dir}/argbash-lib.m4" "${output_m4}")" + prefix_len=$(printf '%s\n' "${input}" | wc -l) + input="$(printf '%s\n' "${input}" | cat - "$1")" + run_autom4te "${input}" 2> "${discard}" | + grep -v '^#\s*needed because of Argbash -->\s*$' | + grep -v '^#\s*<-- needed because of Argbash\s*$' _ret=$? - if test $_ret != 0 - then + if test "${_ret}" != 0; then local errstr - errstr="$(run_autom4te "$input" 2>&1 > "$discard")" - interpret_error "$errstr" "$input" "$prefix_len" >&2 - echo "Error during autom4te run, aborting!" >&2; - exit $_ret; + errstr="$(run_autom4te "${input}" 2>&1 > "${discard}")" + interpret_error "${errstr}" "${input}" "${prefix_len}" >&2 + echo "Error during autom4te run, aborting!" >&2 + exit "${_ret}" fi - return "$_ret" + return "${_ret}" } # Fills content to variable _wrapped_defns --- where are scripts of given stems @@ -367,26 +364,36 @@ settle_wrapped_fname() # Based on http://stackoverflow.com/a/19772067/592892 local _srcfiles=() _file_found _found ext srcstem searchdir line stem="$2" while read -r line; do - _srcfiles+=("$line") - done < <(echo 'm4_changecom()m4_define([ARGBASH_WRAP])' "$(cat "$1")" \ - | autom4te -l m4sugar -t 'ARGBASH_WRAP:$1' 2> "$discard") + _srcfiles+=("${line}") + done < <(echo 'm4_changecom()m4_define([ARGBASH_WRAP])' "$(cat "$1")" | + autom4te -l m4sugar -t 'ARGBASH_WRAP:$1' 2> "${discard}") test "${#_srcfiles[@]}" -gt 0 || return - for srcstem in "${_srcfiles[@]}" - do + for srcstem in "${_srcfiles[@]}"; do _found=no - for searchdir in "${_arg_search[@]}" - do - test -f "$searchdir/$srcstem.m4" && { _found=yes; ext='.m4'; break; } - test -f "$searchdir/$srcstem.sh" && { _found=yes; ext='.sh'; break; } - test -f "$searchdir/$srcstem" && { _found=yes; ext=''; break; } + for searchdir in "${_arg_search[@]}"; do + test -f "${searchdir}/${srcstem}.m4" && { + _found=yes + ext='.m4' + break + } + test -f "${searchdir}/${srcstem}.sh" && { + _found=yes + ext='.sh' + break + } + test -f "${searchdir}/${srcstem}" && { + _found=yes + ext='' + break + } done # The last searchdir is a correct one - test $_found = yes || die "Couldn't find wrapped file of stem '$srcstem' in any of directories: ${_arg_search[*]}" 2 - _file_found="$searchdir/${srcstem}${ext}" - stem=${2:-$srcstem} - settle_wrapped_fname "$_file_found" "$stem" - _wrapped_defns="${_wrapped_defns}m4_define([_GROUP_OF_$srcstem], [[$stem]])m4_define([_SCRIPT_$srcstem], [[$_file_found]])" + test "${_found}" = yes || die "Couldn't find wrapped file of stem '${srcstem}' in any of directories: ${_arg_search[*]}" 2 + _file_found="${searchdir}/${srcstem}${ext}" + stem=${2:-${srcstem}} + settle_wrapped_fname "${_file_found}" "${stem}" + _wrapped_defns="${_wrapped_defns}m4_define([_GROUP_OF_${srcstem}], [[${stem}]])m4_define([_SCRIPT_${srcstem}], [[${_file_found}]])" done } @@ -399,111 +406,110 @@ get_parsing_code() { local _shfile _m4file _newerfile # Get the argument of INCLUDE_PARSING_CODE - _srcfile="$(echo 'm4_changecom()m4_define([INCLUDE_PARSING_CODE])' "$(cat "$infile")" \ - | autom4te -l m4sugar -t 'INCLUDE_PARSING_CODE:$1' 2> "$discard" \ - | tail -n 1)" - test -n "$_srcfile" || return 1 - _thatfile="$(dirname "$infile")/$_srcfile" - test -f "$_thatfile" && _shfile="$_thatfile" + _srcfile="$(echo 'm4_changecom()m4_define([INCLUDE_PARSING_CODE])' "$(cat "${infile}")" | + autom4te -l m4sugar -t 'INCLUDE_PARSING_CODE:$1' 2> "${discard}" | + tail -n 1)" + test -n "${_srcfile}" || return 1 + _thatfile="$(dirname "${infile}")/${_srcfile}" + test -f "${_thatfile}" && _shfile="${_thatfile}" # Take out everything after last dot (http://stackoverflow.com/questions/125281/how-do-i-remove-the-file-suffix-and-path-portion-from-a-path-string-in-bash) _thatfile="${_thatfile%.*}.m4" - test -f "$_thatfile" && _m4file="$_thatfile" + test -f "${_thatfile}" && _m4file="${_thatfile}" # if have neither of files - test -z "$_shfile" && test -z "$_m4file" && echo "Strange, we think that there was a source file '$_srcfile' that should be included, but we haven't found it in directory '$(dirname "$_thatfile")'" >&2 && return 1 + test -z "${_shfile}" && test -z "${_m4file}" && echo "Strange, we think that there was a source file '${_srcfile}' that should be included, but we haven't found it in directory '$(dirname "${_thatfile}")'" >&2 && return 1 # We have one file, but not the other one => decision of what to pick is easy. - test -z "$_shfile" && test -n "$_m4file" && echo "$_m4file" && return - test -n "$_shfile" && test -z "$_m4file" && echo "$_shfile" && return + test -z "${_shfile}" && test -n "${_m4file}" && echo "${_m4file}" && return + test -n "${_shfile}" && test -z "${_m4file}" && echo "${_shfile}" && return # We have both, so we pick up the newer one - _newerfile="$_shfile" - test "$_m4file" -nt "$_shfile" && _newerfile="$_m4file" - echo "$_newerfile" + _newerfile="${_shfile}" + test "${_m4file}" -nt "${_shfile}" && _newerfile="${_m4file}" + echo "${_newerfile}" } - # $1: The output file # $2: The output type string set_output_permission() { - if grep -q '\' <<< "$2" - then + if grep -q '\' <<< "$2"; then chmod a+x "$1" fi } - # MS Windows compatibility fix discard=/dev/null -test -e $discard || discard=NUL +test -e "${discard}" || discard=NUL set -o pipefail -infile="$_arg_input" +infile="${_arg_input}" trap cleanup EXIT # If we are reading from stdout, then create a temp file -if test "$infile" = '-' -then - if test "$_arg_in_place" = 'on' - then +if test "${infile}" = '-'; then + if test "${_arg_in_place}" = 'on'; then echo "Cannot use stdin input with --in-place option!" >&2 - exit 1; + exit 1 fi infile=temp_in_$$ - _files_to_clean+=("$infile") - cat > "$infile" + _files_to_clean+=("${infile}") + cat > "${infile}" fi -m4dir="$script_dir/../src" -test -n "$_arg_debug" && DEBUG=('-t' "$_arg_debug") - -output_m4="$m4dir/output-strip-none.m4" -test "$_arg_library" = "on" && { echo "The --library option is deprecated, use --strip user-content" next time >&2; _arg_strip="user-content"; } -if test "$_arg_strip" = "user-content" -then - output_m4="$m4dir/output-strip-user-content.m4" -elif test "$_arg_strip" = "all" -then - output_m4="$m4dir/output-strip-all.m4" +m4dir="${script_dir}/../src" +test -n "${_arg_debug}" && DEBUG=('-t' "${_arg_debug}") + +output_m4="${m4dir}/output-strip-none.m4" +test "${_arg_library}" = "on" && { + echo "The --library option is deprecated, use --strip user-content" next time >&2 + _arg_strip="user-content" +} +if test "${_arg_strip}" = "user-content"; then + output_m4="${m4dir}/output-strip-user-content.m4" +elif test "${_arg_strip}" = "all"; then + output_m4="${m4dir}/output-strip-all.m4" fi -test -f "$infile" || _PRINT_HELP=yes die "argument '$infile' is supposed to be a file!" 1 -if test "$_arg_in_place" = on -then - _arg_output="$infile" +test -f "${infile}" || _PRINT_HELP=yes die "argument '${infile}' is supposed to be a file!" 1 +if test "${_arg_in_place}" = on; then + _arg_output="${infile}" fi -test -n "$_arg_output" || { echo "The output can't be blank - it is not a legal filename!" >&2; exit 1; } -outfname="$_arg_output" -autom4te --version > "$discard" 2>&1 || { echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1; exit 1; } -_arg_search+=("$(dirname "$infile")") +test -n "${_arg_output}" || { + echo "The output can't be blank - it is not a legal filename!" >&2 + exit 1 +} +outfname="${_arg_output}" +autom4te --version > "${discard}" 2>&1 || { + echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 + exit 1 +} +_arg_search+=("$(dirname "${infile}")") _wrapped_defns="" # So let's settle the parsing code first. Hopefully we won't create a loop. parsing_code="$(get_parsing_code)" # Just if the original was m4, we replace .m4 with .sh -test -n "$parsing_code" && parsing_code_out="${parsing_code:0:-2}sh" -test "$_arg_library" = off && test -n "$parsing_code" && ($0 --strip user-content "$parsing_code" -o "$parsing_code_out") +test -n "${parsing_code}" && parsing_code_out="${parsing_code:0:-2}sh" +test "${_arg_library}" = off && test -n "${parsing_code}" && ($0 --strip user-content "${parsing_code}" -o "${parsing_code_out}") # We may use some of the wrapping stuff, so let's fill the _wrapped_defns -settle_wrapped_fname "$infile" +settle_wrapped_fname "${infile}" assert_m4_files_are_readable -output="$(do_stuff "$infile" "$outfname" "$_arg_type")" || die "" "$?" -if test "$_arg_check_typos" = on -then +output="$(do_stuff "${infile}" "${outfname}" "${_arg_type}")" || die "" "$?" +if test "${_arg_check_typos}" = on; then # match against suspicious, then inverse match against correct stuff: # #\(allowed\|another allowed\|...\) end of line> # Then, extract all matches (assumed to be alnum chars + '_') from grep and put them in the error msg. - grep_output="$(printf "%s" "$output" | grep '^#\s*\(ARG_\|ARGBASH\)' | grep -v '^#\s*\(ARGBASH_SET_INDENT\|ARG_OPTIONAL_SINGLE\|ARG_VERSION\|ARG_VERSION_AUTO\|ARG_HELP\|ARG_OPTIONAL_INCREMENTAL\|ARG_OPTIONAL_REPEATED\|ARG_VERBOSE\|ARG_OPTIONAL_BOOLEAN\|ARG_OPTIONAL_ACTION\|ARG_POSITIONAL_SINGLE\|ARG_POSITIONAL_INF\|ARG_POSITIONAL_MULTI\|ARG_POSITIONAL_DOUBLEDASH\|ARG_OPTION_STACKING\|ARG_RESTRICT_VALUES\|ARG_DEFAULTS_POS\|ARG_LEFTOVERS\|ARGBASH_WRAP\|INCLUDE_PARSING_CODE\|DEFINE_LOAD_LIBRARY\|DEFINE_SCRIPT_DIR\|DEFINE_SCRIPT_DIR_GNU\|ARGBASH_SET_DELIM\|ARGBASH_GO\|ARGBASH_PREPARE\|ARG_TYPE_GROUP\|ARG_TYPE_GROUP_SET\|ARG_USE_ENV\|ARG_USE_PROGRAM\)\s*\((\|$\)' | sed -e 's/#\s*\([[:alnum:]_]*\).*/\1 /' | tr -d '\n\r')" - test -n "$grep_output" && die "Your script contains possible misspelled Argbash macros: $grep_output" 1 + grep_output="$(printf "%s" "${output}" | grep '^#\s*\(ARG_\|ARGBASH\)' | grep -v '^#\s*\(ARGBASH_SET_INDENT\|ARG_OPTIONAL_SINGLE\|ARG_VERSION\|ARG_VERSION_AUTO\|ARG_HELP\|ARG_OPTIONAL_INCREMENTAL\|ARG_OPTIONAL_REPEATED\|ARG_VERBOSE\|ARG_OPTIONAL_BOOLEAN\|ARG_OPTIONAL_ACTION\|ARG_POSITIONAL_SINGLE\|ARG_POSITIONAL_INF\|ARG_POSITIONAL_MULTI\|ARG_POSITIONAL_DOUBLEDASH\|ARG_OPTION_STACKING\|ARG_RESTRICT_VALUES\|ARG_DEFAULTS_POS\|ARG_LEFTOVERS\|ARGBASH_WRAP\|INCLUDE_PARSING_CODE\|DEFINE_LOAD_LIBRARY\|DEFINE_SCRIPT_DIR\|DEFINE_SCRIPT_DIR_GNU\|ARGBASH_SET_DELIM\|ARGBASH_GO\|ARGBASH_PREPARE\|ARG_TYPE_GROUP\|ARG_TYPE_GROUP_SET\|ARG_USE_ENV\|ARG_USE_PROGRAM\)\s*\((\|$\)' | sed -e 's/#\s*\([[:alnum:]_]*\).*/\1 /' | tr -d '\n\r')" + test -n "${grep_output}" && die "Your script contains possible misspelled Argbash macros: ${grep_output}" 1 fi -if test "$outfname" != '-' -then - printf "%s\\n" "$output" > "$outfname" - set_output_permission "$outfname" "$_arg_type" +if test "${outfname}" != '-'; then + printf '%s\n' "${output}" > "${outfname}" + set_output_permission "${outfname}" "${_arg_type}" else - printf "%s\\n" "$output" + printf '%s\n' "${output}" fi # # ] <-- needed because of Argbash diff --git a/bin/argbash-1to2 b/bin/argbash-1to2 index 7aa8545..66141e2 100755 --- a/bin/argbash-1to2 +++ b/bin/argbash-1to2 @@ -6,7 +6,7 @@ version=2.10.0 # ARG_POSITIONAL_INF([input],[The input file to transform],[1]) # ARG_OPTIONAL_SINGLE([output],[o],[Name of the output file (pass '-' for stdout and empty string for the same as input file)],[""]) -# ARG_VERSION([echo "argbash-1to2 v$version"]) +# ARG_VERSION([echo "argbash-1to2 v${version}"]) # ARG_HELP([Convert a template for argbash>=1,<2 to argbash>=2,<3]) # ARGBASH_GO() @@ -29,7 +29,7 @@ begins_with_short_option() { local first_option all_short_options='ovh' first_option="${1:0:1}" - test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 + test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0 } # THE DEFAULTS INITIALIZATION - POSITIONALS @@ -56,9 +56,9 @@ parse_commandline() while test $# -gt 0 do _key="$1" - case "$_key" in + case "${_key}" in -o|--output) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_output="$2" shift ;; @@ -69,11 +69,11 @@ parse_commandline() _arg_output="${_key##-o}" ;; -v|--version) - echo "argbash-1to2 v$version" + echo "argbash-1to2 v${version}" exit 0 ;; -v*) - echo "argbash-1to2 v$version" + echo "argbash-1to2 v${version}" exit 0 ;; -h|--help) @@ -86,7 +86,7 @@ parse_commandline() ;; *) _last_positional="$1" - _positionals+=("$_last_positional") + _positionals+=("${_last_positional}") _positionals_count=$((_positionals_count + 1)) ;; esac @@ -98,7 +98,7 @@ parse_commandline() handle_passed_args_count() { local _required_args_string="'input'" - test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require at least 1 (namely: $_required_args_string), but got only ${_positionals_count}." 1 + test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require at least 1 (namely: ${_required_args_string}), but got only ${_positionals_count}." 1 } @@ -109,14 +109,14 @@ assign_positional_args() _our_args=$((${#_positionals[@]} - 1)) for ((ii = 0; ii < _our_args; ii++)) do - _positional_names="$_positional_names _arg_input[$((ii + 1))]" + _positional_names="${_positional_names} _arg_input[$((ii + 1))]" done - shift "$_shift_for" + shift "${_shift_for}" for _positional_name in ${_positional_names} do test $# -gt 0 || break - eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 + eval "${_positional_name}=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 shift done } @@ -138,36 +138,37 @@ cleanup() test "${#_files_to_clean[*]}" != 0 && rm -f "${_files_to_clean[@]}" } -do_stuff () +do_stuff() { # SCRIPT_DIR is likely also a default, but maybe not - it may have been set explicitly - grep -q '\${\?SCRIPT_DIR' -- "$infname" && echo "You probably use a variable 'SCRIPT_DIR' in your script. It may be that you should rename it to 'script_dir', but this is not certain :-(" >&2 + grep -q '\${\?SCRIPT_DIR' -- "${infname}" && echo "You probably use a variable 'SCRIPT_DIR' in your script. It may be that you should rename it to 'script_dir', but this is not certain :-(" >&2 # We match $_ARG_FOO as well as ${ARG_FOO... # and _ARGS_FOO - sed 's/\(\${\?_ARGS\?_\w\+\)/\L\1\l/g' "$infname" + sed 's/\(\${\?_ARGS\?_\w\+\)/\L\1\l/g' "${infname}" } -outfname="$_arg_output" -test "${#infname[@]}" -gt 1 && test -n "$outfname" && die "You have specified more than one (${#infname[@]}) input filenames, so you probably want to modify the corresponding files in-place. In order to do so, you can't specify an output filename, even '-' does make no sense (currently: '$outfname')" +outfname="${_arg_output}" +test "${#infname[@]}" -gt 1 && test -n "${outfname}" && die "You have specified more than one (${#infname[@]}) input filenames, so you probably want to modify the corresponding files in-place. In order to do so, you can't specify an output filename, even '-' does make no sense (currently: '${outfname}')" trap cleanup EXIT -for infname in "${_arg_input[@]}" -do - test -f "$infname" || { echo "The input parameter has to be a file (got: '$infname')" >&2; exit 1; } - - test -n "$_arg_output" || outfname="$infname" - if test "$outfname" = '-' - then +for infname in "${_arg_input[@]}"; do + test -f "${infname}" || { + echo "The input parameter has to be a file (got: '${infname}')" >&2 + exit 1 + } + + test -n "${_arg_output}" || outfname="${infname}" + if test "${outfname}" = '-'; then do_stuff else # vvv This should catch most of the cases when we want to overwrite the source file # vvv and we don't want to leave a file (not even an empty one) when something goes wrong. temp_outfile="temp_$$" - _files_to_clean+=("$temp_outfile") - do_stuff > "$temp_outfile" - mv "$temp_outfile" "$outfname" + _files_to_clean+=("${temp_outfile}") + do_stuff > "${temp_outfile}" + mv "${temp_outfile}" "${outfname}" # So we don't make .m4 scripts executable - chmod --reference "$infname" "$outfname" + chmod --reference "${infname}" "${outfname}" fi done diff --git a/bin/argbash-init b/bin/argbash-init index 9a206c0..74e10eb 100755 --- a/bin/argbash-init +++ b/bin/argbash-init @@ -14,7 +14,7 @@ version=2.10.0 # ARG_OPTIONAL_REPEATED([wrap],[],[What script(s) to wrap]) # ARG_OPTIONAL_SINGLE([mode],[m],[The slider between feature-rich and simple script.],[default]) # ARG_TYPE_GROUP_SET([mode],[MODE],[mode],[default,full,minimal]) -# ARG_VERSION([echo "argbash-init v$version"]) +# ARG_VERSION([echo "argbash-init v${version}"]) # ARG_HELP([Make a template for scripts.]) # ARGBASH_GO() @@ -39,9 +39,9 @@ mode() local _allowed=("default" "full" "minimal") _seeking="$1" for element in "${_allowed[@]}" do - test "$element" = "$_seeking" && echo "$element" && return 0 + test "${element}" = "${_seeking}" && echo "${element}" && return 0 done - die "Value '$_seeking' (of argument '$2') doesn't match the list of allowed values: 'default', 'full' and 'minimal'" 4 + die "Value '${_seeking}' (of argument '$2') doesn't match the list of allowed values: 'default', 'full' and 'minimal'" 4 } @@ -49,7 +49,7 @@ begins_with_short_option() { local first_option all_short_options='smvh' first_option="${1:0:1}" - test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 + test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0 } # THE DEFAULTS INITIALIZATION - POSITIONALS @@ -88,16 +88,16 @@ parse_commandline() while test $# -gt 0 do _key="$1" - case "$_key" in + case "${_key}" in -s|--separate) _arg_separate=$((_arg_separate + 1)) ;; -s*) _arg_separate=$((_arg_separate + 1)) _next="${_key##-s}" - if test -n "$_next" -a "$_next" != "$_key" + if test -n "${_next}" -a "${_next}" != "${_key}" then - { begins_with_short_option "$_next" && shift && set -- "-s" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." + { begins_with_short_option "${_next}" && shift && set -- "-s" "-${_next}" "$@"; } || die "The short option '${_key}' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." fi ;; --no-hints|--hints) @@ -105,7 +105,7 @@ parse_commandline() test "${1:0:5}" = "--no-" && _arg_hints="off" ;; --pos) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_pos+=("$2") shift ;; @@ -113,7 +113,7 @@ parse_commandline() _arg_pos+=("${_key##--pos=}") ;; --opt) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_opt+=("$2") shift ;; @@ -121,7 +121,7 @@ parse_commandline() _arg_opt+=("${_key##--opt=}") ;; --opt-bool) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_opt_bool+=("$2") shift ;; @@ -129,7 +129,7 @@ parse_commandline() _arg_opt_bool+=("${_key##--opt-bool=}") ;; --wrap) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_wrap+=("$2") shift ;; @@ -137,7 +137,7 @@ parse_commandline() _arg_wrap+=("${_key##--wrap=}") ;; -m|--mode) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_mode="$(mode "$2" "mode")" || exit 1 shift ;; @@ -148,11 +148,11 @@ parse_commandline() _arg_mode="$(mode "${_key##-m}" "mode")" || exit 1 ;; -v|--version) - echo "argbash-init v$version" + echo "argbash-init v${version}" exit 0 ;; -v*) - echo "argbash-init v$version" + echo "argbash-init v${version}" exit 0 ;; -h|--help) @@ -165,7 +165,7 @@ parse_commandline() ;; *) _last_positional="$1" - _positionals+=("$_last_positional") + _positionals+=("${_last_positional}") _positionals_count=$((_positionals_count + 1)) ;; esac @@ -185,11 +185,11 @@ assign_positional_args() local _positional_name _shift_for=$1 _positional_names="_arg_output " - shift "$_shift_for" + shift "${_shift_for}" for _positional_name in ${_positional_names} do test $# -gt 0 || break - eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 + eval "${_positional_name}=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 shift done } @@ -205,132 +205,109 @@ assign_positional_args 1 "${_positionals[@]}" ### END OF CODE GENERATED BY Argbash (sortof) ### ]) # [ <-- needed because of Argbash - _variables=() HAVE_POSITIONAL_ARG=no - -# This should be in sync with _translit_var in stuff.m4 -_translit_var() +# This should be in sync with _translate_var in stuff.m4 +_translate_var() { - printf "\$_arg_%s" "$1" | tr '[:upper:]' '[:lower:]' | tr '-' '_' + printf '${_arg_%s}' "$1" | tr '[:upper:]' '[:lower:]' | tr '-' '_' } - optional_argument_without_hints() { echo "# ARG_OPTIONAL_SINGLE([$1])" } - optional_argument_with_hints() { echo "# ARG_OPTIONAL_SINGLE([$1], [], [], [])" } - optional_argument() { "${FUNCNAME[0]}_$2" "$1" - _variables+=("printf 'Value of --%s: %s\\n' '$1' \"$(_translit_var "$1")\"") + _variables+=("printf 'Value of --%s: %s\\n' '$1' \"$(_translate_var "$1")\"") } - boolean_argument_with_hints() { echo "# ARG_OPTIONAL_BOOLEAN([$1], [], [], [])" } - boolean_argument_without_hints() { echo "# ARG_OPTIONAL_BOOLEAN([$1])" } - boolean_argument() { "${FUNCNAME[0]}_$2" "$1" - _variables+=("printf \"'%s' is %s\\\\n\" '$1' \"$(_translit_var "$1")\"") + _variables+=("printf \"'%s' is %s\\\\n\" '$1' \"$(_translate_var "$1")\"") } - positional_argument_with_hints() { echo "# ARG_POSITIONAL_SINGLE([$1], [], [&2" - elif test "$1" = "standalone_lib" - then + if test "$1" = "lib"; then + echo "echo \"This is just a parsing library template, not the library - pass the parent script '${outfname}' to 'argbash' to fix this.\" >&2" + elif test "$1" = "standalone_lib"; then echo "echo \"This is just a parsing library template, not the library - pass this file to 'argbash' to fix this.\" >&2" else echo "echo \"This is just a script template, not the script (yet) - pass it to 'argbash' to fix this.\" >&2" fi - echo "exit 11 #)Created by argbash-init v$version" + echo "exit 11 #)Created by argbash-init v${version}" } - do_args() { local _mode="without_hints" - if test "$_arg_hints" = on - then + if test "${_arg_hints}" = on; then echo "# Rearrange the order of options below according to what you would like to see in the help message." _mode="with_hints" fi - for name in "${_arg_opt[@]}" - do optional_argument "$name" "$_mode"; done - for name in "${_arg_opt_bool[@]}" - do boolean_argument "$name" "$_mode"; done - for name in "${_arg_pos[@]}" - do positional_argument "$name" "$_mode"; done + for name in "${_arg_opt[@]}"; do optional_argument "${name}" "${_mode}"; done + for name in "${_arg_opt_bool[@]}"; do boolean_argument "${name}" "${_mode}"; done + for name in "${_arg_pos[@]}"; do positional_argument "${name}" "${_mode}"; done } - do_args_footer() { - if test "$_arg_mode" = "full" - then + if test "${_arg_mode}" = "full"; then echo '# ARGBASH_SET_DELIM([ =])' echo '# ARG_OPTION_STACKING([getopt])' echo '# ARG_RESTRICT_VALUES([no-local-options])' - elif test "$_arg_mode" = "minimal" - then + elif test "${_arg_mode}" = "minimal"; then echo '# ARGBASH_SET_DELIM([ ])' echo '# ARG_OPTION_STACKING([none])' echo '# ARG_RESTRICT_VALUES([none])' fi - test "$HAVE_POSITIONAL_ARG" = yes && echo '# ARG_DEFAULTS_POS' + test "${HAVE_POSITIONAL_ARG}" = yes && echo '# ARG_DEFAULTS_POS' echo "# ARG_HELP([])" echo "# ARGBASH_GO" } - do_script_assisted() { do_header script @@ -342,7 +319,6 @@ do_script_assisted() do_body_protected } - # # $1: The filename of the parsing library do_script_separate() @@ -350,25 +326,23 @@ do_script_separate() do_header script parse_fname=${parse_fname_stem}.sh - echo "# Run 'argbash --strip user-content \"$1\" -o \"$parse_fname\"' to generate the '$parse_fname' file." - echo "# If you need to make changes later, edit '$parse_fname' directly, and regenerate by running" - echo "# 'argbash --strip user-content \"$parse_fname\" -o \"$parse_fname\"'" + echo "# Run 'argbash --strip user-content \"$1\" -o \"${parse_fname}\"' to generate the '${parse_fname}' file." + echo "# If you need to make changes later, edit '${parse_fname}' directly, and regenerate by running" + echo "# 'argbash --strip user-content \"${parse_fname}\" -o \"${parse_fname}\"'" echo 'script_dir="$(cd "$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")" && pwd)"' - echo '. "${script_dir}/'"$(basename "$parse_fname")\" || { echo \"Couldn't find '$(basename "$parse_fname")' parsing library in the '"'$script_dir'"' directory\"; exit 1; }" + echo '. "${script_dir}/'"$(basename "${parse_fname}")\" || { echo \"Couldn't find '$(basename "${parse_fname}")' parsing library in the '"'${script_dir}'"' directory\"; exit 1; }" echo do_body } - do_body() { echo "# vvv PLACE YOUR CODE HERE vvv" if test "${#_variables[@]}" -gt 0; then echo "# For example:" - for stat in "${_variables[@]}" - do - echo "$stat" + for stat in "${_variables[@]}"; do + echo "${stat}" done echo else @@ -379,7 +353,6 @@ do_body() echo "# ^^^ TERMINATE YOUR CODE BEFORE THE BOTTOM ARGBASH MARKER ^^^" } - do_body_protected() { echo @@ -390,45 +363,41 @@ do_body_protected() echo "# ] <-- needed because of Argbash" } - do_stuff() { do_header "$1" do_args do_args_footer - test "$_arg_separate" = 0 && do_body_protected + test "${_arg_separate}" = 0 && do_body_protected } -outfname="$_arg_output" +outfname="${_arg_output}" # we canonicize the empty string input to output filename to the dash -test -n "$outfname" || outfname='-' -test "$outfname" = "-" -a "$_arg_separate" -gt 0 && die "If you want to separate parsing and script body, you have to specify the outname, stdout doesn't work." +test -n "${outfname}" || outfname='-' +test "${outfname}" = "-" -a "${_arg_separate}" -gt 0 && die "If you want to separate parsing and script body, you have to specify the outname, stdout doesn't work." -if test "$outfname" = '-' -then +if test "${outfname}" = '-'; then do_stuff 'script' else - if test "$_arg_separate" = 0 - then - do_stuff 'script' > "$outfname" + if test "${_arg_separate}" = 0; then + do_stuff 'script' > "${outfname}" else parse_fname_stem="$(echo "${outfname}" | sed -e 's/\.\(sh\|m4\)$//')-parsing" # IMPORTANT NOTION: # do_stuff has to be called FIRST, because it sets the _variables array content as its side-effect - if test "$_arg_separate" = 1 - then + if test "${_arg_separate}" = 1; then do_stuff 'lib' > "${parse_fname_stem}.m4" - do_script_assisted > "$outfname" + do_script_assisted > "${outfname}" else - test "$_arg_separate" = 2 || echo "The greatest separation value is 2, got $_arg_separate" >&2 + test "${_arg_separate}" = 2 || echo "The greatest separation value is 2, got ${_arg_separate}" >&2 parsing_library_file="${parse_fname_stem}.m4" - do_stuff 'standalone_lib' > "${parsing_library_file}" - do_script_separate "$parsing_library_file" > "$outfname" + do_stuff 'standalone_lib' > "${parsing_library_file}" + do_script_separate "${parsing_library_file}" > "${outfname}" fi fi - chmod a+x "$outfname" + chmod a+x "${outfname}" fi # diff --git a/resources/Makefile b/resources/Makefile index 8c8f853..f8420b9 100644 --- a/resources/Makefile +++ b/resources/Makefile @@ -2,8 +2,9 @@ NUL = # SC2015: Note that A && B || C is not if-then-else. C may run when A is true. SHELLCHECK_EXCLUDE_CHECKS_ARGUMENT = -e 2015 +SHELLCHECK_OPTIONAL_CHECKS_ARGUMENT = --enable=all -SHELLCHECK = $(shell shellcheck -V > /dev/null && echo "shellcheck -x $(SHELLCHECK_EXCLUDE_CHECKS_ARGUMENT)") +SHELLCHECK = $(shell shellcheck -V > /dev/null && echo "shellcheck -x $(SHELLCHECK_EXCLUDE_CHECKS_ARGUMENT) $(SHELLCHECK_OPTIONAL_CHECKS_ARGUMENT)") DEFINE_SCRIPT_DIR_FORM ?= DEFINE_SCRIPT_DIR$(shell readlink -e /dev/null > /dev/null && echo "_GNU") diff --git a/resources/examples/minimal-raw.m4 b/resources/examples/minimal-raw.m4 index 43f8014..e02ce38 100755 --- a/resources/examples/minimal-raw.m4 +++ b/resources/examples/minimal-raw.m4 @@ -14,9 +14,9 @@ exit 11 #)Created by argbash-init v2.10.0 # vvv PLACE YOUR CODE HERE vvv # For example: -printf 'Value of --%s: %s\n' 'option' "$_arg_option" -printf "'%s' is %s\\n" 'print' "$_arg_print" -printf "Value of '%s': %s\\n" 'positional-arg' "$_arg_positional_arg" +printf 'Value of --%s: %s\n' 'option' "${_arg_option}" +printf "'%s' is %s\\n" 'print' "${_arg_print}" +printf "Value of '%s': %s\\n" 'positional-arg' "${_arg_positional_arg}" # ^^^ TERMINATE YOUR CODE BEFORE THE BOTTOM ARGBASH MARKER ^^^ diff --git a/resources/examples/minimal.m4 b/resources/examples/minimal.m4 index 2326c48..066e9b7 100644 --- a/resources/examples/minimal.m4 +++ b/resources/examples/minimal.m4 @@ -16,10 +16,9 @@ exit 11 #)Created by argbash-init v2.10.0 # vvv PLACE YOUR CODE HERE vvv # For example: -if [ "$_arg_print" = on ] -then - echo "Positional arg value: '$_arg_positional_arg'" - echo "Optional arg '--option' value: '$_arg_option'" +if [ "${_arg_print}" = on ]; then + echo "Positional arg value: '${_arg_positional_arg}'" + echo "Optional arg '--option' value: '${_arg_option}'" else echo "Not telling anything, print not requested" fi diff --git a/resources/examples/simple-parsing.m4 b/resources/examples/simple-parsing.m4 index 884a120..5d4705b 100644 --- a/resources/examples/simple-parsing.m4 +++ b/resources/examples/simple-parsing.m4 @@ -1,5 +1,5 @@ #!/bin/bash - +#foo # ARG_POSITIONAL_SINGLE([filename]) # ARG_OPTIONAL_SINGLE([unit], u, [What unit we accept (b for bytes, k for kibibytes, M for mebibytes)], b) # ARG_VERSION([echo $0 v0.1]) diff --git a/resources/examples/simple-parsing.sh b/resources/examples/simple-parsing.sh index f41af7f..6b2bb79 100755 --- a/resources/examples/simple-parsing.sh +++ b/resources/examples/simple-parsing.sh @@ -1,5 +1,5 @@ #!/bin/bash - +#foo # ARG_POSITIONAL_SINGLE([filename]) # ARG_OPTIONAL_SINGLE([unit],[u],[What unit we accept (b for bytes, k for kibibytes, M for mebibytes)],[b]) # ARG_VERSION([echo $0 v0.1]) @@ -26,7 +26,7 @@ begins_with_short_option() { local first_option all_short_options='uvh' first_option="${1:0:1}" - test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 + test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0 } # THE DEFAULTS INITIALIZATION - POSITIONALS @@ -52,9 +52,9 @@ parse_commandline() while test $# -gt 0 do _key="$1" - case "$_key" in + case "${_key}" in -u|--unit) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_unit="$2" shift ;; @@ -86,7 +86,7 @@ parse_commandline() ;; *) _last_positional="$1" - _positionals+=("$_last_positional") + _positionals+=("${_last_positional}") _positionals_count=$((_positionals_count + 1)) ;; esac @@ -98,8 +98,8 @@ parse_commandline() handle_passed_args_count() { local _required_args_string="'filename'" - test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: $_required_args_string), but got only ${_positionals_count}." 1 - test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: $_required_args_string), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 + test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: ${_required_args_string}), but got only ${_positionals_count}." 1 + test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: ${_required_args_string}), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 } @@ -108,11 +108,11 @@ assign_positional_args() local _positional_name _shift_for=$1 _positional_names="_arg_filename " - shift "$_shift_for" + shift "${_shift_for}" for _positional_name in ${_positional_names} do test $# -gt 0 || break - eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 + eval "${_positional_name}=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 shift done } @@ -124,3 +124,5 @@ assign_positional_args 1 "${_positionals[@]}" # OTHER STUFF GENERATED BY Argbash ### END OF CODE GENERATED BY Argbash (sortof) ### ]) +# [ <-- needed because of Argbash +# ] <-- needed because of Argbash diff --git a/resources/examples/simple-standalone.m4 b/resources/examples/simple-standalone.m4 index 5e8e9dd..07b0db9 100644 --- a/resources/examples/simple-standalone.m4 +++ b/resources/examples/simple-standalone.m4 @@ -1,9 +1,9 @@ #!/bin/bash - +#foo # ARG_POSITIONAL_SINGLE([filename]) # ARG_OPTIONAL_SINGLE([unit], u, [What unit we accept (b for bytes, k for kilobytes, M for megabytes)], b) -# ARG_VERSION([echo $0 v0.1]) +# ARG_VERSION([echo "$0 v0.1"]) # ARG_OPTIONAL_BOOLEAN(verbose) -# ARG_HELP +# ARG_HELP() # ARGBASH_SET_INDENT([ ]) # ARGBASH_GO diff --git a/resources/examples/simple-standalone.sh b/resources/examples/simple-standalone.sh index 1910221..a01a134 100755 --- a/resources/examples/simple-standalone.sh +++ b/resources/examples/simple-standalone.sh @@ -1,80 +1,127 @@ #!/bin/bash - +#foo # ARG_POSITIONAL_SINGLE([filename]) # ARG_OPTIONAL_SINGLE([unit],[u],[What unit we accept (b for bytes, k for kilobytes, M for megabytes)],[b]) -# ARG_VERSION([echo $0 v0.1]) +# ARG_VERSION([echo "$0 v0.1"]) # ARG_OPTIONAL_BOOLEAN([verbose]) -# ARG_HELP() +# ARG_HELP([]) # ARGBASH_SET_INDENT([ ]) # ARGBASH_GO() # needed because of Argbash --> m4_ignore([ -### START OF CODE GENERATED BY Argbash v2.0.0 one line above ### +### START OF CODE GENERATED BY Argbash v2.10.0 one line above ### # Argbash is a bash code generator used to get arguments parsing right. -# Argbash is FREE SOFTWARE, know your rights: https://github.com/matejak/argbash +# Argbash is FREE SOFTWARE, see https://argbash.io for more info + die() { - local _ret=$2 - test -n "$_ret" || _ret=1 - test "$_PRINT_HELP" = yes && print_help >&2 + local _ret="${2:-1}" + test "${_PRINT_HELP:-no}" = yes && print_help >&2 echo "$1" >&2 - exit ${_ret} + exit "${_ret}" +} + + +begins_with_short_option() +{ + local first_option all_short_options='uvh' + first_option="${1:0:1}" + test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0 } -# THE DEFAULTS INITIALIZATION --- POSITIONALS -# THE DEFAULTS INITIALIZATION --- OPTIONALS +# THE DEFAULTS INITIALIZATION - POSITIONALS +_positionals=() +# THE DEFAULTS INITIALIZATION - OPTIONALS _arg_unit="b" -_arg_verbose=off +_arg_verbose="off" + -# THE PRINT HELP FUNCION -print_help () +print_help() { printf 'Usage: %s [-u|--unit ] [-v|--version] [--(no-)verbose] [-h|--help] \n' "$0" - printf "\t-u,--unit: What unit we accept (b for bytes, k for kilobytes, M for megabytes) (default: '%s')\n" "${_arg_unit}" - printf "\t-v,--version: Prints version\n" - printf "\t-h,--help: Prints help\n" + printf '\t%s\n' "-u, --unit: What unit we accept (b for bytes, k for kilobytes, M for megabytes) (default: 'b')" + printf '\t%s\n' "-v, --version: Prints version" + printf '\t%s\n' "-h, --help: Prints help" +} + + +parse_commandline() +{ + _positionals_count=0 + while test $# -gt 0 + do + _key="$1" + case "${_key}" in + -u|--unit) + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 + _arg_unit="$2" + shift + ;; + --unit=*) + _arg_unit="${_key##--unit=}" + ;; + -u*) + _arg_unit="${_key##-u}" + ;; + -v|--version) + echo "$0 v0.1" + exit 0 + ;; + -v*) + echo "$0 v0.1" + exit 0 + ;; + --no-verbose|--verbose) + _arg_verbose="on" + test "${1:0:5}" = "--no-" && _arg_verbose="off" + ;; + -h|--help) + print_help + exit 0 + ;; + -h*) + print_help + exit 0 + ;; + *) + _last_positional="$1" + _positionals+=("${_last_positional}") + _positionals_count=$((_positionals_count + 1)) + ;; + esac + shift + done +} + + +handle_passed_args_count() +{ + local _required_args_string="'filename'" + test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: ${_required_args_string}), but got only ${_positionals_count}." 1 + test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: ${_required_args_string}), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 +} + + +assign_positional_args() +{ + local _positional_name _shift_for=$1 + _positional_names="_arg_filename " + + shift "${_shift_for}" + for _positional_name in ${_positional_names} + do + test $# -gt 0 || break + eval "${_positional_name}=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 + shift + done } -# THE PARSING ITSELF -while test $# -gt 0 -do - _key="$1" - case "$_key" in - -u|--unit) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 - _arg_unit="$2" - - shift - ;; - -v|--version) - echo $0 v0.1 - exit 0 - ;; - --no-verbose|--verbose) - _arg_verbose="on" - - test "${1:0:5}" = "--no-" && _arg_verbose="off" - ;; - -h|--help) - print_help - exit 0 - ;; - *) - _positionals+=("$1") - ;; - - esac - shift -done - -_positional_names=('_arg_filename' ) -test ${#_positionals[@]} -lt 1 && _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1, but got only ${#_positionals[@]}." 1 -test ${#_positionals[@]} -gt 1 && _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1, but got ${#_positionals[@]} (the last one was: '${_positionals[*]: -1}')." 1 -for (( ii = 0; ii < ${#_positionals[@]}; ii++)) -do - eval "${_positional_names[ii]}=\${_positionals[ii]}" || die "Error during argument parsing, possibly an Argbash bug." 1 -done +parse_commandline "$@" +handle_passed_args_count +assign_positional_args 1 "${_positionals[@]}" # OTHER STUFF GENERATED BY Argbash ### END OF CODE GENERATED BY Argbash (sortof) ### ]) +# [ <-- needed because of Argbash +# ] <-- needed because of Argbash diff --git a/resources/examples/simple-wrapper.m4 b/resources/examples/simple-wrapper.m4 index 442d188..115760f 100644 --- a/resources/examples/simple-wrapper.m4 +++ b/resources/examples/simple-wrapper.m4 @@ -10,16 +10,17 @@ # [ <-- needed because of Argbash -script="$script_dir/simple.sh" -test -f "$script" || { echo "Missing the wrapped script, was expecting it next to me, in '$script_dir'."; exit 1; } +script="${script_dir}/simple.sh" +test -f "${script}" || { + echo "Missing the wrapped script, was expecting it next to me, in '${script_dir}'." + exit 1 +} -for directory in "${_arg_directory[@]}" -do - test -d "$directory" || die "We expected a directory, got '$directory', bailing out." - printf "Contents of '%s' matching '%s':\n" "$directory" "$_arg_glob" - for file in "$directory"/$_arg_glob - do - test -f "$file" && printf "\t%s: %s\n" "$(basename "$file")" "$("$script" "${_args_simple_parsing_opt[@]}" "$file")" +for directory in "${_arg_directory[@]}"; do + test -d "${directory}" || die "We expected a directory, got '${directory}', bailing out." + printf "Contents of '%s' matching '%s':\n" "${directory}" "${_arg_glob}" + for file in "${directory}"/${_arg_glob}; do + test -f "${file}" && printf "\t%s: %s\n" "$(basename "${file}")" "$("${script}" "${_args_simple_parsing_opt[@]}" "${file}")" done done diff --git a/resources/examples/simple-wrapper.sh b/resources/examples/simple-wrapper.sh index e423a0b..3e2079c 100755 --- a/resources/examples/simple-wrapper.sh +++ b/resources/examples/simple-wrapper.sh @@ -26,7 +26,7 @@ begins_with_short_option() { local first_option all_short_options='uh' first_option="${1:0:1}" - test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 + test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0 } # THE DEFAULTS INITIALIZATION - POSITIONALS @@ -55,9 +55,9 @@ parse_commandline() while test $# -gt 0 do _key="$1" - case "$_key" in + case "${_key}" in --glob) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_glob="$2" shift ;; @@ -65,18 +65,18 @@ parse_commandline() _arg_glob="${_key##--glob=}" ;; -u|--unit) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 _arg_unit="$2" _args_simple_parsing_opt+=("${_key}" "$2") shift ;; --unit=*) _arg_unit="${_key##--unit=}" - _args_simple_parsing_opt+=("$_key") + _args_simple_parsing_opt+=("${_key}") ;; -u*) _arg_unit="${_key##-u}" - _args_simple_parsing_opt+=("$_key") + _args_simple_parsing_opt+=("${_key}") ;; --no-verbose|--verbose) _arg_verbose="on" @@ -93,7 +93,7 @@ parse_commandline() ;; *) _last_positional="$1" - _positionals+=("$_last_positional") + _positionals+=("${_last_positional}") _positionals_count=$((_positionals_count + 1)) ;; esac @@ -105,7 +105,7 @@ parse_commandline() handle_passed_args_count() { local _required_args_string="'directory'" - test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require at least 1 (namely: $_required_args_string), but got only ${_positionals_count}." 1 + test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require at least 1 (namely: ${_required_args_string}), but got only ${_positionals_count}." 1 } @@ -116,14 +116,14 @@ assign_positional_args() _our_args=$((${#_positionals[@]} - 1)) for ((ii = 0; ii < _our_args; ii++)) do - _positional_names="$_positional_names _arg_directory[$((ii + 1))]" + _positional_names="${_positional_names} _arg_directory[$((ii + 1))]" done - shift "$_shift_for" + shift "${_shift_for}" for _positional_name in ${_positional_names} do test $# -gt 0 || break - eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 + eval "${_positional_name}=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 shift done } @@ -140,16 +140,17 @@ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || { echo "Couldn't d # [ <-- needed because of Argbash -script="$script_dir/simple.sh" -test -f "$script" || { echo "Missing the wrapped script, was expecting it next to me, in '$script_dir'."; exit 1; } +script="${script_dir}/simple.sh" +test -f "${script}" || { + echo "Missing the wrapped script, was expecting it next to me, in '${script_dir}'." + exit 1 +} -for directory in "${_arg_directory[@]}" -do - test -d "$directory" || die "We expected a directory, got '$directory', bailing out." - printf "Contents of '%s' matching '%s':\n" "$directory" "$_arg_glob" - for file in "$directory"/$_arg_glob - do - test -f "$file" && printf "\t%s: %s\n" "$(basename "$file")" "$("$script" "${_args_simple_parsing_opt[@]}" "$file")" +for directory in "${_arg_directory[@]}"; do + test -d "${directory}" || die "We expected a directory, got '${directory}', bailing out." + printf "Contents of '%s' matching '%s':\n" "${directory}" "${_arg_glob}" + for file in "${directory}"/${_arg_glob}; do + test -f "${file}" && printf "\t%s: %s\n" "$(basename "${file}")" "$("${script}" "${_args_simple_parsing_opt[@]}" "${file}")" done done diff --git a/resources/examples/simple.m4 b/resources/examples/simple.m4 index 43bff2d..dd5f874 100644 --- a/resources/examples/simple.m4 +++ b/resources/examples/simple.m4 @@ -8,14 +8,16 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -verbose=$_arg_verbose -unit=$_arg_unit +verbose=${_arg_verbose} +unit=${_arg_unit} -test -f $_arg_filename || { echo "Filename $_arg_filename doesn't seem to belong to a file"; exit 1; } -filename="$_arg_filename" +test -f ${_arg_filename} || { + echo "Filename ${_arg_filename} doesn't seem to belong to a file" + exit 1 +} +filename="${_arg_filename}" -if [ $verbose = on ] -then +if [ ${verbose} = on ]; then _b="bytes (B)" _kb="kibibytes (kiB)" _mb="mebibytes (MiB)" @@ -25,17 +27,17 @@ else _mb="MiB" fi -size_bytes=$(wc -c "$filename" | cut -f 1 -d ' ') +size_bytes=$(wc -c "${filename}" | cut -f 1 -d ' ') -test "$unit" = b && echo $size_bytes $_b && exit 0 +test "${unit}" = b && echo ${size_bytes} ${_b} && exit 0 -size_kibibytes=$(($size_bytes / 1024)) -test "$unit" = k && echo $size_kibibytes $_kb && exit 0 +size_kibibytes=$((size_bytes / 1024)) +test "${unit}" = k && echo ${size_kibibytes} ${_kb} && exit 0 -size_mebibytes=$(($size_kibibytes / 1024)) -test "$unit" = M && echo $size_mebibytes $_mb && exit 0 +size_mebibytes=$((size_kibibytes / 1024)) +test "${unit}" = M && echo ${size_mebibytes} ${_mb} && exit 0 -test "$verbose" = on && echo "The unit '$unit' is not supported" +test "${verbose}" = on && echo "The unit '${unit}' is not supported" exit 1 # ] <-- needed because of Argbash diff --git a/resources/examples/simple.sh b/resources/examples/simple.sh index b56deaa..4c78ed0 100755 --- a/resources/examples/simple.sh +++ b/resources/examples/simple.sh @@ -10,7 +10,8 @@ # OTHER STUFF GENERATED BY Argbash script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || { echo "Couldn't determine the script's running directory, which probably matters, bailing out" >&2; exit 2; } -. "$script_dir/simple-parsing.sh" # '.' means 'source' +# shellcheck source=SCRIPTDIR/simple-parsing.sh +. "${script_dir}/simple-parsing.sh" # '.' means 'source' ### END OF CODE GENERATED BY Argbash (sortof) ### ]) @@ -19,14 +20,16 @@ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || { echo "Couldn't d # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -verbose=$_arg_verbose -unit=$_arg_unit +verbose=${_arg_verbose} +unit=${_arg_unit} -test -f $_arg_filename || { echo "Filename $_arg_filename doesn't seem to belong to a file"; exit 1; } -filename="$_arg_filename" +test -f ${_arg_filename} || { + echo "Filename ${_arg_filename} doesn't seem to belong to a file" + exit 1 +} +filename="${_arg_filename}" -if [ $verbose = on ] -then +if [ ${verbose} = on ]; then _b="bytes (B)" _kb="kibibytes (kiB)" _mb="mebibytes (MiB)" @@ -36,17 +39,17 @@ else _mb="MiB" fi -size_bytes=$(wc -c "$filename" | cut -f 1 -d ' ') +size_bytes=$(wc -c "${filename}" | cut -f 1 -d ' ') -test "$unit" = b && echo $size_bytes $_b && exit 0 +test "${unit}" = b && echo ${size_bytes} ${_b} && exit 0 -size_kibibytes=$(($size_bytes / 1024)) -test "$unit" = k && echo $size_kibibytes $_kb && exit 0 +size_kibibytes=$((size_bytes / 1024)) +test "${unit}" = k && echo ${size_kibibytes} ${_kb} && exit 0 -size_mebibytes=$(($size_kibibytes / 1024)) -test "$unit" = M && echo $size_mebibytes $_mb && exit 0 +size_mebibytes=$((size_kibibytes / 1024)) +test "${unit}" = M && echo ${size_mebibytes} ${_mb} && exit 0 -test "$verbose" = on && echo "The unit '$unit' is not supported" +test "${verbose}" = on && echo "The unit '${unit}' is not supported" exit 1 # ] <-- needed because of Argbash diff --git a/src/argbash-1to2.m4 b/src/argbash-1to2.m4 index 5eba495..c06d283 100644 --- a/src/argbash-1to2.m4 +++ b/src/argbash-1to2.m4 @@ -6,7 +6,7 @@ version=_ARGBASH_VERSION # ARG_POSITIONAL_INF([input], [The input file to transform], 1) # ARG_OPTIONAL_SINGLE([output], o, [Name of the output file (pass '-' for stdout and empty string for the same as input file)], "") -# ARG_VERSION([echo "argbash-1to2 v$version"]) +# ARG_VERSION([echo "argbash-1to2 v${version}"]) # ARG_HELP([Convert a template for argbash>=1,<2 to argbash>=2,<3]) # ARGBASH_GO @@ -19,36 +19,37 @@ cleanup() test "${#_files_to_clean[*]}" != 0 && rm -f "${_files_to_clean[@]}" } -do_stuff () +do_stuff() { # SCRIPT_DIR is likely also a default, but maybe not - it may have been set explicitly - grep -q '\${\?SCRIPT_DIR' -- "$infname" && echo "You probably use a variable 'SCRIPT_DIR' in your script. It may be that you should rename it to 'script_dir', but this is not certain :-(" >&2 + grep -q '\${\?SCRIPT_DIR' -- "${infname}" && echo "You probably use a variable 'SCRIPT_DIR' in your script. It may be that you should rename it to 'script_dir', but this is not certain :-(" >&2 # We match $_ARG_FOO as well as ${ARG_FOO... # and _ARGS_FOO - sed 's/\(\${\?_ARGS\?_\w\+\)/\L\1\l/g' "$infname" + sed 's/\(\${\?_ARGS\?_\w\+\)/\L\1\l/g' "${infname}" } -outfname="$_arg_output" -test "${#infname[@]}" -gt 1 && test -n "$outfname" && die "You have specified more than one (${#infname[@]}) input filenames, so you probably want to modify the corresponding files in-place. In order to do so, you can't specify an output filename, even '-' does make no sense (currently: '$outfname')" +outfname="${_arg_output}" +test "${#infname[@]}" -gt 1 && test -n "${outfname}" && die "You have specified more than one (${#infname[@]}) input filenames, so you probably want to modify the corresponding files in-place. In order to do so, you can't specify an output filename, even '-' does make no sense (currently: '${outfname}')" trap cleanup EXIT -for infname in "${_arg_input[@]}" -do - test -f "$infname" || { echo "The input parameter has to be a file (got: '$infname')" >&2; exit 1; } - - test -n "$_arg_output" || outfname="$infname" - if test "$outfname" = '-' - then +for infname in "${_arg_input[@]}"; do + test -f "${infname}" || { + echo "The input parameter has to be a file (got: '${infname}')" >&2 + exit 1 + } + + test -n "${_arg_output}" || outfname="${infname}" + if test "${outfname}" = '-'; then do_stuff else # vvv This should catch most of the cases when we want to overwrite the source file # vvv and we don't want to leave a file (not even an empty one) when something goes wrong. temp_outfile="temp_$$" - _files_to_clean+=("$temp_outfile") - do_stuff > "$temp_outfile" - mv "$temp_outfile" "$outfname" + _files_to_clean+=("${temp_outfile}") + do_stuff > "${temp_outfile}" + mv "${temp_outfile}" "${outfname}" # So we don't make .m4 scripts executable - chmod --reference "$infname" "$outfname" + chmod --reference "${infname}" "${outfname}" fi done diff --git a/src/argbash-init.m4 b/src/argbash-init.m4 index f591650..86c643f 100644 --- a/src/argbash-init.m4 +++ b/src/argbash-init.m4 @@ -14,137 +14,114 @@ version=_ARGBASH_VERSION # ARG_OPTIONAL_REPEATED([wrap], ,[What script(s) to wrap]) # ARG_OPTIONAL_SINGLE([mode], m, [The slider between feature-rich and simple script.], [default]) # ARG_TYPE_GROUP_SET([mode], [MODE], [mode], [default,full,minimal]) -# ARG_VERSION([echo "argbash-init v$version"]) +# ARG_VERSION([echo "argbash-init v${version}"]) # ARG_HELP([Make a template for scripts.]) # ARGBASH_GO[ - _variables=() HAVE_POSITIONAL_ARG=no - -# This should be in sync with _translit_var in stuff.m4 -_translit_var() +# This should be in sync with _translate_var in stuff.m4 +_translate_var() { - printf "\$_arg_%s" "$1" | tr '[:upper:]' '[:lower:]' | tr '-' '_' + printf '${_arg_%s}' "$1" | tr '[:upper:]' '[:lower:]' | tr '-' '_' } - optional_argument_without_hints() { echo "# ARG_OPTIONAL_SINGLE([$1])" } - optional_argument_with_hints() { echo "# ARG_OPTIONAL_SINGLE([$1], [], [], [])" } - optional_argument() { "${FUNCNAME[0]}_$2" "$1" - _variables+=("printf 'Value of --%s: %s\\n' '$1' \"$(_translit_var "$1")\"") + _variables+=("printf 'Value of --%s: %s\\n' '$1' \"$(_translate_var "$1")\"") } - boolean_argument_with_hints() { echo "# ARG_OPTIONAL_BOOLEAN([$1], [], [], [])" } - boolean_argument_without_hints() { echo "# ARG_OPTIONAL_BOOLEAN([$1])" } - boolean_argument() { "${FUNCNAME[0]}_$2" "$1" - _variables+=("printf \"'%s' is %s\\\\n\" '$1' \"$(_translit_var "$1")\"") + _variables+=("printf \"'%s' is %s\\\\n\" '$1' \"$(_translate_var "$1")\"") } - positional_argument_with_hints() { echo "# ARG_POSITIONAL_SINGLE([$1], [], [&2" - elif test "$1" = "standalone_lib" - then + if test "$1" = "lib"; then + echo "echo \"This is just a parsing library template, not the library - pass the parent script '${outfname}' to 'argbash' to fix this.\" >&2" + elif test "$1" = "standalone_lib"; then echo "echo \"This is just a parsing library template, not the library - pass this file to 'argbash' to fix this.\" >&2" else echo "echo \"This is just a script template, not the script (yet) - pass it to 'argbash' to fix this.\" >&2" fi - echo "exit 11 #)Created by argbash-init v$version" + echo "exit 11 #)Created by argbash-init v${version}" } - do_args() { local _mode="without_hints" - if test "$_arg_hints" = on - then + if test "${_arg_hints}" = on; then echo "# Rearrange the order of options below according to what you would like to see in the help message." _mode="with_hints" fi - for name in "${_arg_opt[@]}" - do optional_argument "$name" "$_mode"; done - for name in "${_arg_opt_bool[@]}" - do boolean_argument "$name" "$_mode"; done - for name in "${_arg_pos[@]}" - do positional_argument "$name" "$_mode"; done + for name in "${_arg_opt[@]}"; do optional_argument "${name}" "${_mode}"; done + for name in "${_arg_opt_bool[@]}"; do boolean_argument "${name}" "${_mode}"; done + for name in "${_arg_pos[@]}"; do positional_argument "${name}" "${_mode}"; done } - do_args_footer() { - if test "$_arg_mode" = "full" - then + if test "${_arg_mode}" = "full"; then echo '# ARGBASH_SET_DELIM([ =])' echo '# ARG_OPTION_STACKING([getopt])' echo '# ARG_RESTRICT_VALUES([no-local-options])' - elif test "$_arg_mode" = "minimal" - then + elif test "${_arg_mode}" = "minimal"; then echo '# ARGBASH_SET_DELIM([ ])' echo '# ARG_OPTION_STACKING([none])' echo '# ARG_RESTRICT_VALUES([none])' fi - test "$HAVE_POSITIONAL_ARG" = yes && echo '# ARG_DEFAULTS_POS' + test "${HAVE_POSITIONAL_ARG}" = yes && echo '# ARG_DEFAULTS_POS' echo "# ARG_HELP([])" echo "# ARGBASH_GO" } - do_script_assisted() { do_header script @@ -156,7 +133,6 @@ do_script_assisted() do_body_protected } - # # $1: The filename of the parsing library do_script_separate() @@ -164,25 +140,23 @@ do_script_separate() do_header script parse_fname=${parse_fname_stem}.sh - echo "# Run 'argbash --strip user-content \"$1\" -o \"$parse_fname\"' to generate the '$parse_fname' file." - echo "# If you need to make changes later, edit '$parse_fname' directly, and regenerate by running" - echo "# 'argbash --strip user-content \"$parse_fname\" -o \"$parse_fname\"'" + echo "# Run 'argbash --strip user-content \"$1\" -o \"${parse_fname}\"' to generate the '${parse_fname}' file." + echo "# If you need to make changes later, edit '${parse_fname}' directly, and regenerate by running" + echo "# 'argbash --strip user-content \"${parse_fname}\" -o \"${parse_fname}\"'" echo 'script_dir="$(cd "$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")" && pwd)"' - echo '. "${script_dir}/'"$(basename "$parse_fname")\" || { echo \"Couldn't find '$(basename "$parse_fname")' parsing library in the '"'$script_dir'"' directory\"; exit 1; }" + echo '. "${script_dir}/'"$(basename "${parse_fname}")\" || { echo \"Couldn't find '$(basename "${parse_fname}")' parsing library in the '"'${script_dir}'"' directory\"; exit 1; }" echo do_body } - do_body() { echo "# vvv PLACE YOUR CODE HERE vvv" if test "${#_variables[@]}" -gt 0; then echo "# For example:" - for stat in "${_variables[@]}" - do - echo "$stat" + for stat in "${_variables[@]}"; do + echo "${stat}" done echo else @@ -193,7 +167,6 @@ do_body() echo "# ^^^ TERMINATE YOUR CODE BEFORE THE BOTTOM ARGBASH MARKER ^^^" } - do_body_protected() { echo @@ -204,45 +177,41 @@ do_body_protected() echo "# ] <-- needed because of Argbash" } - do_stuff() { do_header "$1" do_args do_args_footer - test "$_arg_separate" = 0 && do_body_protected + test "${_arg_separate}" = 0 && do_body_protected } -outfname="$_arg_output" +outfname="${_arg_output}" # we canonicize the empty string input to output filename to the dash -test -n "$outfname" || outfname='-' -test "$outfname" = "-" -a "$_arg_separate" -gt 0 && die "If you want to separate parsing and script body, you have to specify the outname, stdout doesn't work." +test -n "${outfname}" || outfname='-' +test "${outfname}" = "-" -a "${_arg_separate}" -gt 0 && die "If you want to separate parsing and script body, you have to specify the outname, stdout doesn't work." -if test "$outfname" = '-' -then +if test "${outfname}" = '-'; then do_stuff 'script' else - if test "$_arg_separate" = 0 - then - do_stuff 'script' > "$outfname" + if test "${_arg_separate}" = 0; then + do_stuff 'script' > "${outfname}" else parse_fname_stem="$(echo "${outfname}" | sed -e 's/\.\(sh\|m4\)$//')-parsing" # IMPORTANT NOTION: # do_stuff has to be called FIRST, because it sets the _variables array content as its side-effect - if test "$_arg_separate" = 1 - then + if test "${_arg_separate}" = 1; then do_stuff 'lib' > "${parse_fname_stem}.m4" - do_script_assisted > "$outfname" + do_script_assisted > "${outfname}" else - test "$_arg_separate" = 2 || echo "The greatest separation value is 2, got $_arg_separate" >&2 + test "${_arg_separate}" = 2 || echo "The greatest separation value is 2, got ${_arg_separate}" >&2 parsing_library_file="${parse_fname_stem}.m4" - do_stuff 'standalone_lib' > "${parsing_library_file}" - do_script_separate "$parsing_library_file" > "$outfname" + do_stuff 'standalone_lib' > "${parsing_library_file}" + do_script_separate "${parsing_library_file}" > "${outfname}" fi fi - chmod a+x "$outfname" + chmod a+x "${outfname}" fi # ]dnl diff --git a/src/argbash.m4 b/src/argbash.m4 index 4da0056..8aa8186 100644 --- a/src/argbash.m4 +++ b/src/argbash.m4 @@ -4,7 +4,6 @@ # SC2016: Expressions don't expand in single quotes, use double quotes for that. # SC2059 Don't use variables in the printf format string. - # DEFINE_SCRIPT_DIR # ARG_POSITIONAL_SINGLE([input], [The input template file (pass '-' for stdin)]) # ARG_OPTIONAL_SINGLE([output], o, [Name of the output file (pass '-' for stdout)], -) @@ -35,12 +34,11 @@ cleanup() # $1: What (string) to pipe to autom4te run_autom4te() { - printf '%s\n' "$1" \ - | autom4te "${DEBUG[@]}" -l m4sugar -I "$m4dir" + printf '%s\n' "$1" | + autom4te "${DEBUG[@]}" -l m4sugar -I "${m4dir}" return $? } - # TODO: Refactor to associative arrays as soon as the argbash online is sufficiently reliable # We don't use associative arrays due to old bash compatibility reasons autom4te_error_messages=( @@ -61,13 +59,11 @@ interpret_error() # print the error, smart stuff may follow printf '%s\n' "$1" local eof_lineno line_mentioned - for idx in "${!autom4te_error_messages[@]}" - do - eof_lineno="$(printf "%s" "$1" | grep -e "${autom4te_error_messages[$idx]}" | sed -e 's/.*:\([0-9]\+\).*/\1/')" - if test -n "$eof_lineno" - then - line_mentioned="$(printf '%s' "$2" | sed -n "$eof_lineno"p | tr -d '\n\r')" - printf "${argbash_error_response_stem[$idx]}" "$((eof_lineno - $3))" "$line_mentioned" + for idx in "${!autom4te_error_messages[@]}"; do + eof_lineno="$(printf "%s" "$1" | grep -e "${autom4te_error_messages[${idx}]}" | sed -e 's/.*:\([0-9]\+\).*/\1/')" + if test -n "${eof_lineno}"; then + line_mentioned="$(printf '%s' "$2" | sed -n "${eof_lineno}"p | tr -d '\n\r')" + printf "${argbash_error_response_stem[${idx}]}" "$((eof_lineno - $3))" "${line_mentioned}" fi eof_lineno='' done @@ -77,55 +73,56 @@ interpret_error() # $2: The original intended output file define_file_metadata() { - local _defines='' _intended_destination="$ARGBASH_INTENDED_DESTINATION" _input_dirname _output_dirname - test -n "$_intended_destination" || _intended_destination="$2" + ARGBASH_INTENDED_DESTINATION="${ARGBASH_INTENDED_DESTINATION=}" + SPURIONS_OUTPUT_SUFFIX="${SPURIONS_OUTPUT_SUFFIX=}" + local _defines='' _intended_destination="${ARGBASH_INTENDED_DESTINATION}" _input_dirname _output_dirname + test -n "${_intended_destination}" || _intended_destination="$2" _input_dirname="$(dirname "$1")" test "$1" != '-' && _defines="${_defines}m4_define([INPUT_BASENAME], [[$(basename "$1")]])" - _defines="${_defines}m4_define([INPUT_ABS_DIRNAME], [[$(cd "$_input_dirname" && pwd)]])" + _defines="${_defines}m4_define([INPUT_ABS_DIRNAME], [[$(cd "${_input_dirname}" && pwd)]])" - _output_dirname="$(dirname "$_intended_destination")" - test "$_intended_destination" != '-' && _defines="${_defines}m4_define([OUTPUT_BASENAME], [[$(basename "$_intended_destination" "$SPURIONS_OUTPUT_SUFFIX")]])" - _defines="${_defines}m4_define([OUTPUT_ABS_DIRNAME], [[$(cd "$_output_dirname" && pwd)]])" - printf "%s" "$_defines" + _output_dirname="$(dirname "${_intended_destination}")" + test "${_intended_destination}" != '-' && _defines="${_defines}m4_define([OUTPUT_BASENAME], [[$(basename "${_intended_destination}" "${SPURIONS_OUTPUT_SUFFIX}")]])" + _defines="${_defines}m4_define([OUTPUT_ABS_DIRNAME], [[$(cd "${_output_dirname}" && pwd)]])" + printf "%s" "${_defines}" } - +# Yes both tests need to pass or we should throw out an error message +# shellcheck disable=2015 assert_m4_files_are_readable() { - local _argbash_lib="$m4dir/argbash-lib.m4" - test -d "$m4dir" && test -x "$m4dir" || die "The directory '$m4dir' with files needed by Argbash is not browsable. Check whether it exists and review it's permissions." - test -r "$_argbash_lib" && test -f "$_argbash_lib" || die "The '$_argbash_lib' file needed by Argbash is not readable. Check whether it exists and review it's permissions." - test -r "$output_m4" && test -f "$output_m4" || die "The '$output_m4' file needed by Argbash is not readable. Check whether it exists and review it's permissions." + local _argbash_lib="${m4dir}/argbash-lib.m4" + test -d "${m4dir}" && test -x "${m4dir}" || die "The directory '${m4dir}' with files needed by Argbash is not browsable. Check whether it exists and review it's permissions." + test -r "${_argbash_lib}" && test -f "${_argbash_lib}" || die "The '${_argbash_lib}' file needed by Argbash is not readable. Check whether it exists and review it's permissions." + test -r "${output_m4}" && test -f "${output_m4}" || die "The '${output_m4}' file needed by Argbash is not readable. Check whether it exists and review it's permissions." } - # The main function that generates the parsing script body # $1: The input file # $2: The output file # $3: The argument type do_stuff() { - local _pass_also="$_wrapped_defns" input prefix_len _ret - test "$_arg_commented" = on && _pass_also="${_pass_also}m4_define([COMMENT_OUTPUT])" + local _pass_also="${_wrapped_defns}" input prefix_len _ret + test "${_arg_commented}" = on && _pass_also="${_pass_also}m4_define([COMMENT_OUTPUT])" _pass_also="${_pass_also}m4_define([_OUTPUT_TYPE], [[$3]])" - _pass_also="${_pass_also}$(define_file_metadata "$_arg_input" "$2")" - input="$(printf '%s\n' "$_pass_also" | cat - "$m4dir/argbash-lib.m4" "$output_m4")" - prefix_len=$(printf '%s\n' "$input" | wc -l) - input="$(printf '%s\n' "$input" | cat - "$1")" - run_autom4te "$input" 2> "$discard" \ - | grep -v '^#\s*needed because of Argbash -->\s*$' \ - | grep -v '^#\s*<-- needed because of Argbash\s*$' + _pass_also="${_pass_also}$(define_file_metadata "${_arg_input}" "$2")" + input="$(printf '%s\n' "${_pass_also}" | cat - "${m4dir}/argbash-lib.m4" "${output_m4}")" + prefix_len=$(printf '%s\n' "${input}" | wc -l) + input="$(printf '%s\n' "${input}" | cat - "$1")" + run_autom4te "${input}" 2> "${discard}" | + grep -v '^#\s*needed because of Argbash -->\s*$' | + grep -v '^#\s*<-- needed because of Argbash\s*$' _ret=$? - if test $_ret != 0 - then + if test "${_ret}" != 0; then local errstr - errstr="$(run_autom4te "$input" 2>&1 > "$discard")" - interpret_error "$errstr" "$input" "$prefix_len" >&2 - echo "Error during autom4te run, aborting!" >&2; - exit $_ret; + errstr="$(run_autom4te "${input}" 2>&1 > "${discard}")" + interpret_error "${errstr}" "${input}" "${prefix_len}" >&2 + echo "Error during autom4te run, aborting!" >&2 + exit "${_ret}" fi - return "$_ret" + return "${_ret}" } # Fills content to variable _wrapped_defns --- where are scripts of given stems @@ -137,26 +134,36 @@ settle_wrapped_fname() # Based on http://stackoverflow.com/a/19772067/592892 local _srcfiles=() _file_found _found ext srcstem searchdir line stem="$2" while read -r line; do - _srcfiles+=("$line") - done < <(echo 'm4_changecom()m4_define([ARGBASH_WRAP])' "$(cat "$1")" \ - | autom4te -l m4sugar -t 'ARGBASH_WRAP:$1' 2> "$discard") + _srcfiles+=("${line}") + done < <(echo 'm4_changecom()m4_define([ARGBASH_WRAP])' "$(cat "$1")" | + autom4te -l m4sugar -t 'ARGBASH_WRAP:$1' 2> "${discard}") test "${#_srcfiles[@]}" -gt 0 || return - for srcstem in "${_srcfiles[@]}" - do + for srcstem in "${_srcfiles[@]}"; do _found=no - for searchdir in "${_arg_search[@]}" - do - test -f "$searchdir/$srcstem.m4" && { _found=yes; ext='.m4'; break; } - test -f "$searchdir/$srcstem.sh" && { _found=yes; ext='.sh'; break; } - test -f "$searchdir/$srcstem" && { _found=yes; ext=''; break; } + for searchdir in "${_arg_search[@]}"; do + test -f "${searchdir}/${srcstem}.m4" && { + _found=yes + ext='.m4' + break + } + test -f "${searchdir}/${srcstem}.sh" && { + _found=yes + ext='.sh' + break + } + test -f "${searchdir}/${srcstem}" && { + _found=yes + ext='' + break + } done # The last searchdir is a correct one - test $_found = yes || die "Couldn't find wrapped file of stem '$srcstem' in any of directories: ${_arg_search[*]}" 2 - _file_found="$searchdir/${srcstem}${ext}" - stem=${2:-$srcstem} - settle_wrapped_fname "$_file_found" "$stem" - _wrapped_defns="${_wrapped_defns}m4_define([_GROUP_OF_$srcstem], [[$stem]])m4_define([_SCRIPT_$srcstem], [[$_file_found]])" + test "${_found}" = yes || die "Couldn't find wrapped file of stem '${srcstem}' in any of directories: ${_arg_search[*]}" 2 + _file_found="${searchdir}/${srcstem}${ext}" + stem=${2:-${srcstem}} + settle_wrapped_fname "${_file_found}" "${stem}" + _wrapped_defns="${_wrapped_defns}m4_define([_GROUP_OF_${srcstem}], [[${stem}]])m4_define([_SCRIPT_${srcstem}], [[${_file_found}]])" done } @@ -169,111 +176,110 @@ get_parsing_code() { local _shfile _m4file _newerfile # Get the argument of INCLUDE_PARSING_CODE - _srcfile="$(echo 'm4_changecom()m4_define([INCLUDE_PARSING_CODE])' "$(cat "$infile")" \ - | autom4te -l m4sugar -t 'INCLUDE_PARSING_CODE:$1' 2> "$discard" \ - | tail -n 1)" - test -n "$_srcfile" || return 1 - _thatfile="$(dirname "$infile")/$_srcfile" - test -f "$_thatfile" && _shfile="$_thatfile" + _srcfile="$(echo 'm4_changecom()m4_define([INCLUDE_PARSING_CODE])' "$(cat "${infile}")" | + autom4te -l m4sugar -t 'INCLUDE_PARSING_CODE:$1' 2> "${discard}" | + tail -n 1)" + test -n "${_srcfile}" || return 1 + _thatfile="$(dirname "${infile}")/${_srcfile}" + test -f "${_thatfile}" && _shfile="${_thatfile}" # Take out everything after last dot (http://stackoverflow.com/questions/125281/how-do-i-remove-the-file-suffix-and-path-portion-from-a-path-string-in-bash) _thatfile="${_thatfile%.*}.m4" - test -f "$_thatfile" && _m4file="$_thatfile" + test -f "${_thatfile}" && _m4file="${_thatfile}" # if have neither of files - test -z "$_shfile" && test -z "$_m4file" && echo "Strange, we think that there was a source file '$_srcfile' that should be included, but we haven't found it in directory '$(dirname "$_thatfile")'" >&2 && return 1 + test -z "${_shfile}" && test -z "${_m4file}" && echo "Strange, we think that there was a source file '${_srcfile}' that should be included, but we haven't found it in directory '$(dirname "${_thatfile}")'" >&2 && return 1 # We have one file, but not the other one => decision of what to pick is easy. - test -z "$_shfile" && test -n "$_m4file" && echo "$_m4file" && return - test -n "$_shfile" && test -z "$_m4file" && echo "$_shfile" && return + test -z "${_shfile}" && test -n "${_m4file}" && echo "${_m4file}" && return + test -n "${_shfile}" && test -z "${_m4file}" && echo "${_shfile}" && return # We have both, so we pick up the newer one - _newerfile="$_shfile" - test "$_m4file" -nt "$_shfile" && _newerfile="$_m4file" - echo "$_newerfile" + _newerfile="${_shfile}" + test "${_m4file}" -nt "${_shfile}" && _newerfile="${_m4file}" + echo "${_newerfile}" } - # $1: The output file # $2: The output type string set_output_permission() { - if grep -q '\' <<< "$2" - then + if grep -q '\' <<< "$2"; then chmod a+x "$1" fi } - # MS Windows compatibility fix discard=/dev/null -test -e $discard || discard=NUL +test -e "${discard}" || discard=NUL set -o pipefail -infile="$_arg_input" +infile="${_arg_input}" trap cleanup EXIT # If we are reading from stdout, then create a temp file -if test "$infile" = '-' -then - if test "$_arg_in_place" = 'on' - then +if test "${infile}" = '-'; then + if test "${_arg_in_place}" = 'on'; then echo "Cannot use stdin input with --in-place option!" >&2 - exit 1; + exit 1 fi infile=temp_in_$$ - _files_to_clean+=("$infile") - cat > "$infile" + _files_to_clean+=("${infile}") + cat > "${infile}" fi -m4dir="$script_dir/../src" -test -n "$_arg_debug" && DEBUG=('-t' "$_arg_debug") +m4dir="${script_dir}/../src" +test -n "${_arg_debug}" && DEBUG=('-t' "${_arg_debug}") -output_m4="$m4dir/output-strip-none.m4" -test "$_arg_library" = "on" && { echo "The --library option is deprecated, use --strip user-content" next time >&2; _arg_strip="user-content"; } -if test "$_arg_strip" = "user-content" -then - output_m4="$m4dir/output-strip-user-content.m4" -elif test "$_arg_strip" = "all" -then - output_m4="$m4dir/output-strip-all.m4" +output_m4="${m4dir}/output-strip-none.m4" +test "${_arg_library}" = "on" && { + echo "The --library option is deprecated, use --strip user-content" next time >&2 + _arg_strip="user-content" +} +if test "${_arg_strip}" = "user-content"; then + output_m4="${m4dir}/output-strip-user-content.m4" +elif test "${_arg_strip}" = "all"; then + output_m4="${m4dir}/output-strip-all.m4" fi -test -f "$infile" || _PRINT_HELP=yes die "argument '$infile' is supposed to be a file!" 1 -if test "$_arg_in_place" = on -then - _arg_output="$infile" +test -f "${infile}" || _PRINT_HELP=yes die "argument '${infile}' is supposed to be a file!" 1 +if test "${_arg_in_place}" = on; then + _arg_output="${infile}" fi -test -n "$_arg_output" || { echo "The output can't be blank - it is not a legal filename!" >&2; exit 1; } -outfname="$_arg_output" -autom4te --version > "$discard" 2>&1 || { echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1; exit 1; } -_arg_search+=("$(dirname "$infile")") +test -n "${_arg_output}" || { + echo "The output can't be blank - it is not a legal filename!" >&2 + exit 1 +} +outfname="${_arg_output}" +autom4te --version > "${discard}" 2>&1 || { + echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 + exit 1 +} +_arg_search+=("$(dirname "${infile}")") _wrapped_defns="" # So let's settle the parsing code first. Hopefully we won't create a loop. parsing_code="$(get_parsing_code)" # Just if the original was m4, we replace .m4 with .sh -test -n "$parsing_code" && parsing_code_out="${parsing_code:0:-2}sh" -test "$_arg_library" = off && test -n "$parsing_code" && ($0 --strip user-content "$parsing_code" -o "$parsing_code_out") +test -n "${parsing_code}" && parsing_code_out="${parsing_code:0:-2}sh" +test "${_arg_library}" = off && test -n "${parsing_code}" && ($0 --strip user-content "${parsing_code}" -o "${parsing_code_out}") # We may use some of the wrapping stuff, so let's fill the _wrapped_defns -settle_wrapped_fname "$infile" +settle_wrapped_fname "${infile}" assert_m4_files_are_readable -output="$(do_stuff "$infile" "$outfname" "$_arg_type")" || die "" "$?" -if test "$_arg_check_typos" = on -then +output="$(do_stuff "${infile}" "${outfname}" "${_arg_type}")" || die "" "$?" +if test "${_arg_check_typos}" = on; then # match against suspicious, then inverse match against correct stuff: # #\(allowed\|another allowed\|...\) end of line> # Then, extract all matches (assumed to be alnum chars + '_') from grep and put them in the error msg. - grep_output="$(printf "%s" "$output" | grep '^#\s*\(ARG_\|ARGBASH\)' | grep -v '^#\s*\(]m4_set_contents([_KNOWN_MACROS], [\|])[\)\s*\((\|$\)' | sed -e 's/#\s*\([[:alnum:]_]*\).*/\1 /' | tr -d '\n\r')" - test -n "$grep_output" && die "Your script contains possible misspelled Argbash macros: $grep_output" 1 + grep_output="$(printf "%s" "${output}" | grep '^#\s*\(ARG_\|ARGBASH\)' | grep -v '^#\s*\(]m4_set_contents([_KNOWN_MACROS], [\|])[\)\s*\((\|$\)' | sed -e 's/#\s*\([[:alnum:]_]*\).*/\1 /' | tr -d '\n\r')" + test -n "${grep_output}" && die "Your script contains possible misspelled Argbash macros: ${grep_output}" 1 fi -if test "$outfname" != '-' -then - printf "%s\\n" "$output" > "$outfname" - set_output_permission "$outfname" "$_arg_type" +if test "${outfname}" != '-'; then + printf '%s\n' "${output}" > "${outfname}" + set_output_permission "${outfname}" "${_arg_type}" else - printf "%s\\n" "$output" + printf '%s\n' "${output}" fi # ]dnl diff --git a/src/argument_value_types.m4 b/src/argument_value_types.m4 index 60fb05a..5a85a91 100644 --- a/src/argument_value_types.m4 +++ b/src/argument_value_types.m4 @@ -125,7 +125,7 @@ m4_define([_VALIDATE_POSITIONAL_ARGUMENTS], [m4_do( [m4_pushdef([_arg_varname], [_varname(_arg)])], - [_arg_varname=_MAYBE_VALIDATE_VALUE(_arg, "$_arg_varname") || exit 1 + [_arg_varname=_MAYBE_VALIDATE_VALUE(_arg, "${_arg_varname}") || exit 1 ], [m4_popdef([_arg_varname])], )])])], @@ -167,5 +167,5 @@ dnl $2: suffix m4_define([_VALIDATE_VALUES_IDX], [m4_ifnblank([$2], [m4_do( [_varname([$1])[_$2="@S|@@{:@]], [_GET_VALUE_TYPE([$1], 1)], - [ "$_varname([$1])" "[$1]" idx@:}@"], + [ "${_varname([$1])}" "[$1]" idx@:}@"], )])]) diff --git a/src/collectors.m4 b/src/collectors.m4 index 2391921..87d4429 100644 --- a/src/collectors.m4 +++ b/src/collectors.m4 @@ -57,14 +57,14 @@ m4_define([_pos_suffix], [[_pos]]) m4_define([_arg_prefix], [[_arg_]]) m4_define([_args_prefix], [[_args_]]) m4_define([_varname], [m4_do( - [m4_quote(_arg_prefix[]_translit_var([$1]))], + [m4_quote(_arg_prefix[]_translate_var([$1]))], )]) dnl dnl The operation on command names that makes stem of variable names -dnl Since each call of _translit_var etc. strips one level of quoting, we have to quote $1 more than usually -m4_define([_translit_var], [m4_translit(m4_translit([[[$1]]], [A-Z], [a-z]), [-/], [__])]) +dnl Since each call of _translate_var etc. strips one level of quoting, we have to quote $1 more than usually +m4_define([_translate_var], [m4_translit(m4_translit([[[$1]]], [A-Z], [a-z]), [-/], [__])]) m4_define([_translit_prog], [m4_translit(m4_translit([[[$1]]], [a-z], [A-Z]), [-], [_])]) @@ -116,7 +116,7 @@ m4_define([_CHECK_ARGNAME_FREE], [m4_do( m4_define([_CHECK_POSITIONAL_ARGNAME_IS_FREE], [m4_do( - [m4_pushdef([_ARG_VAR_NAME], m4_dquote(_translit_var([$1])))], + [m4_pushdef([_ARG_VAR_NAME], m4_dquote(_translate_var([$1])))], [_CHECK_ARGNAME_FREE_FATAL([$1], _ARG_VAR_NAME)], [m4_set_add([_POSITIONALS], _ARG_VAR_NAME)], [m4_popdef([_ARG_VAR_NAME])], @@ -124,7 +124,7 @@ m4_define([_CHECK_POSITIONAL_ARGNAME_IS_FREE], [m4_do( m4_define([_ENSURE_UNIQUENESS_OF_ARGUMENT_IDENTIFIER], [m4_do( - [m4_pushdef([_ARG_VAR_NAME], m4_dquote(_translit_var([$1])))], + [m4_pushdef([_ARG_VAR_NAME], m4_dquote(_translate_var([$1])))], [_CHECK_ARGNAME_FREE_FATAL([$1], _ARG_VAR_NAME)], [m4_set_add([_ARGS_LONG], _ARG_VAR_NAME)], [m4_popdef([_ARG_VAR_NAME])], @@ -171,7 +171,7 @@ dnl TODO: Take the _WRAPPED code and move it one level up dnl dnl $1 - the variable where the argument value is collected m4_define([_POS_WRAPPED], [m4_ifdef([WRAPPED_FILE_STEM], - [__POS_WRAPPED([$1], m4_expand([_args_prefix[]_translit_var(_GET_BASENAME(WRAPPED_FILE_STEM))]))], + [__POS_WRAPPED([$1], m4_expand([_args_prefix[]_translate_var(_GET_BASENAME(WRAPPED_FILE_STEM))]))], )]) m4_define([__POS_WRAPPED], [m4_do( @@ -181,7 +181,7 @@ m4_define([__POS_WRAPPED], [m4_do( )]) m4_define([_OPT_WRAPPED], [m4_ifdef([WRAPPED_FILE_STEM], - [__OPT_WRAPPED([$1], m4_expand([_args_prefix[]_translit_var(_GET_BASENAME(WRAPPED_FILE_STEM))]))], + [__OPT_WRAPPED([$1], m4_expand([_args_prefix[]_translate_var(_GET_BASENAME(WRAPPED_FILE_STEM))]))], )]) m4_define([__OPT_WRAPPED], [m4_do( diff --git a/src/env_vars.m4 b/src/env_vars.m4 index e1e8a9d..d2bf97e 100644 --- a/src/env_vars.m4 +++ b/src/env_vars.m4 @@ -34,6 +34,6 @@ dnl $1: name dnl $2: default dnl TODO: Try to use the 'declare' builtin to see whether the variable is even defined m4_define([__SETTLE_ENV], [m4_do( - [test -n "@S|@$1" || $1="$2" + [test -n "@S|@{$1}" || $1="$2" ], )]) diff --git a/src/function_generators.m4 b/src/function_generators.m4 index 6b2ced1..63d4c2d 100644 --- a/src/function_generators.m4 +++ b/src/function_generators.m4 @@ -51,7 +51,7 @@ m4_define([_MAKE_NEXT_OPTARG_FUNCTION], [MAKE_FUNCTION( [begins_with_short_option], [_JOIN_INDENTED(1, [[first_option="${1:0:1}"]], - [[test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0]])], + [[test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0]])], [first_option], m4_expand([all_short_options='m4_list_join([_ARGS_SHORT], [])']), )]) @@ -80,7 +80,7 @@ m4_define([_CHECK_FOR_TOO_LITTLE_ARGS], [m4_do( [_MINIMAL_POSITIONAL_VALUES_COUNT], [[ || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require ]], [_SPECIFICATION_OF_ACCEPTED_VALUES_COUNT], - [ (namely: $_required_args_string)], + [ (namely: ${_required_args_string})], [[, but got only ${_positionals_count}." 1 ]], )]) @@ -95,7 +95,7 @@ m4_define([__CHECK_FOR_TOO_MANY_ARGS], [m4_do( [_INDENT_(1)[test "${_positionals_count}" -le ]_HIGHEST_POSITIONAL_VALUES_COUNT], [[ || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect ]], [_SPECIFICATION_OF_ACCEPTED_VALUES_COUNT], - [_IF_SOME_POSITIONAL_VALUES_ARE_EXPECTED([ (namely: $_required_args_string)])], + [_IF_SOME_POSITIONAL_VALUES_ARE_EXPECTED([ (namely: ${_required_args_string})])], [[, but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 ]], )]) @@ -138,15 +138,15 @@ m4_define([_MAKE_ASSIGN_POSITIONAL_ARGS_FUNCTION], [MAKE_FUNCTION( [assign_positional_args], [m4_do( [m4_n([_MAKE_LIST_OF_POSITIONAL_ASSIGNMENT_TARGETS])], [_JOIN_INDENTED(1, - [[shift "$_shift_for"]], + [[shift "${_shift_for}"]], [[for _positional_name in ${_positional_names}]], [[do]], _INDENT_MORE( [[test @S|@# -gt 0 || break]], - [[eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1]], + [[eval "${_positional_name}=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1]], _CASE_RESTRICT_VALUES([], [], [_COMM_BLOCK(0, [# It has been requested that all positional arguments that look like options are rejected]), - [[evaluate_strictness "$_positional_name" "${1##_arg}"]], + [[evaluate_strictness "${_positional_name}" "${1##_arg}"]], ]), [[shift]], ), diff --git a/src/progs.m4 b/src/progs.m4 index be15eba..f2428b6 100644 --- a/src/progs.m4 +++ b/src/progs.m4 @@ -9,9 +9,9 @@ m4_define([_CHECK_PROG_FACTORY_INDIR], [MAKE_FUNCTION( [@S|@3: The error message]], [check_prog], [_JOIN_INDENTED(1, - [test -n "$_msg" || _msg="Unable to find a reachable executable '@S|@2'"], - [eval "test -n \"\@S|@@S|@1\" || @S|@1=\"@S|@2\""], - [eval "command -v \"\@S|@@S|@1\" > /dev/null 2> /dev/null" || die "$_msg" 1], + [test -n "${_msg}" || _msg="Unable to find a reachable executable '@S|@2'"], + [eval "test -n \"\@S|@{@S|@1}\" || @S|@1=\"@S|@2\""], + [eval "command -v \"\@S|@{@S|@1}\" > /dev/null 2> /dev/null" || die "${_msg}" 1], )], [_msg="@S|@3"], )]) @@ -29,8 +29,8 @@ m4_define([_CHECK_PROG_FACTORY_SINGLE], [MAKE_FUNCTION( [], [check_prog_for_$1], [_JOIN_INDENTED(1, - [test -n "@S|@$1" || $1="$2"], - [$1="$(command -v "@S|@$1")" || die "m4_default([$3], [Unable to find a reachable executable '$2'])" 1], + [test -n "@S|@{$1}" || $1="$2"], + [$1="$(command -v "@S|@{$1}")" || die "m4_default([$3], [Unable to find a reachable executable '$2'])" 1], )])]) diff --git a/src/stuff.m4 b/src/stuff.m4 index 5b17ede..0d4c4cb 100644 --- a/src/stuff.m4 +++ b/src/stuff.m4 @@ -76,11 +76,13 @@ dnl The argbash script generator will pick it up and (re)generate that one as we dnl dnl $1: the filename (assuming that it is in the same directory as the script) dnl $2: what has been passed to DEFINE_SCRIPT_DIR as the first param +dnl TODO: add shellcheck source directive argbash_api([INCLUDE_PARSING_CODE], _CHECK_PASSED_ARGS_COUNT(1, 2)[m4_do( [[$0($@)]], [m4_ifndef([SCRIPT_DIR_DEFINED], [m4_fatal([You have to define a script directory by some means before using '$0'])])], [m4_list_append([_OTHER], - m4_expand([[. "$]m4_default_quoted([$2], _SCRIPT_DIR_NAME)[/$1]" [# '.' means 'source' + m4_expand([[# shellcheck source=SCRIPTDIR/$1]]), + m4_expand([[. "$][{]m4_default_quoted([$2], _SCRIPT_DIR_NAME)[}][/$1]" [# '.' means 'source' ]]))], )]) @@ -442,7 +444,7 @@ dnl $3: Name of the value-to-variable macro dnl $4: The name of the argument-holding variable dnl $5: Where to get the last value (optional) m4_define([_VAL_OPT_ADD_SPACE_WITHOUT_GETOPT_OR_SHORT_OPT], [_JOIN_INDENTED(_INDENT_LEVEL_IN_ARGV_CASE_BODY, - [test $[]# -lt 2 && die "Missing value for the optional argument '$_key'." 1], + [test $[]# -lt 2 && die "Missing value for the optional argument '${_key}'." 1], [$3([$1], ["@S|@2"], [$4])], [_APPEND_WRAPPED_ARGUMENT_TO_ARRAY_SPACE([$4], [m4_default_quoted([$5], [@S|@2])])], [shift], @@ -456,8 +458,8 @@ dnl $3: Name of the value-to-variable macro dnl $4: The name of the argument-holding variable dnl $5: Where to get the last value (optional) m4_define([_VAL_OPT_ADD_GETOPTS], [_JOIN_INDENTED(_INDENT_LEVEL_IN_ARGV_CASE_BODY, - [test "x$OPTARG" = x && die "Missing value for the optional argument '-$_key'." 1], - [$3([$1], ["$OPTARG"], [$4])], + [test "x${OPTARG}" = x && die "Missing value for the optional argument '-${_key}'." 1], + [$3([$1], ["${OPTARG}"], [$4])], [_APPEND_WRAPPED_ARGUMENT_TO_ARRAY_SPACE([$4], [m4_default_quoted([$5], [$OPTARG])])], )]) @@ -512,13 +514,13 @@ m4_define([_APPEND_WRAPPED_ARGUMENT_TO_ARRAY_SPACE], [m4_do( dnl see _APPEND_WRAPPED_ARGUMENT_TO_ARRAY_EQUALS_OR_BOTH for docs m4_define([_APPEND_WRAPPED_ARGUMENT_TO_ARRAY_GETOPT], [m4_do( - [_IF_WRAPPING_OPTION([$1], [_COLLECT_$1+=("$_key")])], + [_IF_WRAPPING_OPTION([$1], [_COLLECT_$1+=("${_key}")])], )]) dnl see _APPEND_WRAPPED_ARGUMENT_TO_ARRAY_EQUALS_OR_BOTH for docs m4_define([_APPEND_WRAPPED_ARGUMENT_TO_ARRAY_EQUALS], [m4_do( - [_IF_WRAPPING_OPTION([$1], [_COLLECT_$1+=("$_key")])], + [_IF_WRAPPING_OPTION([$1], [_COLLECT_$1+=("${_key}")])], )]) @@ -726,8 +728,8 @@ m4_define([_MAKE_OPTARG_SIMPLE_CASE_SECTION], [m4_do( [_IF_ARG_IS_BOOLEAN([$3], [[--no-$1]])], [_IF_ARG_ACCEPTS_VALUE([$3], [_IF_SPACE_IS_A_DELIMITER([[--$1]])], [[--$1]])])], [m4_case([$3], - [arg], [_VAL_OPT_ADD_SPACE_WITHOUT_GETOPT_OR_SHORT_OPT([$1], [$2], [_ASSIGN_VALUE_TO_VAR], [$5])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([$_key], [$$5])], - [repeated], [_VAL_OPT_ADD_SPACE_WITHOUT_GETOPT_OR_SHORT_OPT([$1], [$2], [_APPEND_VALUE_TO_ARRAY], [$5], [${$5[-1]}])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([$_key], [${$5[-1]}])], + [arg], [_VAL_OPT_ADD_SPACE_WITHOUT_GETOPT_OR_SHORT_OPT([$1], [$2], [_ASSIGN_VALUE_TO_VAR], [$5])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([${_key}], [${$5}])], + [repeated], [_VAL_OPT_ADD_SPACE_WITHOUT_GETOPT_OR_SHORT_OPT([$1], [$2], [_APPEND_VALUE_TO_ARRAY], [$5], [${$5[-1]}])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([${_key}], [${$5[-1]}])], [bool], [_JOIN_INDENTED(_INDENT_LEVEL_IN_ARGV_CASE_BODY, [[$5="on"]], @@ -758,7 +760,7 @@ dnl And for -h*, since this is an action and argbash then ends (but maybe not, w m4_define([_MAKE_OPTARG_GETOPTS_CASE_SECTION], [m4_do( [_INDENT_AND_END_CASE_MATCH([[$2]])], [m4_case([$3], - [arg], [_VAL_OPT_ADD_GETOPTS([$1], [$2], [_ASSIGN_VALUE_TO_VAR], [$5])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([$_key], [$$5])], + [arg], [_VAL_OPT_ADD_GETOPTS([$1], [$2], [_ASSIGN_VALUE_TO_VAR], [$5])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([${_key}], [${$5}])], [repeated], [m4_fatal([Repeated arguments are not supported in the POSIX mode])], [bool], [_JOIN_INDENTED(_INDENT_LEVEL_IN_ARGV_CASE_BODY, @@ -803,8 +805,8 @@ m4_define([_MAKE_OPTARG_LONGOPT_EQUALS_CASE_SECTION], [m4_do( [_INDENT_AND_END_CASE_MATCH( [[--$1=*]])], [m4_case([$3], - [arg], [_VAL_OPT_ADD_EQUALS_WITH_LONG_OPT([$1], [], [_ASSIGN_VALUE_TO_VAR], [$5])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([$_key], [$$5])], - [repeated], [_VAL_OPT_ADD_EQUALS_WITH_LONG_OPT([$1], [], [_APPEND_VALUE_TO_ARRAY], [$5], [${$5[-1]}])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([$_key], [${$5[-1]}])], + [arg], [_VAL_OPT_ADD_EQUALS_WITH_LONG_OPT([$1], [], [_ASSIGN_VALUE_TO_VAR], [$5])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([${_key}], [${$5}])], + [repeated], [_VAL_OPT_ADD_EQUALS_WITH_LONG_OPT([$1], [], [_APPEND_VALUE_TO_ARRAY], [$5], [${$5[-1]}])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([${_key}], [${$5[-1]}])], [m4_fatal([Internal error: Argument of type '$3' is other than 'arg' or 'repeated' and shouldn't make it to the '$0' macro.])] )], [_INDENT_(_INDENT_LEVEL_IN_ARGV_CASE_BODY);; @@ -818,8 +820,8 @@ m4_define([_MAKE_OPTARG_GETOPT_CASE_SECTION], [m4_do( [dnl Search for occurences of e.g. -ujohn and make sure that either -u accepts a value, or -j is a short option ], [m4_case([$3], - [arg], [_VAL_OPT_ADD_ONLY_WITH_SHORT_OPT_GETOPT([$1], [$2], [_ASSIGN_VALUE_TO_VAR], [$5])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([$_key], [$$5])], - [repeated], [_VAL_OPT_ADD_ONLY_WITH_SHORT_OPT_GETOPT([$1], [$2], [_APPEND_VALUE_TO_ARRAY], [$5], [${$5[-1]}])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([$_key], [${$5[-1]}])], + [arg], [_VAL_OPT_ADD_ONLY_WITH_SHORT_OPT_GETOPT([$1], [$2], [_ASSIGN_VALUE_TO_VAR], [$5])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([${_key}], [${$5}])], + [repeated], [_VAL_OPT_ADD_ONLY_WITH_SHORT_OPT_GETOPT([$1], [$2], [_APPEND_VALUE_TO_ARRAY], [$5], [${$5[-1]}])_CHECK_PASSED_VALUE_AGAINST_BLACKLIST([${_key}], [${$5[-1]}])], [bool], [_JOIN_INDENTED(_INDENT_LEVEL_IN_ARGV_CASE_BODY, [[$5="on"]], @@ -866,7 +868,7 @@ m4_define([_HANDLE_OCCURENCE_OF_DOUBLEDASH_ARG], [m4_do( [# assign the rest of arguments as positional arguments and bail out.], )], [_JOIN_INDENTED(_INDENT_LEVEL_IN_ARGV_WHILE, - [if test "$_key" = '--'], + [if test "${_key}" = '--'], [then], _INDENT_MORE( [shift], @@ -887,7 +889,7 @@ m4_define([_HANDLE_OCCURENCE_OF_DOUBLEDASH_ARG_POSIX], [m4_do( [# mark the first positional argument the one right after this one.], )], [_JOIN_INDENTED(_INDENT_LEVEL_IN_ARGV_WHILE, - [if test "$_key" = '--'], + [if test "${_key}" = '--'], [then], _INDENT_MORE( [_positionals_index=$((_positionals_index + 1))], @@ -914,7 +916,7 @@ m4_define([_EVAL_OPTIONALS_AND_POSITIONALS_POSIX], [m4_do( m4_define([_MAKE_CASE_STATEMENT], [m4_do( - [_INDENT_(2)[case "$_key" in + [_INDENT_(2)[case "${_key}" in ]], [m4_lists_foreach_optional([_ARGS_LONG,_ARGS_SHORT,_ARGS_CATH,_ARGS_DEFAULT,_ARGS_VARNAME], [_argname,_arg_short,_arg_type,_default,_arg_varname], [_MAKE_OPTARG_CASE_SECTIONS(_argname, _arg_short, _arg_type, _default, _arg_varname)])], @@ -930,7 +932,7 @@ m4_define([_EVAL_OPTIONALS_GETOPTS], [m4_do( m4_define([_MAKE_POSIX_CASE_STATEMENT], [m4_do( - [_INDENT_(2)[case "$_key" in + [_INDENT_(2)[case "${_key}" in ]], [m4_lists_foreach_optional([_ARGS_LONG,_ARGS_SHORT,_ARGS_CATH,_ARGS_DEFAULT,_ARGS_VARNAME], [_argname,_arg_short,_arg_type,_default,_arg_varname], [_MAKE_OPTARG_GETOPTS_CASE_SECTION(_argname, _arg_short, _arg_type, _default, _arg_varname)])], @@ -971,7 +973,7 @@ m4_define([_HANDLE_NON_OPTION_MATCH_POSIX], [m4_do( m4_define([_STORE_CURRENT_ARG_AS_POSITIONAL_BODY], [[_last_positional="@S|@1"], - [_positionals+=("$_last_positional")], + [_positionals+=("${_last_positional}")], [_positionals_count=$((_positionals_count + 1))]]) @@ -1013,7 +1015,7 @@ m4_define([_MAKE_LIST_OF_POSITIONAL_ASSIGNMENT_TARGETS], [m4_do( [_our_args=$(([${#_positionals[@]} - ]_pos_names_count))], [[for ((ii = 0; ii < _our_args; ii++))]], [do], - [_INDENT_()_positional_names="$_positional_names _INF_VARNAME@<:@$((ii + _INF_ARGN))@:>@"], + [_INDENT_()_positional_names="${_positional_names} _INF_VARNAME@<:@$((ii + _INF_ARGN))@:>@"], [done], )], )])], @@ -1051,7 +1053,7 @@ m4_define([_MAKE_VALUES_ASSIGNMENTS_BASE_POSIX], [m4_do( [_IF_HAVE_POSITIONAL_ARGS([m4_do( [_ENDL_()_MAKE_ASSIGN_POSITIONAL_ARGS_FUNCTION()_ENDL_(2)], )])], - [$1([parse_commandline "@S|@@"], [_positionals_count=$((@S|@# - OPTIND + 1)); _last_positional=$(eval "printf '%s' \"\@S|@@S|@#\""); handle_passed_args_count], [assign_positional_args "$OPTIND" "@S|@@"])], + [$1([parse_commandline "@S|@@"], [_positionals_count=$((@S|@# - OPTIND + 1)); _last_positional=$(eval "printf '%s' \"\@S|@@S|@#\""); handle_passed_args_count], [assign_positional_args "${OPTIND}" "@S|@@"])], )]) @@ -1328,9 +1330,9 @@ dnl $1: The short option m4_define([_PASS_WHEN_GETOPT], [m4_ifnblank([$1], [m4_do( [_IF_OPT_GROUPING_GETOPT( [[[_next="${_key##-$1}"]], - [[if test -n "$_next" -a "$_next" != "$_key"]], + [[if test -n "${_next}" -a "${_next}" != "${_key}"]], [[then]], - [_INDENT_()[{ begins_with_short_option "$_next" && shift && set -- "-$1" "-${_next}" "@S|@@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option."]], + [_INDENT_()[{ begins_with_short_option "${_next}" && shift && set -- "-$1" "-${_next}" "@S|@@"; } || die "The short option '${_key}' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option."]], [[fi]]])], )])]) diff --git a/src/value_validators.m4 b/src/value_validators.m4 index 3702785..fa6bae8 100644 --- a/src/value_validators.m4 +++ b/src/value_validators.m4 @@ -129,11 +129,11 @@ m4_define([_MK_VALIDATE_GROUP_FUNCTION], [MAKE_BASH_FUNCTION(, [for element in "${_allowed@<:@@@:>@}"], [do], m4_ifnblank([$2], - [[_INDENT_()test "$element" = "$_seeking" && { test "@S|@3" = "idx" && echo "$_idx" || echo "$element"; } && return 0], + [[_INDENT_()test "${element}" = "${_seeking}" && { test "@S|@3" = "idx" && echo "${_idx}" || echo "${element}"; } && return 0], [_INDENT_()_idx=$((_idx + 1))],], - [[_INDENT_()test "$element" = "$_seeking" && echo "$element" && return 0],]) + [[_INDENT_()test "${element}" = "${_seeking}" && echo "${element}" && return 0],]) [done], - [die "Value '$_seeking' (of argument '@S|@2') doesn't match the list of allowed values: m4_list_join([_LIST_$1], [, ], ', ', [ and ])" 4], + [die "Value '${_seeking}' (of argument '@S|@2') doesn't match the list of allowed values: m4_list_join([_LIST_$1], [, ], ', ', [ and ])" 4], )], [_allowed=(m4_list_join([_LIST_$1_QUOTED], [ ]))], [_seeking="@S|@1"], diff --git a/tests/regressiontests/Makefile b/tests/regressiontests/Makefile index edb8685..536a743 100644 --- a/tests/regressiontests/Makefile +++ b/tests/regressiontests/Makefile @@ -493,7 +493,7 @@ test-progs: $(TESTDIR)/test-progs.sh ERROR="fulala doesnt exist" $(REVERSE) $< $< 2>&1 | grep fulala | grep -q exist FULALA=make $< - ERROR="make doesnt work" MAKE=false FULALA=make $(REVERSE) $< + ERROR="make doesn't work" MAKE=false FULALA=make $(REVERSE) $< $< -h | grep fulala | grep -q FULALA test -z "$(SHELLCHECK)" || $(SHELLCHECK) "$(TESTDIR)/test-progs.sh" test-prog: $(TESTDIR)/test-prog.sh @@ -502,7 +502,7 @@ test-prog: $(TESTDIR)/test-prog.sh $< 2>&1 | grep fulala | grep -q exist FULALA=make $< $< -h | grep fulala | grep -q FULALA - ERROR="fulala doesnt work" FULALA=false $(REVERSE) $< + ERROR="fulala doesn't work" FULALA=false $(REVERSE) $< test -z "$(SHELLCHECK)" || $(SHELLCHECK) "$(TESTDIR)/test-prog.sh" test-infinity: $(TESTDIR)/test-infinity.sh $< | grep -q 'POS_S=first,second,third,' @@ -649,7 +649,7 @@ $(TESTDIR)/test-init_simple-s-update.m4: $(ARGBASH_INIT) $(TESTDIR)/regenerate-t $(ARGBASH_INIT_EXEC) --opt ordnung -s $@ > /dev/null sed -i '2 s|^|# shellcheck source=$(basename $@)-parsing.sh\n|' $@ sed -i 's/^echo .*//' $@ - echo 'test "$$_arg_ordnung" = yes || exit 1' >> $@ + echo 'test "$${_arg_ordnung}" = yes || exit 1' >> $@ test-init_simple-s-update: $(TESTDIR)/test-init_simple-s-update.sh @# Regenerate everyting during the next test run diff --git a/tests/regressiontests/basic.m4 b/tests/regressiontests/basic.m4 index ac3df20..9127c44 100644 --- a/tests/regressiontests/basic.m4 +++ b/tests/regressiontests/basic.m4 @@ -26,6 +26,6 @@ m4_define([opt_arg_help], [m4_fatal([The option 'opt_arg' help string got expand # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "BOOL=$_arg_boo_l,OPT_S=$_arg_opt_arg,POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,OPT_INCR=$_arg_opt_incr," +echo "BOOL=${_arg_boo_l},OPT_S=${_arg_opt_arg},POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},OPT_INCR=${_arg_opt_incr}," # closing escape square bracket: ] diff --git a/tests/regressiontests/call-salone.m4 b/tests/regressiontests/call-salone.m4 index b6a349e..ab0a7b9 100644 --- a/tests/regressiontests/call-salone.m4 +++ b/tests/regressiontests/call-salone.m4 @@ -8,6 +8,6 @@ # [ <-- needed because of Argbash -echo "BOOL=$_arg_boo_l,OPT_S=$_arg_opt_arg,POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,OPT_INCR=$_arg_opt_incr," +echo "BOOL=${_arg_boo_l},OPT_S=${_arg_opt_arg},POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},OPT_INCR=${_arg_opt_incr}," # ] <-- needed because of Argbash diff --git a/tests/regressiontests/gen-test-more.m4 b/tests/regressiontests/gen-test-more.m4 index b64aea3..f1fd99a 100644 --- a/tests/regressiontests/gen-test-more.m4 +++ b/tests/regressiontests/gen-test-more.m4 @@ -3,4 +3,3 @@ # ARG_POSITIONAL_SINGLE([pos-arg], [@pos-arg@], [default]) # ARG_POSITIONAL_MULTI([pos-more], [@pos-more-arg@], 3, [foo], [bar]) # ARGBASH_GO - diff --git a/tests/regressiontests/make/tests/tests-base.m4 b/tests/regressiontests/make/tests/tests-base.m4 index 6ff3bb6..be7237d 100644 --- a/tests/regressiontests/make/tests/tests-base.m4 +++ b/tests/regressiontests/make/tests/tests-base.m4 @@ -276,7 +276,7 @@ ADD_TEST_BASH([test-progs], [[ ERROR="fulala doesnt exist" $(REVERSE) $< $< 2>&1 | grep fulala | grep -q exist FULALA=make $< - ERROR="make doesnt work" MAKE=false FULALA=make $(REVERSE) $< + ERROR="make doesn't work" MAKE=false FULALA=make $(REVERSE) $< $< -h | grep fulala | grep -q FULALA ]]) @@ -286,7 +286,7 @@ ADD_TEST_BASH([test-prog], [[ $< 2>&1 | grep fulala | grep -q exist FULALA=make $< $< -h | grep fulala | grep -q FULALA - ERROR="fulala doesnt work" FULALA=false $(REVERSE) $< + ERROR="fulala doesn't work" FULALA=false $(REVERSE) $< ]]) ADD_TEST_BASH([test-infinity], [[ diff --git a/tests/regressiontests/make/tests/tests-init.m4 b/tests/regressiontests/make/tests/tests-init.m4 index e5323c1..739ec0b 100644 --- a/tests/regressiontests/make/tests/tests-init.m4 +++ b/tests/regressiontests/make/tests/tests-init.m4 @@ -46,7 +46,7 @@ ADD_RULE([$(TESTDIR)/test-init_simple-s-update.m4], [$(ARGBASH_INIT) $(TESTDIR)/ [$(ARGBASH_INIT_EXEC) --opt ordnung -s $@ > /dev/null sed -i '2 s|^|# shellcheck source=$(basename $@)-parsing.sh\n|' $@ sed -i 's/^echo .*//' $@ - echo 'test "$$_arg_ordnung" = yes || exit 1' >> $@ + echo 'test "$${_arg_ordnung}" = yes || exit 1' >> $@ ]) dnl diff --git a/tests/regressiontests/reverse b/tests/regressiontests/reverse index 34f92bc..ac8b891 100755 --- a/tests/regressiontests/reverse +++ b/tests/regressiontests/reverse @@ -1,27 +1,23 @@ #!/bin/bash -if test -n "$ERROR" -then +if test -n "${ERROR}"; then ERRSTRING="$("$@" 2>&1)" else "$@" fi -if test $? = 0 -then +if test $? = 0; then echo "Error expected, but it did not occur" >&2 exit 1 # We don't care what the error string should look like -elif test -z "$ERROR" -then +elif test -z "${ERROR}"; then exit 0 # We examine the error string else - if echo "$ERRSTRING" | grep -q "$ERROR" - then + if echo "${ERRSTRING}" | grep -q "${ERROR}"; then exit 0 else - echo "Error occured, but not a good one:" >&2 + echo "Error occurred, but not the expected error:" >&2 "$@" fi fi diff --git a/tests/regressiontests/test-ddash-old.m4 b/tests/regressiontests/test-ddash-old.m4 index 45e89f5..2f9a75f 100644 --- a/tests/regressiontests/test-ddash-old.m4 +++ b/tests/regressiontests/test-ddash-old.m4 @@ -10,7 +10,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "BOOL=$_ARG_BOO_L,POS_OPT=$_ARG_POS_OPT," +echo "BOOL=${_ARG_BOO_L},POS_OPT=${_ARG_POS_OPT}," # closing escape square bracket: ] - diff --git a/tests/regressiontests/test-delim-both.m4 b/tests/regressiontests/test-delim-both.m4 index efb2af3..05457ee 100644 --- a/tests/regressiontests/test-delim-both.m4 +++ b/tests/regressiontests/test-delim-both.m4 @@ -10,8 +10,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "OPT_S=$_arg_opt,OPT_REP=${_arg_add[*]}," +echo "OPT_S=${_arg_opt},OPT_REP=${_arg_add[*]}," # closing escape square bracket: ] - - diff --git a/tests/regressiontests/test-delim-equals.m4 b/tests/regressiontests/test-delim-equals.m4 index b7c46b2..cf8724a 100644 --- a/tests/regressiontests/test-delim-equals.m4 +++ b/tests/regressiontests/test-delim-equals.m4 @@ -11,8 +11,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "OPT_S=$_arg_opt,XXX=$_arg_xxx,OPT_REP=${_arg_add[*]}," +echo "OPT_S=${_arg_opt},XXX=${_arg_xxx},OPT_REP=${_arg_add[*]}," # closing escape square bracket: ] - - diff --git a/tests/regressiontests/test-delim-space.m4 b/tests/regressiontests/test-delim-space.m4 index 88eefea..43e2b50 100644 --- a/tests/regressiontests/test-delim-space.m4 +++ b/tests/regressiontests/test-delim-space.m4 @@ -10,7 +10,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "OPT_S=$_arg_opt,OPT_REP=${_arg_add[*]}," +echo "OPT_S=${_arg_opt},OPT_REP=${_arg_add[*]}," # closing escape square bracket: ] - diff --git a/tests/regressiontests/test-env-base.m4 b/tests/regressiontests/test-env-base.m4 index 0899fe5..d435fa9 100644 --- a/tests/regressiontests/test-env-base.m4 +++ b/tests/regressiontests/test-env-base.m4 @@ -5,4 +5,6 @@ # ARG_HELP() # ARGBASH_GO -echo "ENVI_FOO=$ENVI_FOO,ENVI_BAR=$ENVI_BAR," +# Assume ENVI_BAR is set by the environment +# shellcheck disable=2154 +echo "ENVI_FOO=${ENVI_FOO},ENVI_BAR=${ENVI_BAR}," diff --git a/tests/regressiontests/test-env-simple.m4 b/tests/regressiontests/test-env-simple.m4 index e32a5da..bd4cb4c 100644 --- a/tests/regressiontests/test-env-simple.m4 +++ b/tests/regressiontests/test-env-simple.m4 @@ -4,4 +4,4 @@ # ARG_HELP() # ARGBASH_GO -echo "ENVI_FOO=$ENVI_FOO," +echo "ENVI_FOO=${ENVI_FOO}," diff --git a/tests/regressiontests/test-group-idx.m4 b/tests/regressiontests/test-group-idx.m4 index 3b0599b..78f4733 100644 --- a/tests/regressiontests/test-group-idx.m4 +++ b/tests/regressiontests/test-group-idx.m4 @@ -11,6 +11,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "ACT=$_arg_act_ion,IDX=$_arg_act_ion_index,OPT=$_arg_opt_tion,IDX2=$_arg_opt_tion_index," +echo "ACT=${_arg_act_ion},IDX=${_arg_act_ion_index},OPT=${_arg_opt_tion},IDX2=${_arg_opt_tion_index}," # closing escape square bracket: ] diff --git a/tests/regressiontests/test-group.m4 b/tests/regressiontests/test-group.m4 index 48deaa9..2490877 100644 --- a/tests/regressiontests/test-group.m4 +++ b/tests/regressiontests/test-group.m4 @@ -11,6 +11,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "ACT=$_arg_act_ion,REP=${_arg_repeated[*]}" +echo "ACT=${_arg_act_ion},REP=${_arg_repeated[*]}" #] diff --git a/tests/regressiontests/test-infinity-minimal_call.m4 b/tests/regressiontests/test-infinity-minimal_call.m4 index 271fa77..4174e0d 100644 --- a/tests/regressiontests/test-infinity-minimal_call.m4 +++ b/tests/regressiontests/test-infinity-minimal_call.m4 @@ -9,8 +9,7 @@ # sometimes after a basic validation echo -n POS_S= -for val in "${_arg_pos_arg[@]}"; do echo -n "$val,"; done +for val in "${_arg_pos_arg[@]}"; do echo -n "${val},"; done echo # closing escape square bracket: ] - diff --git a/tests/regressiontests/test-infinity-mixed.m4 b/tests/regressiontests/test-infinity-mixed.m4 index 4dea980..c314a60 100644 --- a/tests/regressiontests/test-infinity-mixed.m4 +++ b/tests/regressiontests/test-infinity-mixed.m4 @@ -12,8 +12,7 @@ set -e # sometimes after a basic validation echo -n POS_S= -for val in "${_arg_pos_arg[@]}"; do echo -n "$val,"; done +for val in "${_arg_pos_arg[@]}"; do echo -n "${val},"; done echo # closing escape square bracket: ] - diff --git a/tests/regressiontests/test-infinity-nodefaults.m4 b/tests/regressiontests/test-infinity-nodefaults.m4 index b8b3ab0..8777de9 100644 --- a/tests/regressiontests/test-infinity-nodefaults.m4 +++ b/tests/regressiontests/test-infinity-nodefaults.m4 @@ -9,8 +9,7 @@ # sometimes after a basic validation echo -n POS_S= -for val in "${_arg_pos_arg[@]}"; do echo -n "$val,"; done +for val in "${_arg_pos_arg[@]}"; do echo -n "${val},"; done echo # closing escape square bracket: ] - diff --git a/tests/regressiontests/test-infinity.m4 b/tests/regressiontests/test-infinity.m4 index a3559ff..59a1843 100644 --- a/tests/regressiontests/test-infinity.m4 +++ b/tests/regressiontests/test-infinity.m4 @@ -9,7 +9,7 @@ # sometimes after a basic validation echo -n POS_S= -for val in "${_arg_pos_arg[@]}"; do echo -n "$val,"; done +for val in "${_arg_pos_arg[@]}"; do echo -n "${val},"; done echo # closing escape square bracket: ] diff --git a/tests/regressiontests/test-int.m4 b/tests/regressiontests/test-int.m4 index c502d12..8e2791d 100644 --- a/tests/regressiontests/test-int.m4 +++ b/tests/regressiontests/test-int.m4 @@ -14,6 +14,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "POS_S=$_arg_pos_arg,OPT_S=$_arg_int,NN=$_arg_nnint,P=$_arg_pint," +echo "POS_S=${_arg_pos_arg},OPT_S=${_arg_int},NN=${_arg_nnint},P=${_arg_pint}," # closing escape square bracket: ] diff --git a/tests/regressiontests/test-leftovers.m4 b/tests/regressiontests/test-leftovers.m4 index 44f2e23..e082373 100644 --- a/tests/regressiontests/test-leftovers.m4 +++ b/tests/regressiontests/test-leftovers.m4 @@ -14,9 +14,9 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo -n "MORE=$_arg_more,OPT_S=$_arg_cosi,FEAR=$_arg_fear,POS_S=$_arg_another,LEFTOVERS=" -for val in "${_arg_leftovers[@]}" - do echo -n "$val," +echo -n "MORE=${_arg_more},OPT_S=${_arg_cosi},FEAR=${_arg_fear},POS_S=${_arg_another},LEFTOVERS=" +for val in "${_arg_leftovers[@]}"; do + echo -n "${val}," done echo diff --git a/tests/regressiontests/test-more.m4 b/tests/regressiontests/test-more.m4 index 6d48ebf..b6cfefc 100644 --- a/tests/regressiontests/test-more.m4 +++ b/tests/regressiontests/test-more.m4 @@ -9,6 +9,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "POS_S=$_arg_pos_arg,POS_MORE=${_arg_pos_more[*]}," +echo "POS_S=${_arg_pos_arg},POS_MORE=${_arg_pos_more[*]}," # closing escape square bracket: ] diff --git a/tests/regressiontests/test-onlyopt.m4 b/tests/regressiontests/test-onlyopt.m4 index 19eefa3..98f98d0 100644 --- a/tests/regressiontests/test-onlyopt.m4 +++ b/tests/regressiontests/test-onlyopt.m4 @@ -17,7 +17,7 @@ if_not_posix([# ARG_OPTIONAL_REPEATED([opt-repeated], r, [@opt-repeated@])]) # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "BOOL=$_arg_boo_l,OPT_S=$_arg_opt_arg,OPT_INCR=$_arg_incrx,]if_not_posix([[ARG_REPEATED=${_arg_opt_repeated[*]},]])[" +echo "BOOL=${_arg_boo_l},OPT_S=${_arg_opt_arg},OPT_INCR=${_arg_incrx},]if_not_posix([[ARG_REPEATED=${_arg_opt_repeated[*]},]])[" # closing escape square bracket: ] diff --git a/tests/regressiontests/test-onlypos-declared.m4 b/tests/regressiontests/test-onlypos-declared.m4 index 4cf8cda..ab33897 100644 --- a/tests/regressiontests/test-onlypos-declared.m4 +++ b/tests/regressiontests/test-onlypos-declared.m4 @@ -9,6 +9,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt," +echo "POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt}," # closing escape square bracket: ] diff --git a/tests/regressiontests/test-onlypos.m4 b/tests/regressiontests/test-onlypos.m4 index d00f52a..1bcb5df 100644 --- a/tests/regressiontests/test-onlypos.m4 +++ b/tests/regressiontests/test-onlypos.m4 @@ -12,6 +12,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt," +echo "POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt}," # closing escape square bracket: ] diff --git a/tests/regressiontests/test-prog.m4 b/tests/regressiontests/test-prog.m4 index c5c40b9..42dc41d 100644 --- a/tests/regressiontests/test-prog.m4 +++ b/tests/regressiontests/test-prog.m4 @@ -7,7 +7,7 @@ # [ <-- needed because of Argbash -"$FULALA" --version > /dev/null || die "fulala doesnt work" +"${FULALA}" --version > /dev/null || die "fulala doesn't work" # ] <-- needed because of Argbash m4_ifdef([m4_esyscmd], [m4_fatal([The m4_esyscmd macro is enabled!])]) diff --git a/tests/regressiontests/test-progs.m4 b/tests/regressiontests/test-progs.m4 index 90837a6..588386c 100644 --- a/tests/regressiontests/test-progs.m4 +++ b/tests/regressiontests/test-progs.m4 @@ -8,7 +8,9 @@ # [ <-- needed because of Argbash -"$MAKE" --version > /dev/null || die "make doesnt work" +# Expecting make to come from the environment +# shellcheck disable=SC2154 +"${MAKE}" --version > /dev/null || die "make doesn't work" # ] <-- needed because of Argbash m4_ifdef([m4_esyscmd], [m4_fatal([The m4_esyscmd macro is enabled!])]) diff --git a/tests/regressiontests/test-simple.m4 b/tests/regressiontests/test-simple.m4 index d45d3fd..1f741d1 100644 --- a/tests/regressiontests/test-simple.m4 +++ b/tests/regressiontests/test-simple.m4 @@ -12,7 +12,7 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "OPT_S=$_arg_prefix,POS_S=$_arg_pos_arg,LA=$_arg_la," +echo "OPT_S=${_arg_prefix},POS_S=${_arg_pos_arg},LA=${_arg_la}," # ] <-- needed because of Argbash m4_ifdef([m4_esyscmd], [m4_fatal([The m4_esyscmd macro is enabled!])]) diff --git a/tests/regressiontests/test-wrapping-excl.m4 b/tests/regressiontests/test-wrapping-excl.m4 index 4ed79ea..f0a4459 100644 --- a/tests/regressiontests/test-wrapping-excl.m4 +++ b/tests/regressiontests/test-wrapping-excl.m4 @@ -8,7 +8,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,CMDLINE_ONLYPOS=${_args_test_onlypos[*]}" +echo "POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},CMDLINE_ONLYPOS=${_args_test_onlypos[*]}" # closing escape square bracket: ] - diff --git a/tests/regressiontests/test-wrapping-more.m4 b/tests/regressiontests/test-wrapping-more.m4 index c2d6457..309190e 100644 --- a/tests/regressiontests/test-wrapping-more.m4 +++ b/tests/regressiontests/test-wrapping-more.m4 @@ -8,7 +8,6 @@ # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "OPT_INCR=$_arg_incrx,CMDLINE=${_args_test_onlyopt[*]}," +echo "OPT_INCR=${_arg_incrx},CMDLINE=${_args_test_onlyopt[*]}," # closing escape square bracket: ] - diff --git a/tests/regressiontests/test-wrapping-otherdir.m4 b/tests/regressiontests/test-wrapping-otherdir.m4 index f822fd6..061586c 100644 --- a/tests/regressiontests/test-wrapping-otherdir.m4 +++ b/tests/regressiontests/test-wrapping-otherdir.m4 @@ -13,7 +13,7 @@ m4_define(_DEFAULT_WRAP_FLAGS, []) # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "POS_S0=$_arg_pos_arg0,POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,OPT_S=$_arg_opt_arg,POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,OPT_INCR=$_arg_incrx,CMDLINE=${_args_test_onlyopt[*]} ${_args_test_onlypos[*]}," +echo "POS_S0=${_arg_pos_arg0},POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},OPT_S=${_arg_opt_arg},POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},OPT_INCR=${_arg_incrx},CMDLINE=${_args_test_onlyopt[*]} ${_args_test_onlypos[*]}," # closing escape square bracket: ] diff --git a/tests/regressiontests/test-wrapping-second_level.m4 b/tests/regressiontests/test-wrapping-second_level.m4 index 739f1d2..d8aabe4 100644 --- a/tests/regressiontests/test-wrapping-second_level.m4 +++ b/tests/regressiontests/test-wrapping-second_level.m4 @@ -12,9 +12,9 @@ m4_define(_DEFAULT_WRAP_FLAGS, []) # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -# shellcheck disable=SC2154 # SC2154: _arg_pos_arg1 is referenced but not assigned --- this is part of the test. -echo "POS_S1=$_arg_pos_arg1,POS_S0=$_arg_pos_arg0,POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,OPT_S=$_arg_opt_arg,POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,CMDLINE=${_args_test_onlyopt[*]} ${_args_test_wrapping_single_level[*]}," +# shellcheck disable=SC2154 +echo "POS_S1=${_arg_pos_arg1},POS_S0=${_arg_pos_arg0},POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},OPT_S=${_arg_opt_arg},POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},CMDLINE=${_args_test_onlyopt[*]} ${_args_test_wrapping_single_level[*]}," # closing escape square bracket: ] diff --git a/tests/regressiontests/test-wrapping.m4 b/tests/regressiontests/test-wrapping.m4 index 0afe00c..5a6fe38 100644 --- a/tests/regressiontests/test-wrapping.m4 +++ b/tests/regressiontests/test-wrapping.m4 @@ -13,6 +13,6 @@ m4_define(_DEFAULT_WRAP_FLAGS, []) # Now we take the parsed data and assign them no nice-looking variable names, # sometimes after a basic validation -echo "POS_S0=$_arg_pos_arg0,POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,OPT_S=$_arg_opt_arg,POS_S=$_arg_pos_arg,POS_OPT=$_arg_pos_opt,OPT_INCR=$_arg_incrx,CMDLINE=${_args_test_onlyopt[*]} ${_args_test_onlypos[*]}," +echo "POS_S0=${_arg_pos_arg0},POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},OPT_S=${_arg_opt_arg},POS_S=${_arg_pos_arg},POS_OPT=${_arg_pos_opt},OPT_INCR=${_arg_incrx},CMDLINE=${_args_test_onlyopt[*]} ${_args_test_onlypos[*]}," # closing escape square bracket: ] From dd1a7b1ee2a8299d9c8e63e89aa0ee049ec44458 Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Sat, 26 Sep 2020 10:27:28 -0700 Subject: [PATCH 02/12] Update src/argbash-1to2.m4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Týč --- src/argbash-1to2.m4 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/argbash-1to2.m4 b/src/argbash-1to2.m4 index c06d283..1bb86ed 100644 --- a/src/argbash-1to2.m4 +++ b/src/argbash-1to2.m4 @@ -33,10 +33,7 @@ test "${#infname[@]}" -gt 1 && test -n "${outfname}" && die "You have specified trap cleanup EXIT for infname in "${_arg_input[@]}"; do - test -f "${infname}" || { - echo "The input parameter has to be a file (got: '${infname}')" >&2 - exit 1 - } + test -f "${infname}" || die "The input parameter has to be a file (got: '${infname}')" test -n "${_arg_output}" || outfname="${infname}" if test "${outfname}" = '-'; then From 0ffbd1ee0dd1c42afbd91d1c45b834555d82d7fe Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Sat, 26 Sep 2020 11:00:07 -0700 Subject: [PATCH 03/12] Clean based on comments Fixed comments to pull request Cleaned up warning during make install Added files to gitignore --- .gitignore | 5 +++++ bin/argbash | 3 +-- bin/argbash-1to2 | 5 +---- bin/argbash-init | 5 ++++- resources/Makefile | 2 ++ resources/argbash-defs.rst | 2 ++ resources/examples/simple-parsing.m4 | 2 +- resources/examples/simple-parsing.sh | 4 +--- resources/examples/simple-standalone.m4 | 2 +- resources/examples/simple-standalone.sh | 4 +--- src/argbash-init.m4 | 5 ++++- src/argbash.m4 | 3 +-- 12 files changed, 24 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 0c87168..048c793 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,8 @@ tests/regressiontests/test.sh doc/_build resources/packages/build +resources/examples/simple-standalone +resources/examples/simple-parsing +resources/examples/minimal.sh +resources/argbash.rst +resources/argbash.1.gz diff --git a/bin/argbash b/bin/argbash index c12495f..acfc5cb 100755 --- a/bin/argbash +++ b/bin/argbash @@ -264,8 +264,7 @@ cleanup() # $1: What (string) to pipe to autom4te run_autom4te() { - printf '%s\n' "$1" | - autom4te "${DEBUG[@]}" -l m4sugar -I "${m4dir}" + printf '%s\n' "$1" | autom4te "${DEBUG[@]}" -l m4sugar -I "${m4dir}" return $? } diff --git a/bin/argbash-1to2 b/bin/argbash-1to2 index 66141e2..9bb0172 100755 --- a/bin/argbash-1to2 +++ b/bin/argbash-1to2 @@ -152,10 +152,7 @@ test "${#infname[@]}" -gt 1 && test -n "${outfname}" && die "You have specified trap cleanup EXIT for infname in "${_arg_input[@]}"; do - test -f "${infname}" || { - echo "The input parameter has to be a file (got: '${infname}')" >&2 - exit 1 - } + test -f "${infname}" || die "The input parameter has to be a file (got: '${infname}')" test -n "${_arg_output}" || outfname="${infname}" if test "${outfname}" = '-'; then diff --git a/bin/argbash-init b/bin/argbash-init index 74e10eb..bb1d28c 100755 --- a/bin/argbash-init +++ b/bin/argbash-init @@ -208,9 +208,12 @@ assign_positional_args 1 "${_positionals[@]}" _variables=() HAVE_POSITIONAL_ARG=no -# This should be in sync with _translate_var in stuff.m4 +# This should be in sync with _translate_var in collectors.m4 _translate_var() { + # Single quotes so we don't need to escape the variable name here + # This is taking the original name, adding ${ to the front, } to + # the end, replacing - with _ and making it lowercase printf '${_arg_%s}' "$1" | tr '[:upper:]' '[:lower:]' | tr '-' '_' } diff --git a/resources/Makefile b/resources/Makefile index f8420b9..6d42b6f 100644 --- a/resources/Makefile +++ b/resources/Makefile @@ -59,6 +59,8 @@ EXAMPLES = \ examples/minimal.sh \ examples/simple.sh \ examples/simple-wrapper.sh \ + examples/simple-standalone \ + examples/simple-parsing \ $(NUL) ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) diff --git a/resources/argbash-defs.rst b/resources/argbash-defs.rst index feb592b..fe92c21 100644 --- a/resources/argbash-defs.rst +++ b/resources/argbash-defs.rst @@ -12,6 +12,8 @@ .. |OPTION_OUTPUT| replace:: \ +.. |OPTION_IN_PLACE| replace:: \ + .. |OPTION_TYPE| replace:: Check out the documentation to learn about all argbash capabilities that are supported. .. |OPTION_LIBRARY| replace:: This option is deprecated and it is the same as ``--strip user-content``. diff --git a/resources/examples/simple-parsing.m4 b/resources/examples/simple-parsing.m4 index 5d4705b..884a120 100644 --- a/resources/examples/simple-parsing.m4 +++ b/resources/examples/simple-parsing.m4 @@ -1,5 +1,5 @@ #!/bin/bash -#foo + # ARG_POSITIONAL_SINGLE([filename]) # ARG_OPTIONAL_SINGLE([unit], u, [What unit we accept (b for bytes, k for kibibytes, M for mebibytes)], b) # ARG_VERSION([echo $0 v0.1]) diff --git a/resources/examples/simple-parsing.sh b/resources/examples/simple-parsing.sh index 6b2bb79..52b8492 100755 --- a/resources/examples/simple-parsing.sh +++ b/resources/examples/simple-parsing.sh @@ -1,5 +1,5 @@ #!/bin/bash -#foo + # ARG_POSITIONAL_SINGLE([filename]) # ARG_OPTIONAL_SINGLE([unit],[u],[What unit we accept (b for bytes, k for kibibytes, M for mebibytes)],[b]) # ARG_VERSION([echo $0 v0.1]) @@ -124,5 +124,3 @@ assign_positional_args 1 "${_positionals[@]}" # OTHER STUFF GENERATED BY Argbash ### END OF CODE GENERATED BY Argbash (sortof) ### ]) -# [ <-- needed because of Argbash -# ] <-- needed because of Argbash diff --git a/resources/examples/simple-standalone.m4 b/resources/examples/simple-standalone.m4 index 07b0db9..59e674e 100644 --- a/resources/examples/simple-standalone.m4 +++ b/resources/examples/simple-standalone.m4 @@ -1,5 +1,5 @@ #!/bin/bash -#foo + # ARG_POSITIONAL_SINGLE([filename]) # ARG_OPTIONAL_SINGLE([unit], u, [What unit we accept (b for bytes, k for kilobytes, M for megabytes)], b) # ARG_VERSION([echo "$0 v0.1"]) diff --git a/resources/examples/simple-standalone.sh b/resources/examples/simple-standalone.sh index a01a134..12110b6 100755 --- a/resources/examples/simple-standalone.sh +++ b/resources/examples/simple-standalone.sh @@ -1,5 +1,5 @@ #!/bin/bash -#foo + # ARG_POSITIONAL_SINGLE([filename]) # ARG_OPTIONAL_SINGLE([unit],[u],[What unit we accept (b for bytes, k for kilobytes, M for megabytes)],[b]) # ARG_VERSION([echo "$0 v0.1"]) @@ -123,5 +123,3 @@ assign_positional_args 1 "${_positionals[@]}" # OTHER STUFF GENERATED BY Argbash ### END OF CODE GENERATED BY Argbash (sortof) ### ]) -# [ <-- needed because of Argbash -# ] <-- needed because of Argbash diff --git a/src/argbash-init.m4 b/src/argbash-init.m4 index 86c643f..ed00957 100644 --- a/src/argbash-init.m4 +++ b/src/argbash-init.m4 @@ -22,9 +22,12 @@ version=_ARGBASH_VERSION _variables=() HAVE_POSITIONAL_ARG=no -# This should be in sync with _translate_var in stuff.m4 +# This should be in sync with _translate_var in collectors.m4 _translate_var() { + # Single quotes so we don't need to escape the variable name here + # This is taking the original name, adding ${ to the front, } to + # the end, replacing - with _ and making it lowercase printf '${_arg_%s}' "$1" | tr '[:upper:]' '[:lower:]' | tr '-' '_' } diff --git a/src/argbash.m4 b/src/argbash.m4 index 8aa8186..ee91cf5 100644 --- a/src/argbash.m4 +++ b/src/argbash.m4 @@ -34,8 +34,7 @@ cleanup() # $1: What (string) to pipe to autom4te run_autom4te() { - printf '%s\n' "$1" | - autom4te "${DEBUG[@]}" -l m4sugar -I "${m4dir}" + printf '%s\n' "$1" | autom4te "${DEBUG[@]}" -l m4sugar -I "${m4dir}" return $? } From 9f3f0a296f9303ba2dadb4baca63e525c9d88b50 Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Sat, 26 Sep 2020 11:11:34 -0700 Subject: [PATCH 04/12] Adding to authors and changelog --- AUTHORS | 1 + ChangeLog | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index aaa6218..7222bc0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,3 +3,4 @@ Conduitry Felipe Santos Matěj Týč Stephen Gallagher +Scott Atkins \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index 22fe098..44d52d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,20 @@ 2.10.1 (TBA) ------------------- +Bugfixes: + +* Warning during make install +* Typos and spelling mistakes +* Examples missing from build + +New features: + +* Compliant with optional checks for ShellCheck (most notably the require-variable-braces check) 2.10.0 (2020-09-22) ------------------- -Buxfixes: +Bugfixes: * `argbash-init` is able to handle empty string as the only argument without being puzzled (#130). * Error handling of script working directory detection now more robust (#134). @@ -19,9 +28,9 @@ New features: 2.9.0 (2020-08-01) ------------------ -Buxfixes: +Bugfixes: -* Fixed typo in `argbash-init` and updated obsolete/incaccurate hints (#97). +* Fixed typo in `argbash-init` and updated obsolete/inaccurate hints (#97). * Fixed incorrect permission of non-script output files (#104). * Increased MacOS compatibility by removing terminator from the `chmod` invocation (#107). From 8d1d6147601fc5fae056b6075db927f79ed82fc5 Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Sat, 3 Oct 2020 16:25:56 -0700 Subject: [PATCH 05/12] Applying whitespace style + VSCode Tasks --- .vscode/settings.json | 7 ++++++- .vscode/tasks.json | 22 ++++++++++++++++++++++ bin/argbash | 20 +++++++++++++++++--- bin/argbash-1to2 | 2 ++ bin/argbash-init | 31 +++++++++++++++++++++++++------ resources/examples/minimal.m4 | 19 +++++++------------ src/argbash-1to2.m4 | 2 ++ src/argbash-init.m4 | 31 +++++++++++++++++++++++++------ src/argbash.m4 | 20 +++++++++++++++++--- src/collectors.m4 | 14 +++++++------- src/default_settings.m4 | 2 ++ src/docopt.m4 | 2 ++ src/function_generators.m4 | 2 -- src/list.m4 | 8 ++++++++ src/output-completion.m4 | 6 +++--- src/output-manpage-defs.m4 | 1 + src/output-manpage.m4 | 1 + src/stuff.m4 | 1 + src/utilities.m4 | 9 ++++++++- 19 files changed, 156 insertions(+), 44 deletions(-) create mode 100644 .vscode/tasks.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 8ae007a..e851dfa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,8 @@ { "cSpell.words": [ "ARGBASH", + "DELIM", + "FUNCNAME", "SPURIONS", "alnum", "autom", @@ -13,6 +15,7 @@ "errstr", "eval", "fname", + "getopt", "infile", "infname", "lolo", @@ -21,12 +24,14 @@ "outfname", "positionals", "posix", + "readlink", "searchdir", "shfile", "sortof", "srcfile", "srcfiles", "srcstem", - "thatfile" + "thatfile", + "translit" ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..4fbb881 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,22 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Make Checks", + "type": "shell", + "command": "make check", + "options": { + "cwd": "${cwd}/resources" + } + }, { + "label": "Make Examples", + "type": "shell", + "command": "make examples", + "options": { + "cwd": "${cwd}/resources" + } + } + ] +} \ No newline at end of file diff --git a/bin/argbash b/bin/argbash index acfc5cb..dc9e8e9 100755 --- a/bin/argbash +++ b/bin/argbash @@ -4,6 +4,7 @@ # SC2016: Expressions don't expand in single quotes, use double quotes for that. # SC2059 Don't use variables in the printf format string. + # DEFINE_SCRIPT_DIR() # ARG_POSITIONAL_SINGLE([input],[The input template file (pass '-' for stdin)]) # ARG_OPTIONAL_SINGLE([output],[o],[Name of the output file (pass '-' for stdout)],[-]) @@ -20,7 +21,6 @@ # ARG_DEFAULTS_POS([]) # ARG_HELP([Argbash is an argument parser generator for Bash.]) # ARG_VERSION_AUTO([_ARGBASH_VERSION]) - # ARGBASH_GO() # needed because of Argbash --> m4_ignore([ ### START OF CODE GENERATED BY Argbash v2.10.0 one line above ### @@ -261,6 +261,7 @@ cleanup() test "${#_files_to_clean[*]}" != 0 && rm -f "${_files_to_clean[@]}" } + # $1: What (string) to pipe to autom4te run_autom4te() { @@ -268,6 +269,7 @@ run_autom4te() return $? } + # TODO: Refactor to associative arrays as soon as the argbash online is sufficiently reliable # We don't use associative arrays due to old bash compatibility reasons autom4te_error_messages=( @@ -298,12 +300,13 @@ interpret_error() done } + # $1: The input file # $2: The original intended output file define_file_metadata() { ARGBASH_INTENDED_DESTINATION="${ARGBASH_INTENDED_DESTINATION=}" - SPURIONS_OUTPUT_SUFFIX="${SPURIONS_OUTPUT_SUFFIX=}" + SPURIOUS_OUTPUT_SUFFIX="${SPURIOUS_OUTPUT_SUFFIX=}" local _defines='' _intended_destination="${ARGBASH_INTENDED_DESTINATION}" _input_dirname _output_dirname test -n "${_intended_destination}" || _intended_destination="$2" @@ -312,11 +315,12 @@ define_file_metadata() _defines="${_defines}m4_define([INPUT_ABS_DIRNAME], [[$(cd "${_input_dirname}" && pwd)]])" _output_dirname="$(dirname "${_intended_destination}")" - test "${_intended_destination}" != '-' && _defines="${_defines}m4_define([OUTPUT_BASENAME], [[$(basename "${_intended_destination}" "${SPURIONS_OUTPUT_SUFFIX}")]])" + test "${_intended_destination}" != '-' && _defines="${_defines}m4_define([OUTPUT_BASENAME], [[$(basename "${_intended_destination}" "${SPURIOUS_OUTPUT_SUFFIX}")]])" _defines="${_defines}m4_define([OUTPUT_ABS_DIRNAME], [[$(cd "${_output_dirname}" && pwd)]])" printf "%s" "${_defines}" } + # Yes both tests need to pass or we should throw out an error message # shellcheck disable=2015 assert_m4_files_are_readable() @@ -327,6 +331,7 @@ assert_m4_files_are_readable() test -r "${output_m4}" && test -f "${output_m4}" || die "The '${output_m4}' file needed by Argbash is not readable. Check whether it exists and review it's permissions." } + # The main function that generates the parsing script body # $1: The input file # $2: The output file @@ -354,6 +359,7 @@ do_stuff() return "${_ret}" } + # Fills content to variable _wrapped_defns --- where are scripts of given stems # $1: Infile # $2: Stem - what should be the umbrella of the args @@ -396,6 +402,7 @@ settle_wrapped_fname() done } + # If we want to have the parsing code in a separate file, # 1. Find out the (possible) filename # 2. If the file exists, finish (OK). @@ -427,6 +434,7 @@ get_parsing_code() echo "${_newerfile}" } + # $1: The output file # $2: The output type string set_output_permission() @@ -436,6 +444,7 @@ set_output_permission() fi } + # MS Windows compatibility fix discard=/dev/null test -e "${discard}" || discard=NUL @@ -464,6 +473,7 @@ test "${_arg_library}" = "on" && { echo "The --library option is deprecated, use --strip user-content" next time >&2 _arg_strip="user-content" } + if test "${_arg_strip}" = "user-content"; then output_m4="${m4dir}/output-strip-user-content.m4" elif test "${_arg_strip}" = "all"; then @@ -474,15 +484,18 @@ test -f "${infile}" || _PRINT_HELP=yes die "argument '${infile}' is supposed to if test "${_arg_in_place}" = on; then _arg_output="${infile}" fi + test -n "${_arg_output}" || { echo "The output can't be blank - it is not a legal filename!" >&2 exit 1 } + outfname="${_arg_output}" autom4te --version > "${discard}" 2>&1 || { echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 exit 1 } + _arg_search+=("$(dirname "${infile}")") _wrapped_defns="" @@ -504,6 +517,7 @@ if test "${_arg_check_typos}" = on; then grep_output="$(printf "%s" "${output}" | grep '^#\s*\(ARG_\|ARGBASH\)' | grep -v '^#\s*\(ARGBASH_SET_INDENT\|ARG_OPTIONAL_SINGLE\|ARG_VERSION\|ARG_VERSION_AUTO\|ARG_HELP\|ARG_OPTIONAL_INCREMENTAL\|ARG_OPTIONAL_REPEATED\|ARG_VERBOSE\|ARG_OPTIONAL_BOOLEAN\|ARG_OPTIONAL_ACTION\|ARG_POSITIONAL_SINGLE\|ARG_POSITIONAL_INF\|ARG_POSITIONAL_MULTI\|ARG_POSITIONAL_DOUBLEDASH\|ARG_OPTION_STACKING\|ARG_RESTRICT_VALUES\|ARG_DEFAULTS_POS\|ARG_LEFTOVERS\|ARGBASH_WRAP\|INCLUDE_PARSING_CODE\|DEFINE_LOAD_LIBRARY\|DEFINE_SCRIPT_DIR\|DEFINE_SCRIPT_DIR_GNU\|ARGBASH_SET_DELIM\|ARGBASH_GO\|ARGBASH_PREPARE\|ARG_TYPE_GROUP\|ARG_TYPE_GROUP_SET\|ARG_USE_ENV\|ARG_USE_PROGRAM\)\s*\((\|$\)' | sed -e 's/#\s*\([[:alnum:]_]*\).*/\1 /' | tr -d '\n\r')" test -n "${grep_output}" && die "Your script contains possible misspelled Argbash macros: ${grep_output}" 1 fi + if test "${outfname}" != '-'; then printf '%s\n' "${output}" > "${outfname}" set_output_permission "${outfname}" "${_arg_type}" diff --git a/bin/argbash-1to2 b/bin/argbash-1to2 index 9bb0172..7b48f13 100755 --- a/bin/argbash-1to2 +++ b/bin/argbash-1to2 @@ -138,6 +138,7 @@ cleanup() test "${#_files_to_clean[*]}" != 0 && rm -f "${_files_to_clean[@]}" } + do_stuff() { # SCRIPT_DIR is likely also a default, but maybe not - it may have been set explicitly @@ -147,6 +148,7 @@ do_stuff() sed 's/\(\${\?_ARGS\?_\w\+\)/\L\1\l/g' "${infname}" } + outfname="${_arg_output}" test "${#infname[@]}" -gt 1 && test -n "${outfname}" && die "You have specified more than one (${#infname[@]}) input filenames, so you probably want to modify the corresponding files in-place. In order to do so, you can't specify an output filename, even '-' does make no sense (currently: '${outfname}')" diff --git a/bin/argbash-init b/bin/argbash-init index bb1d28c..ae9f549 100755 --- a/bin/argbash-init +++ b/bin/argbash-init @@ -208,8 +208,9 @@ assign_positional_args 1 "${_positionals[@]}" _variables=() HAVE_POSITIONAL_ARG=no -# This should be in sync with _translate_var in collectors.m4 -_translate_var() + +# This should be in sync with _translit_var in collectors.m4 +_translit_var() { # Single quotes so we don't need to escape the variable name here # This is taking the original name, adding ${ to the front, } to @@ -217,55 +218,65 @@ _translate_var() printf '${_arg_%s}' "$1" | tr '[:upper:]' '[:lower:]' | tr '-' '_' } + optional_argument_without_hints() { echo "# ARG_OPTIONAL_SINGLE([$1])" } + optional_argument_with_hints() { echo "# ARG_OPTIONAL_SINGLE([$1], [], [], [])" } + optional_argument() { "${FUNCNAME[0]}_$2" "$1" - _variables+=("printf 'Value of --%s: %s\\n' '$1' \"$(_translate_var "$1")\"") + _variables+=("printf 'Value of --%s: %s\\n' '$1' \"$(_translit_var "$1")\"") } + boolean_argument_with_hints() { echo "# ARG_OPTIONAL_BOOLEAN([$1], [], [], [])" } + boolean_argument_without_hints() { echo "# ARG_OPTIONAL_BOOLEAN([$1])" } + boolean_argument() { "${FUNCNAME[0]}_$2" "$1" - _variables+=("printf \"'%s' is %s\\\\n\" '$1' \"$(_translate_var "$1")\"") + _variables+=("printf \"'%s' is %s\\\\n\" '$1' \"$(_translit_var "$1")\"") } + positional_argument_with_hints() { echo "# ARG_POSITIONAL_SINGLE([$1], [], [&2 exit 11 #)Created by argbash-init v2.10.0 -# ARG_OPTIONAL_SINGLE([option], o, [A option with short and long flags and default], [boo]) -# ARG_OPTIONAL_BOOLEAN([print], , [A boolean option with long flag (and implicit default: off)]) -# ARG_POSITIONAL_SINGLE([positional-arg], [Positional arg description], ) +# ARG_OPTIONAL_SINGLE([option]) +# ARG_OPTIONAL_BOOLEAN([print]) +# ARG_POSITIONAL_SINGLE([positional-arg]) # ARG_DEFAULTS_POS -# ARG_HELP([This is a minimal demo of Argbash potential]) -# ARG_VERSION([echo $0 v0.1]) -# ARGBASH_SET_INDENT([ ]) +# ARG_HELP([]) # ARGBASH_GO # [ <-- needed because of Argbash # vvv PLACE YOUR CODE HERE vvv # For example: -if [ "${_arg_print}" = on ]; then - echo "Positional arg value: '${_arg_positional_arg}'" - echo "Optional arg '--option' value: '${_arg_option}'" -else - echo "Not telling anything, print not requested" -fi +printf 'Value of --%s: %s\n' 'option' "${_arg_option}" +printf "'%s' is %s\\n" 'print' "${_arg_print}" +printf "Value of '%s': %s\\n" 'positional-arg' "${_arg_positional_arg}" # ^^^ TERMINATE YOUR CODE BEFORE THE BOTTOM ARGBASH MARKER ^^^ diff --git a/src/argbash-1to2.m4 b/src/argbash-1to2.m4 index 1bb86ed..8040ad8 100644 --- a/src/argbash-1to2.m4 +++ b/src/argbash-1to2.m4 @@ -19,6 +19,7 @@ cleanup() test "${#_files_to_clean[*]}" != 0 && rm -f "${_files_to_clean[@]}" } + do_stuff() { # SCRIPT_DIR is likely also a default, but maybe not - it may have been set explicitly @@ -28,6 +29,7 @@ do_stuff() sed 's/\(\${\?_ARGS\?_\w\+\)/\L\1\l/g' "${infname}" } + outfname="${_arg_output}" test "${#infname[@]}" -gt 1 && test -n "${outfname}" && die "You have specified more than one (${#infname[@]}) input filenames, so you probably want to modify the corresponding files in-place. In order to do so, you can't specify an output filename, even '-' does make no sense (currently: '${outfname}')" diff --git a/src/argbash-init.m4 b/src/argbash-init.m4 index ed00957..0e6b111 100644 --- a/src/argbash-init.m4 +++ b/src/argbash-init.m4 @@ -22,8 +22,9 @@ version=_ARGBASH_VERSION _variables=() HAVE_POSITIONAL_ARG=no -# This should be in sync with _translate_var in collectors.m4 -_translate_var() + +# This should be in sync with _translit_var in collectors.m4 +_translit_var() { # Single quotes so we don't need to escape the variable name here # This is taking the original name, adding ${ to the front, } to @@ -31,55 +32,65 @@ _translate_var() printf '${_arg_%s}' "$1" | tr '[:upper:]' '[:lower:]' | tr '-' '_' } + optional_argument_without_hints() { echo "# ARG_OPTIONAL_SINGLE([$1])" } + optional_argument_with_hints() { echo "# ARG_OPTIONAL_SINGLE([$1], [], [], [])" } + optional_argument() { "${FUNCNAME[0]}_$2" "$1" - _variables+=("printf 'Value of --%s: %s\\n' '$1' \"$(_translate_var "$1")\"") + _variables+=("printf 'Value of --%s: %s\\n' '$1' \"$(_translit_var "$1")\"") } + boolean_argument_with_hints() { echo "# ARG_OPTIONAL_BOOLEAN([$1], [], [], [])" } + boolean_argument_without_hints() { echo "# ARG_OPTIONAL_BOOLEAN([$1])" } + boolean_argument() { "${FUNCNAME[0]}_$2" "$1" - _variables+=("printf \"'%s' is %s\\\\n\" '$1' \"$(_translate_var "$1")\"") + _variables+=("printf \"'%s' is %s\\\\n\" '$1' \"$(_translit_var "$1")\"") } + positional_argument_with_hints() { echo "# ARG_POSITIONAL_SINGLE([$1], [], [&2 _arg_strip="user-content" } + if test "${_arg_strip}" = "user-content"; then output_m4="${m4dir}/output-strip-user-content.m4" elif test "${_arg_strip}" = "all"; then @@ -244,15 +254,18 @@ test -f "${infile}" || _PRINT_HELP=yes die "argument '${infile}' is supposed to if test "${_arg_in_place}" = on; then _arg_output="${infile}" fi + test -n "${_arg_output}" || { echo "The output can't be blank - it is not a legal filename!" >&2 exit 1 } + outfname="${_arg_output}" autom4te --version > "${discard}" 2>&1 || { echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 exit 1 } + _arg_search+=("$(dirname "${infile}")") _wrapped_defns="" @@ -274,6 +287,7 @@ if test "${_arg_check_typos}" = on; then grep_output="$(printf "%s" "${output}" | grep '^#\s*\(ARG_\|ARGBASH\)' | grep -v '^#\s*\(]m4_set_contents([_KNOWN_MACROS], [\|])[\)\s*\((\|$\)' | sed -e 's/#\s*\([[:alnum:]_]*\).*/\1 /' | tr -d '\n\r')" test -n "${grep_output}" && die "Your script contains possible misspelled Argbash macros: ${grep_output}" 1 fi + if test "${outfname}" != '-'; then printf '%s\n' "${output}" > "${outfname}" set_output_permission "${outfname}" "${_arg_type}" diff --git a/src/collectors.m4 b/src/collectors.m4 index 87d4429..2391921 100644 --- a/src/collectors.m4 +++ b/src/collectors.m4 @@ -57,14 +57,14 @@ m4_define([_pos_suffix], [[_pos]]) m4_define([_arg_prefix], [[_arg_]]) m4_define([_args_prefix], [[_args_]]) m4_define([_varname], [m4_do( - [m4_quote(_arg_prefix[]_translate_var([$1]))], + [m4_quote(_arg_prefix[]_translit_var([$1]))], )]) dnl dnl The operation on command names that makes stem of variable names -dnl Since each call of _translate_var etc. strips one level of quoting, we have to quote $1 more than usually -m4_define([_translate_var], [m4_translit(m4_translit([[[$1]]], [A-Z], [a-z]), [-/], [__])]) +dnl Since each call of _translit_var etc. strips one level of quoting, we have to quote $1 more than usually +m4_define([_translit_var], [m4_translit(m4_translit([[[$1]]], [A-Z], [a-z]), [-/], [__])]) m4_define([_translit_prog], [m4_translit(m4_translit([[[$1]]], [a-z], [A-Z]), [-], [_])]) @@ -116,7 +116,7 @@ m4_define([_CHECK_ARGNAME_FREE], [m4_do( m4_define([_CHECK_POSITIONAL_ARGNAME_IS_FREE], [m4_do( - [m4_pushdef([_ARG_VAR_NAME], m4_dquote(_translate_var([$1])))], + [m4_pushdef([_ARG_VAR_NAME], m4_dquote(_translit_var([$1])))], [_CHECK_ARGNAME_FREE_FATAL([$1], _ARG_VAR_NAME)], [m4_set_add([_POSITIONALS], _ARG_VAR_NAME)], [m4_popdef([_ARG_VAR_NAME])], @@ -124,7 +124,7 @@ m4_define([_CHECK_POSITIONAL_ARGNAME_IS_FREE], [m4_do( m4_define([_ENSURE_UNIQUENESS_OF_ARGUMENT_IDENTIFIER], [m4_do( - [m4_pushdef([_ARG_VAR_NAME], m4_dquote(_translate_var([$1])))], + [m4_pushdef([_ARG_VAR_NAME], m4_dquote(_translit_var([$1])))], [_CHECK_ARGNAME_FREE_FATAL([$1], _ARG_VAR_NAME)], [m4_set_add([_ARGS_LONG], _ARG_VAR_NAME)], [m4_popdef([_ARG_VAR_NAME])], @@ -171,7 +171,7 @@ dnl TODO: Take the _WRAPPED code and move it one level up dnl dnl $1 - the variable where the argument value is collected m4_define([_POS_WRAPPED], [m4_ifdef([WRAPPED_FILE_STEM], - [__POS_WRAPPED([$1], m4_expand([_args_prefix[]_translate_var(_GET_BASENAME(WRAPPED_FILE_STEM))]))], + [__POS_WRAPPED([$1], m4_expand([_args_prefix[]_translit_var(_GET_BASENAME(WRAPPED_FILE_STEM))]))], )]) m4_define([__POS_WRAPPED], [m4_do( @@ -181,7 +181,7 @@ m4_define([__POS_WRAPPED], [m4_do( )]) m4_define([_OPT_WRAPPED], [m4_ifdef([WRAPPED_FILE_STEM], - [__OPT_WRAPPED([$1], m4_expand([_args_prefix[]_translate_var(_GET_BASENAME(WRAPPED_FILE_STEM))]))], + [__OPT_WRAPPED([$1], m4_expand([_args_prefix[]_translit_var(_GET_BASENAME(WRAPPED_FILE_STEM))]))], )]) m4_define([__OPT_WRAPPED], [m4_do( diff --git a/src/default_settings.m4 b/src/default_settings.m4 index 3d6aa36..008b4f5 100644 --- a/src/default_settings.m4 +++ b/src/default_settings.m4 @@ -4,11 +4,13 @@ _SET_INDENT([ ]) _SET_OPTION_VALUE_DELIMITER([ =]) ARG_OPTION_STACKING([getopt]) + dnl Define STDOUT as m4sugar diversion 1 dnl From now on, we can write 'm4_divert_push([STDOUT])' without getting a warnings. m4_define([_m4_divert(STDOUT)], 1) m4_define([_DEFAULT_WRAP_FLAGS], [[HVI]]) + dnl dnl Just define name of the script dir variable m4_define([_DEFAULT_SCRIPTDIR], [[script_dir]]) diff --git a/src/docopt.m4 b/src/docopt.m4 index 22cd8ed..f38e61c 100644 --- a/src/docopt.m4 +++ b/src/docopt.m4 @@ -1,6 +1,7 @@ m4_include([argument_value_types.m4]) m4_include([value_validators.m4]) + dnl dnl $1: Argname m4_define([_REPRESENT_VALUE_VERBOSE], [_IF_ARG_IS_OF_SET_TYPE([$1], @@ -29,6 +30,7 @@ m4_define([_SYNOPSIS_OF_OPTIONAL_ARGS], [m4_lists_foreach_optional([_ARGS_LONG,_ [])], )])]) + dnl dnl $1: Argname dnl $2: Long + short diff --git a/src/function_generators.m4 b/src/function_generators.m4 index 63d4c2d..b6f200f 100644 --- a/src/function_generators.m4 +++ b/src/function_generators.m4 @@ -180,14 +180,12 @@ m4_define([_MAKE_ARGV_PARSING_FUNCTION], [MAKE_FUNCTION( )], )]) - m4_define([_GET_GETOPTS_STRING], [m4_do( [m4_lists_foreach_optional([_ARGS_SHORT,_ARGS_CATH], [_arg_short,_arg_type], [m4_case(_arg_type, [arg], [_arg_short:], [_arg_short])])], )]) - dnl TODO: Don't make this if having only positional args. m4_define([_MAKE_ARGV_PARSING_FUNCTION_POSIX], [MAKE_FUNCTION( [[The parsing of the command-line]], diff --git a/src/list.m4 b/src/list.m4 index 6986e26..7e90186 100644 --- a/src/list.m4 +++ b/src/list.m4 @@ -46,6 +46,7 @@ m4_define([m4_lists_foreach], [_lists_same_len([$1], [m4_popdef([_varnames])], )], [m4_fatal([Lists $1 don't have the same length.])])]) + dnl dnl $1: The list's ID dnl $2, ... Items to be appended: DON'T QUOTE items too much before you add them, quotes will be escaped (m4_escape) and therefore ineffective in m4sugar! @@ -54,6 +55,7 @@ m4_define([m4_list_append], [m4_do( [_m4_list_append_single($1, m4_argn(idx, $@))])], )]) + m4_define([_m4_list_append_single], [m4_do( [m4_pushdef([_LIST_NAME], [[_LIST_$1]])], [m4_ifndef(_LIST_NAME, @@ -63,6 +65,7 @@ m4_define([_m4_list_append_single], [m4_do( [m4_popdef([_LIST_NAME])], )]) + m4_define([m4_list_len], [m4_do( [m4_pushdef([_LIST_NAME], [[_LIST_$1]])], [m4_ifndef(_LIST_NAME, 0, [m4_count(m4_indir(_LIST_NAME))])], @@ -76,6 +79,7 @@ dnl $2: The action to do if the list is empty or not even defined dnl $3: The action to do if the list is defined and non-empty m4_define([m4_list_ifempty], [m4_if(m4_list_len([$1]), 0, [$2], [$3])]) + dnl dnl Given a list name, it expands to its contents, suitable to use e.g. in m4_foreach dnl TODO: It produces a list of double-quoted items, which we maybe don't want @@ -88,6 +92,7 @@ m4_define([m4_list_contents], [m4_do( dnl [m4_ifndef(_LIST_NAME, [], m4_expand([m4_dquote_elt(m4_indir(_LIST_NAME))]))], + dnl dnl Given a list name and an element, it returns list of indices of the element in the list dnl or nothing if it has not been found @@ -152,6 +157,7 @@ m4_define([m4_list_format_sequence], [m4_do( [m4_popdef([_quote])], )]) + dnl dnl Returns its n-th element, first item has index of 1. dnl If the element index is wrong, return $3 @@ -164,6 +170,7 @@ m4_define([m4_list_nth], [m4_do( )], [m4_ifnblank([$3], [$3], [m4_fatal([Requesting element $2 from list '$1': Only positive indices are available])])])], )]) + dnl dnl The list loses its 1st element, which is also expanded by this macro. m4_define([m4_list_pop_front], [m4_do( @@ -173,6 +180,7 @@ m4_define([m4_list_pop_front], [m4_do( [m4_popdef([_LIST_NAME])], )]) + dnl dnl The list loses its last element, which is also expanded by this macro. m4_define([m4_list_pop_back], [m4_do( diff --git a/src/output-completion.m4 b/src/output-completion.m4 index b00b988..64c4fbe 100644 --- a/src/output-completion.m4 +++ b/src/output-completion.m4 @@ -2,8 +2,8 @@ dnl TODO: Basename determination: output filename, or input filename, or nothing m4_include_once([argument_value_types.m4]) m4_include_once([value_validators.m4]) -dnl Make somehow sure that the program name is translated to a valid shell function identifier -m4_define([_TRANSLATE_BAD_CHARS], [m4_translit([[$1]], [-.], [__])]) +dnl Make somehow sure that the program name is transliterated to a valid shell function identifier +m4_define([_TRANSLIT_BAD_CHARS], [m4_translit([[$1]], [-.], [__])]) m4_define([GATHER_OPTIONS_OF_ARGUMENTS_THAT_ACCEPT_SOME_VALUE], [m4_do( [m4_lists_foreach_optional([_ARGS_LONG,_ARGS_SHORT,_ARGS_CATH], [_argname,_arg_short,_arg_type], [_IF_ARG_ACCEPTS_VALUE(_arg_type, @@ -35,7 +35,7 @@ m4_define([ARGBASH_GO_BASE], [m4_do( [GATHER_OPTIONS_OF_ARGUMENTS_THAT_ACCEPT_SOME_VALUE()], [m4_define([_BASENAME], INFERRED_BASENAME_NOERROR)], [m4_define([_PROGRAM_NAME], m4_dquote(_BASENAME))], - [m4_define([_FUNCTION_NAME], m4_dquote(_[]_TRANSLATE_BAD_CHARS(_PROGRAM_NAME)))], + [m4_define([_FUNCTION_NAME], m4_dquote(_[]_TRANSLIT_BAD_CHARS(_PROGRAM_NAME)))], [[#!/bin/bash]_ENDL_(2)], [[# Put this file to /etc/bash_completion.d/]_BASENAME()_ENDL_()], [[# needed because of Argbash --> m4_ignore@{:@@<:@]_ENDL_()], diff --git a/src/output-manpage-defs.m4 b/src/output-manpage-defs.m4 index 1d57002..a12c20d 100644 --- a/src/output-manpage-defs.m4 +++ b/src/output-manpage-defs.m4 @@ -1,5 +1,6 @@ m4_include_once([docopt.m4]) + dnl dnl $1: The macro call (the caller is supposed to pass [$0($@)]) dnl What is also part of the API: The line diff --git a/src/output-manpage.m4 b/src/output-manpage.m4 index addecda..d7721aa 100644 --- a/src/output-manpage.m4 +++ b/src/output-manpage.m4 @@ -1,5 +1,6 @@ m4_include_once([docopt.m4]) + dnl dnl $1: The macro call (the caller is supposed to pass [$0($@)]) dnl What is also part of the API: The line diff --git a/src/stuff.m4 b/src/stuff.m4 index 0d4c4cb..667e97c 100644 --- a/src/stuff.m4 +++ b/src/stuff.m4 @@ -634,6 +634,7 @@ m4_define([LONG_ARG_TO_INDEX], [m4_do( m4_define([LONG_ARG_TO_ARGS_SOMETHING], [m4_list_nth([_ARGS_$2], LONG_ARG_TO_INDEX([$1]))]) + dnl m4_ifblank([$1], [m4_fatal([The assignment is void, use '_val' variable to do wat you want (s.a. '_arg_varname="$_val"')])]) dnl dnl Globally set the option-value delimiter according to a directive. diff --git a/src/utilities.m4 b/src/utilities.m4 index 2a10a8f..7e5813e 100644 --- a/src/utilities.m4 +++ b/src/utilities.m4 @@ -8,9 +8,9 @@ m4_define([m4_include_once], [m4_do( [m4_set_add([__FILES_ALREADY_INCLUDED__], [$1])m4_include([$1])])], )]) - m4_include_once([list.m4]) + dnl dnl $1: nargs dnl $2: index @@ -22,10 +22,12 @@ m4_define([_DEFAULT_IF_NARGS_GREATER_THAN], [m4_do( [m4_if(m4_eval([$1 <= $2]), 1, [m4_default_quoted([$3], [$4])], [$3])], )]) + m4_define([_ENDL_], [m4_for(_, 1, m4_default([$1], 1), 1, [ ])]) + m4_define([_IF_DIY_MODE], [m4_if(_DIY_MODE, 1, [$1], [$2])]) @@ -95,6 +97,7 @@ m4_define([_sh_quote_also_blanks], [m4_do( [["$1"]])], )]) + dnl dnl Define a macro that is part of the public API dnl Ensure the replication and also add the macro name to a list of allowed macros @@ -108,6 +111,7 @@ m4_define([argbash_arg_api], [m4_do( )]])]], )]) + dnl dnl $1: this comm block ID dnl $2: where it is defined @@ -170,6 +174,7 @@ m4_define([_CHECK_PASSED_ARGS_COUNT_TOO_FEW], m4_define([_CHECK_PASSED_ARGS_COUNT_TOO_MANY], [m4_fatal([You have passed $2 arguments to macro $1, while it accepts at most $3.]m4_ifnblank([$4], [ Call it like: $4]))]) + dnl dnl $1: Name of the macro dnl $2: The actual argc @@ -270,11 +275,13 @@ dnl A very private macro --- return name of the macro containing description for dnl $1: Type ID m4_define([__type_str], [[_type_str_$1]]) + dnl dnl Return type description for the given argname dnl $1: Argument ID m4_define([_GET_VALUE_DESC], [m4_expand(__type_str(_GET_VALUE_TYPE([$1])))]) + dnl dnl Given an argname, return the argument group name (i.e. type string) or 'arg' dnl From ad624f612b52008e2becebb4c24f5506bf502c32 Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Sat, 3 Oct 2020 16:48:59 -0700 Subject: [PATCH 06/12] Update src/stuff.m4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Týč --- src/stuff.m4 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/stuff.m4 b/src/stuff.m4 index 667e97c..be3fa80 100644 --- a/src/stuff.m4 +++ b/src/stuff.m4 @@ -81,8 +81,8 @@ argbash_api([INCLUDE_PARSING_CODE], _CHECK_PASSED_ARGS_COUNT(1, 2)[m4_do( [[$0($@)]], [m4_ifndef([SCRIPT_DIR_DEFINED], [m4_fatal([You have to define a script directory by some means before using '$0'])])], [m4_list_append([_OTHER], - m4_expand([[# shellcheck source=SCRIPTDIR/$1]]), - m4_expand([[. "$][{]m4_default_quoted([$2], _SCRIPT_DIR_NAME)[}][/$1]" [# '.' means 'source' + [# shellcheck source=SCRIPTDIR/$1], + m4_expand([[. "${]m4_default_quoted([$2], _SCRIPT_DIR_NAME)[}/$1]" [# '.' means 'source' ]]))], )]) @@ -1351,4 +1351,3 @@ dnl dnl * Upon arg encounter, validate the value. Die in case of no compliance. dnl * Help: optional args - value should take the name. dnl : positional args - value should have the arg name, but the type should be mentioned on the help line. - From 2669eeec73b0cf93429e63e684e3ba99d13a04f5 Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Sat, 3 Oct 2020 17:06:04 -0700 Subject: [PATCH 07/12] Cleanup of operators --- bin/argbash | 34 ++++++++----- resources/examples/simple-wrapper.m4 | 3 +- resources/examples/simple.m4 | 3 +- src/argbash.m4 | 76 +++++++++++++++------------- 4 files changed, 65 insertions(+), 51 deletions(-) diff --git a/bin/argbash b/bin/argbash index dc9e8e9..27ef4e5 100755 --- a/bin/argbash +++ b/bin/argbash @@ -345,9 +345,9 @@ do_stuff() input="$(printf '%s\n' "${_pass_also}" | cat - "${m4dir}/argbash-lib.m4" "${output_m4}")" prefix_len=$(printf '%s\n' "${input}" | wc -l) input="$(printf '%s\n' "${input}" | cat - "$1")" - run_autom4te "${input}" 2> "${discard}" | - grep -v '^#\s*needed because of Argbash -->\s*$' | - grep -v '^#\s*<-- needed because of Argbash\s*$' + run_autom4te "${input}" 2> "${discard}" \ + | grep -v '^#\s*needed because of Argbash -->\s*$' \ + | grep -v '^#\s*<-- needed because of Argbash\s*$' _ret=$? if test "${_ret}" != 0; then local errstr @@ -370,24 +370,27 @@ settle_wrapped_fname() local _srcfiles=() _file_found _found ext srcstem searchdir line stem="$2" while read -r line; do _srcfiles+=("${line}") - done < <(echo 'm4_changecom()m4_define([ARGBASH_WRAP])' "$(cat "$1")" | - autom4te -l m4sugar -t 'ARGBASH_WRAP:$1' 2> "${discard}") + done < <(echo 'm4_changecom()m4_define([ARGBASH_WRAP])' "$(cat "$1")" \ + | autom4te -l m4sugar -t 'ARGBASH_WRAP:$1' 2> "${discard}") test "${#_srcfiles[@]}" -gt 0 || return for srcstem in "${_srcfiles[@]}"; do _found=no for searchdir in "${_arg_search[@]}"; do - test -f "${searchdir}/${srcstem}.m4" && { + test -f "${searchdir}/${srcstem}.m4" \ + && { _found=yes ext='.m4' break } - test -f "${searchdir}/${srcstem}.sh" && { + test -f "${searchdir}/${srcstem}.sh" \ + && { _found=yes ext='.sh' break } - test -f "${searchdir}/${srcstem}" && { + test -f "${searchdir}/${srcstem}" \ + && { _found=yes ext='' break @@ -412,9 +415,9 @@ get_parsing_code() { local _shfile _m4file _newerfile # Get the argument of INCLUDE_PARSING_CODE - _srcfile="$(echo 'm4_changecom()m4_define([INCLUDE_PARSING_CODE])' "$(cat "${infile}")" | - autom4te -l m4sugar -t 'INCLUDE_PARSING_CODE:$1' 2> "${discard}" | - tail -n 1)" + _srcfile="$(echo 'm4_changecom()m4_define([INCLUDE_PARSING_CODE])' "$(cat "${infile}")" \ + | autom4te -l m4sugar -t 'INCLUDE_PARSING_CODE:$1' 2> "${discard}" \ + | tail -n 1)" test -n "${_srcfile}" || return 1 _thatfile="$(dirname "${infile}")/${_srcfile}" test -f "${_thatfile}" && _shfile="${_thatfile}" @@ -469,7 +472,8 @@ m4dir="${script_dir}/../src" test -n "${_arg_debug}" && DEBUG=('-t' "${_arg_debug}") output_m4="${m4dir}/output-strip-none.m4" -test "${_arg_library}" = "on" && { +test "${_arg_library}" = "on" \ + && { echo "The --library option is deprecated, use --strip user-content" next time >&2 _arg_strip="user-content" } @@ -485,13 +489,15 @@ if test "${_arg_in_place}" = on; then _arg_output="${infile}" fi -test -n "${_arg_output}" || { +test -n "${_arg_output}" \ + || { echo "The output can't be blank - it is not a legal filename!" >&2 exit 1 } outfname="${_arg_output}" -autom4te --version > "${discard}" 2>&1 || { +autom4te --version > "${discard}" 2>&1 \ + || { echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 exit 1 } diff --git a/resources/examples/simple-wrapper.m4 b/resources/examples/simple-wrapper.m4 index 115760f..14cc4a2 100644 --- a/resources/examples/simple-wrapper.m4 +++ b/resources/examples/simple-wrapper.m4 @@ -11,7 +11,8 @@ # [ <-- needed because of Argbash script="${script_dir}/simple.sh" -test -f "${script}" || { +test -f "${script}" \ + || { echo "Missing the wrapped script, was expecting it next to me, in '${script_dir}'." exit 1 } diff --git a/resources/examples/simple.m4 b/resources/examples/simple.m4 index dd5f874..bded960 100644 --- a/resources/examples/simple.m4 +++ b/resources/examples/simple.m4 @@ -11,7 +11,8 @@ verbose=${_arg_verbose} unit=${_arg_unit} -test -f ${_arg_filename} || { +test -f ${_arg_filename}\ + || { echo "Filename ${_arg_filename} doesn't seem to belong to a file" exit 1 } diff --git a/src/argbash.m4 b/src/argbash.m4 index 4d7c0da..231c1a3 100644 --- a/src/argbash.m4 +++ b/src/argbash.m4 @@ -115,9 +115,9 @@ do_stuff() input="$(printf '%s\n' "${_pass_also}" | cat - "${m4dir}/argbash-lib.m4" "${output_m4}")" prefix_len=$(printf '%s\n' "${input}" | wc -l) input="$(printf '%s\n' "${input}" | cat - "$1")" - run_autom4te "${input}" 2> "${discard}" | - grep -v '^#\s*needed because of Argbash -->\s*$' | - grep -v '^#\s*<-- needed because of Argbash\s*$' + run_autom4te "${input}" 2> "${discard}" \ + | grep -v '^#\s*needed because of Argbash -->\s*$' \ + | grep -v '^#\s*<-- needed because of Argbash\s*$' _ret=$? if test "${_ret}" != 0; then local errstr @@ -140,28 +140,31 @@ settle_wrapped_fname() local _srcfiles=() _file_found _found ext srcstem searchdir line stem="$2" while read -r line; do _srcfiles+=("${line}") - done < <(echo 'm4_changecom()m4_define([ARGBASH_WRAP])' "$(cat "$1")" | - autom4te -l m4sugar -t 'ARGBASH_WRAP:$1' 2> "${discard}") + done < <(echo 'm4_changecom()m4_define([ARGBASH_WRAP])' "$(cat "$1")" \ + | autom4te -l m4sugar -t 'ARGBASH_WRAP:$1' 2> "${discard}") test "${#_srcfiles[@]}" -gt 0 || return for srcstem in "${_srcfiles[@]}"; do _found=no for searchdir in "${_arg_search[@]}"; do - test -f "${searchdir}/${srcstem}.m4" && { - _found=yes - ext='.m4' - break - } - test -f "${searchdir}/${srcstem}.sh" && { - _found=yes - ext='.sh' - break - } - test -f "${searchdir}/${srcstem}" && { - _found=yes - ext='' - break - } + test -f "${searchdir}/${srcstem}.m4" \ + && { + _found=yes + ext='.m4' + break + } + test -f "${searchdir}/${srcstem}.sh" \ + && { + _found=yes + ext='.sh' + break + } + test -f "${searchdir}/${srcstem}" \ + && { + _found=yes + ext='' + break + } done # The last searchdir is a correct one test "${_found}" = yes || die "Couldn't find wrapped file of stem '${srcstem}' in any of directories: ${_arg_search[*]}" 2 @@ -182,9 +185,9 @@ get_parsing_code() { local _shfile _m4file _newerfile # Get the argument of INCLUDE_PARSING_CODE - _srcfile="$(echo 'm4_changecom()m4_define([INCLUDE_PARSING_CODE])' "$(cat "${infile}")" | - autom4te -l m4sugar -t 'INCLUDE_PARSING_CODE:$1' 2> "${discard}" | - tail -n 1)" + _srcfile="$(echo 'm4_changecom()m4_define([INCLUDE_PARSING_CODE])' "$(cat "${infile}")" \ + | autom4te -l m4sugar -t 'INCLUDE_PARSING_CODE:$1' 2> "${discard}" \ + | tail -n 1)" test -n "${_srcfile}" || return 1 _thatfile="$(dirname "${infile}")/${_srcfile}" test -f "${_thatfile}" && _shfile="${_thatfile}" @@ -239,10 +242,11 @@ m4dir="${script_dir}/../src" test -n "${_arg_debug}" && DEBUG=('-t' "${_arg_debug}") output_m4="${m4dir}/output-strip-none.m4" -test "${_arg_library}" = "on" && { - echo "The --library option is deprecated, use --strip user-content" next time >&2 - _arg_strip="user-content" -} +test "${_arg_library}" = "on" \ + && { + echo "The --library option is deprecated, use --strip user-content" next time >&2 + _arg_strip="user-content" + } if test "${_arg_strip}" = "user-content"; then output_m4="${m4dir}/output-strip-user-content.m4" @@ -255,16 +259,18 @@ if test "${_arg_in_place}" = on; then _arg_output="${infile}" fi -test -n "${_arg_output}" || { - echo "The output can't be blank - it is not a legal filename!" >&2 - exit 1 -} +test -n "${_arg_output}" \ + || { + echo "The output can't be blank - it is not a legal filename!" >&2 + exit 1 + } outfname="${_arg_output}" -autom4te --version > "${discard}" 2>&1 || { - echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 - exit 1 -} +autom4te --version > "${discard}" 2>&1 \ + || { + echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 + exit 1 + } _arg_search+=("$(dirname "${infile}")") _wrapped_defns="" From 9f38b700efcd41bfa74cc37efcbc399a7aed40ce Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Sat, 3 Oct 2020 17:06:33 -0700 Subject: [PATCH 08/12] Cleanup of finished todo --- src/stuff.m4 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stuff.m4 b/src/stuff.m4 index be3fa80..733520a 100644 --- a/src/stuff.m4 +++ b/src/stuff.m4 @@ -76,7 +76,6 @@ dnl The argbash script generator will pick it up and (re)generate that one as we dnl dnl $1: the filename (assuming that it is in the same directory as the script) dnl $2: what has been passed to DEFINE_SCRIPT_DIR as the first param -dnl TODO: add shellcheck source directive argbash_api([INCLUDE_PARSING_CODE], _CHECK_PASSED_ARGS_COUNT(1, 2)[m4_do( [[$0($@)]], [m4_ifndef([SCRIPT_DIR_DEFINED], [m4_fatal([You have to define a script directory by some means before using '$0'])])], From 67f5eebef724f1b64a097ed399c7bb6e5a16588b Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Sun, 4 Oct 2020 12:43:38 -0700 Subject: [PATCH 09/12] Cleanup comment + bash substituation --- bin/argbash | 42 ++++++++++++++-------------- bin/argbash-init | 6 ++-- resources/examples/simple-wrapper.sh | 3 +- resources/examples/simple.sh | 3 +- src/argbash-init.m4 | 6 ++-- 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/bin/argbash b/bin/argbash index 27ef4e5..6cba045 100755 --- a/bin/argbash +++ b/bin/argbash @@ -379,22 +379,22 @@ settle_wrapped_fname() for searchdir in "${_arg_search[@]}"; do test -f "${searchdir}/${srcstem}.m4" \ && { - _found=yes - ext='.m4' - break - } + _found=yes + ext='.m4' + break + } test -f "${searchdir}/${srcstem}.sh" \ && { - _found=yes - ext='.sh' - break - } + _found=yes + ext='.sh' + break + } test -f "${searchdir}/${srcstem}" \ && { - _found=yes - ext='' - break - } + _found=yes + ext='' + break + } done # The last searchdir is a correct one test "${_found}" = yes || die "Couldn't find wrapped file of stem '${srcstem}' in any of directories: ${_arg_search[*]}" 2 @@ -474,9 +474,9 @@ test -n "${_arg_debug}" && DEBUG=('-t' "${_arg_debug}") output_m4="${m4dir}/output-strip-none.m4" test "${_arg_library}" = "on" \ && { - echo "The --library option is deprecated, use --strip user-content" next time >&2 - _arg_strip="user-content" -} + echo "The --library option is deprecated, use --strip user-content" next time >&2 + _arg_strip="user-content" + } if test "${_arg_strip}" = "user-content"; then output_m4="${m4dir}/output-strip-user-content.m4" @@ -491,16 +491,16 @@ fi test -n "${_arg_output}" \ || { - echo "The output can't be blank - it is not a legal filename!" >&2 - exit 1 -} + echo "The output can't be blank - it is not a legal filename!" >&2 + exit 1 + } outfname="${_arg_output}" autom4te --version > "${discard}" 2>&1 \ || { - echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 - exit 1 -} + echo "You need the 'autom4te' utility (it comes with 'autoconf'), if you have bash, that one is an easy one to get." 2>&1 + exit 1 + } _arg_search+=("$(dirname "${infile}")") _wrapped_defns="" diff --git a/bin/argbash-init b/bin/argbash-init index ae9f549..e940931 100755 --- a/bin/argbash-init +++ b/bin/argbash-init @@ -394,9 +394,9 @@ do_stuff() } -outfname="${_arg_output}" -# we canonicize the empty string input to output filename to the dash -test -n "${outfname}" || outfname='-' +# Alter the output filename to the canonical representation of stdout (-) if it is the empty string or unset +outfname="${_arg_output:--}" + test "${outfname}" = "-" -a "${_arg_separate}" -gt 0 && die "If you want to separate parsing and script body, you have to specify the output filename, stdout doesn't work." if test "${outfname}" = '-'; then diff --git a/resources/examples/simple-wrapper.sh b/resources/examples/simple-wrapper.sh index 3e2079c..c342aed 100755 --- a/resources/examples/simple-wrapper.sh +++ b/resources/examples/simple-wrapper.sh @@ -141,7 +141,8 @@ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || { echo "Couldn't d script="${script_dir}/simple.sh" -test -f "${script}" || { +test -f "${script}" \ + || { echo "Missing the wrapped script, was expecting it next to me, in '${script_dir}'." exit 1 } diff --git a/resources/examples/simple.sh b/resources/examples/simple.sh index 4c78ed0..390c0ff 100755 --- a/resources/examples/simple.sh +++ b/resources/examples/simple.sh @@ -23,7 +23,8 @@ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || { echo "Couldn't d verbose=${_arg_verbose} unit=${_arg_unit} -test -f ${_arg_filename} || { +test -f ${_arg_filename}\ + || { echo "Filename ${_arg_filename} doesn't seem to belong to a file" exit 1 } diff --git a/src/argbash-init.m4 b/src/argbash-init.m4 index 0e6b111..72a05f2 100644 --- a/src/argbash-init.m4 +++ b/src/argbash-init.m4 @@ -208,9 +208,9 @@ do_stuff() } -outfname="${_arg_output}" -# we canonicize the empty string input to output filename to the dash -test -n "${outfname}" || outfname='-' +# Alter the output filename to the canonical representation of stdout (-) if it is the empty string or unset +outfname="${_arg_output:--}" + test "${outfname}" = "-" -a "${_arg_separate}" -gt 0 && die "If you want to separate parsing and script body, you have to specify the output filename, stdout doesn't work." if test "${outfname}" = '-'; then From c4ce82817808fd8e63a30c05a382c040b8c8f0f3 Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Fri, 8 Jan 2021 13:00:30 -0800 Subject: [PATCH 10/12] Fix for patch file --- doc/_static/minimal.patch | 12 ++++++------ doc/_static/wrapper-output-action.txt | 2 +- resources/examples/minimal.m4 | 20 +++++++++++++------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/_static/minimal.patch b/doc/_static/minimal.patch index 1d25fd3..ef285b0 100644 --- a/doc/_static/minimal.patch +++ b/doc/_static/minimal.patch @@ -21,13 +21,13 @@ # vvv PLACE YOUR CODE HERE vvv # For example: --printf 'Value of --%s: %s\n' 'option' "$_arg_option" --printf "'%s' is %s\\n" 'print' "$_arg_print" --printf "Value of '%s': %s\\n" 'positional-arg' "$_arg_positional_arg" -+if [ "$_arg_print" = on ] +-printf 'Value of --%s: %s\n' 'option' "${_arg_option}" +-printf "'%s' is %s\\n" 'print' "${_arg_print}" +-printf "Value of '%s': %s\\n" 'positional-arg' "${_arg_positional_arg}" ++if [ "${_arg_print}" = on ] +then -+ echo "Positional arg value: '$_arg_positional_arg'" -+ echo "Optional arg '--option' value: '$_arg_option'" ++ echo "Positional arg value: '${_arg_positional_arg}'" ++ echo "Optional arg '--option' value: '${_arg_option}'" +else + echo "Not telling anything, print not requested" +fi diff --git a/doc/_static/wrapper-output-action.txt b/doc/_static/wrapper-output-action.txt index d79e86d..0a59547 100644 --- a/doc/_static/wrapper-output-action.txt +++ b/doc/_static/wrapper-output-action.txt @@ -4,7 +4,7 @@ Contents of '../src' matching '*.m4': argbash-1to2.m4: 1 kiB argbash-init.m4: 6 kiB argbash-lib.m4: 0 kiB - argbash.m4: 10 kiB + argbash.m4: 11 kiB argument_value_types.m4: 5 kiB collectors.m4: 21 kiB constants.m4: 0 kiB diff --git a/resources/examples/minimal.m4 b/resources/examples/minimal.m4 index e02ce38..a637094 100644 --- a/resources/examples/minimal.m4 +++ b/resources/examples/minimal.m4 @@ -3,20 +3,26 @@ # m4_ignore( echo "This is just a script template, not the script (yet) - pass it to 'argbash' to fix this." >&2 exit 11 #)Created by argbash-init v2.10.0 -# ARG_OPTIONAL_SINGLE([option]) -# ARG_OPTIONAL_BOOLEAN([print]) -# ARG_POSITIONAL_SINGLE([positional-arg]) +# ARG_OPTIONAL_SINGLE([option], o, [A option with short and long flags and default], [boo]) +# ARG_OPTIONAL_BOOLEAN([print], , [A boolean option with long flag (and implicit default: off)]) +# ARG_POSITIONAL_SINGLE([positional-arg], [Positional arg description], ) # ARG_DEFAULTS_POS -# ARG_HELP([]) +# ARG_HELP([This is a minimal demo of Argbash potential]) +# ARG_VERSION([echo $0 v0.1]) +# ARGBASH_SET_INDENT([ ]) # ARGBASH_GO # [ <-- needed because of Argbash # vvv PLACE YOUR CODE HERE vvv # For example: -printf 'Value of --%s: %s\n' 'option' "${_arg_option}" -printf "'%s' is %s\\n" 'print' "${_arg_print}" -printf "Value of '%s': %s\\n" 'positional-arg' "${_arg_positional_arg}" +if [ "${_arg_print}" = on ] +then + echo "Positional arg value: '${_arg_positional_arg}'" + echo "Optional arg '--option' value: '${_arg_option}'" +else + echo "Not telling anything, print not requested" +fi # ^^^ TERMINATE YOUR CODE BEFORE THE BOTTOM ARGBASH MARKER ^^^ From dd5bd2811e756830b18b922ef6e861c162990cef Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Fri, 8 Jan 2021 13:15:14 -0800 Subject: [PATCH 11/12] Possible fix for workflows --- .github/workflows/docker-build-and-push.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-build-and-push.yaml b/.github/workflows/docker-build-and-push.yaml index 90cc24d..055b977 100644 --- a/.github/workflows/docker-build-and-push.yaml +++ b/.github/workflows/docker-build-and-push.yaml @@ -19,10 +19,10 @@ jobs: - name: Set environment variables run: | DOCKER_USERNAME=matejak - echo "::set-env name=DOCKER_USERNAME::$DOCKER_USERNAME" + echo "DOCKER_USERNAME=$DOCKER_USERNAME" >> $GITHUB_ENV DOCKER_IMAGE="$DOCKER_USERNAME/argbash" - echo "::set-env name=DOCKER_IMAGE::$DOCKER_IMAGE" + echo "DOCKER_IMAGE=$DOCKER_IMAGE" >> $GITHUB_ENV if [[ "$GITHUB_REF" = refs/tags/* ]]; then version="${GITHUB_REF#refs/tags/}" From d618a365b8eb097e62e3d42266831b67bf1540a4 Mon Sep 17 00:00:00 2001 From: Scott Atkins Date: Fri, 8 Jan 2021 13:17:21 -0800 Subject: [PATCH 12/12] Missed docker tags --- .github/workflows/docker-build-and-push.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build-and-push.yaml b/.github/workflows/docker-build-and-push.yaml index 055b977..2a3691e 100644 --- a/.github/workflows/docker-build-and-push.yaml +++ b/.github/workflows/docker-build-and-push.yaml @@ -39,7 +39,7 @@ jobs: DOCKER_TAGS="branch-$branch" unset branch fi - echo "::set-env name=DOCKER_TAGS::$DOCKER_TAGS" + echo "DOCKER_TAGS=$DOCKER_TAGS" >> $GITHUB_ENV echo "The tags were set to '$DOCKER_TAGS'" # This is a workaround due to