You've already forked sh-args-parser
mirror of
https://github.com/nikolaypronchev/sh-args-parser.git
synced 2026-04-17 05:56:31 +03:00
Add positional arg var
This commit is contained in:
@@ -96,6 +96,7 @@ Configuration variables must be assigned before calling `_parse`.
|
|||||||
| _accept_options | `auto` | `any` — The script accepts any options.<br>`none` — The script does not accept any options.<br>`mapped_only` — The script accepts only mapped options.<br>`auto` — The script accepts only mapped options if at least one has been mapped. Otherwise, it accepts any options. |
|
| _accept_options | `auto` | `any` — The script accepts any options.<br>`none` — The script does not accept any options.<br>`mapped_only` — The script accepts only mapped options.<br>`auto` — The script accepts only mapped options if at least one has been mapped. Otherwise, it accepts any options. |
|
||||||
| _default_max_positional_args | | Maximum number of positional arguments. A different value can be set for each command (see [_map_command](#_map_command)). |
|
| _default_max_positional_args | | Maximum number of positional arguments. A different value can be set for each command (see [_map_command](#_map_command)). |
|
||||||
| _default_min_positional_args | `0` | Minimum number of positional arguments. A different value can be set for each command (see [_map_command](#_map_command)). |
|
| _default_min_positional_args | `0` | Minimum number of positional arguments. A different value can be set for each command (see [_map_command](#_map_command)). |
|
||||||
|
| _default_positional_arg_variable || Name of the variable that will store the single positional argument. Implicitly sets `_default_max_positional_args` and `_default_min_positional_args` to 1. Command-specific values for `max_args` and `arg_variable` disables this behavior. |
|
||||||
| _mapping_key_value_delimiter | `=` | Key-value delimiter for options mapping (see [_map_option](#_map_option)). |
|
| _mapping_key_value_delimiter | `=` | Key-value delimiter for options mapping (see [_map_option](#_map_option)). |
|
||||||
| _mapping_values_delimiter | `,` | Values delimiter for options mapping (see [_map_option](#_map_option)). |
|
| _mapping_values_delimiter | `,` | Values delimiter for options mapping (see [_map_option](#_map_option)). |
|
||||||
| _option_duplicates_allowed | `false` | `true` — Multiple uses of options are allowed.<br>`false` — Multiple uses of options are not allowed.|
|
| _option_duplicates_allowed | `false` | `true` — Multiple uses of options are allowed.<br>`false` — Multiple uses of options are not allowed.|
|
||||||
@@ -131,6 +132,7 @@ Maps a command. Takes key-value pairs as arguments. Key and values list are sepa
|
|||||||
| description | Command description. Currently not used. |
|
| description | Command description. Currently not used. |
|
||||||
| min_args | Minimum number of positional arguments when using the command. |
|
| min_args | Minimum number of positional arguments when using the command. |
|
||||||
| max_args | Maximum number of positional arguments when using the command. |
|
| max_args | Maximum number of positional arguments when using the command. |
|
||||||
|
| arg_variable | Name of the variable that will store the command's positional argument. Implicitly sets `min_args` and `max_args` to 1. |
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
_map_command \
|
_map_command \
|
||||||
|
|||||||
103
parser.sh
103
parser.sh
@@ -4,6 +4,7 @@ _accept_command=auto # auto, none, any, mapped_only
|
|||||||
_accept_options=auto # auto, none, any, mapped_only
|
_accept_options=auto # auto, none, any, mapped_only
|
||||||
_default_max_positional_args=""
|
_default_max_positional_args=""
|
||||||
_default_min_positional_args=0
|
_default_min_positional_args=0
|
||||||
|
_default_positional_arg_variable=""
|
||||||
_mapping_key_value_delimiter="="
|
_mapping_key_value_delimiter="="
|
||||||
_mapping_values_delimiter=","
|
_mapping_values_delimiter=","
|
||||||
_option_duplicates_allowed=true
|
_option_duplicates_allowed=true
|
||||||
@@ -151,6 +152,33 @@ _mapped_options_only() {
|
|||||||
[ "$_mapped_options_count" -gt 0 ]
|
[ "$_mapped_options_count" -gt 0 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_is_free_var_name() {
|
||||||
|
if [ -n "$_default_positional_arg_variable" ] && [ "$_default_positional_arg_variable" = "$1" ]; then
|
||||||
|
echo "variable is already used as default positional arg variable: $1."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_i=1
|
||||||
|
while [ "$_i" -le "$_mapped_options_count" ]; do
|
||||||
|
if [ "$1" = "$(_var_value "_options_${_i}_variable")" ]; then
|
||||||
|
echo "variable is already mapped for option #${_i}: $1."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_i=$(_math "$_i + 1")
|
||||||
|
done
|
||||||
|
|
||||||
|
_i=1
|
||||||
|
while [ "$_i" -le "$_mapped_commands_count" ]; do
|
||||||
|
if [ "$1" = "$(_var_value "_commands_${_i}_arg_variable")" ]; then
|
||||||
|
echo "arg variable is already mapped for command #${_i}: $1."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_i=$(_math "$_i + 1")
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
_map_command() {
|
_map_command() {
|
||||||
_command_index=$(_math "$_mapped_commands_count + 1")
|
_command_index=$(_math "$_mapped_commands_count + 1")
|
||||||
_mapping_command_prefix="_commands_${_command_index}"
|
_mapping_command_prefix="_commands_${_command_index}"
|
||||||
@@ -179,6 +207,10 @@ _map_command() {
|
|||||||
_validate_command_min_args "$_map_value"
|
_validate_command_min_args "$_map_value"
|
||||||
elif [ "$_map_key" = "name" ]; then
|
elif [ "$_map_key" = "name" ]; then
|
||||||
_validate_command_name "$_map_value"
|
_validate_command_name "$_map_value"
|
||||||
|
elif [ "$_map_key" = "arg_variable" ]; then
|
||||||
|
_validate_command_arg_variable "$_map_value"
|
||||||
|
_assign "${_mapping_command_prefix}_min_args" 1
|
||||||
|
_assign "${_mapping_command_prefix}_max_args" 1
|
||||||
else
|
else
|
||||||
_err "Invalid command #${_command_index} mapping key: $_map_key."
|
_err "Invalid command #${_command_index} mapping key: $_map_key."
|
||||||
fi
|
fi
|
||||||
@@ -233,6 +265,8 @@ _map_option() {
|
|||||||
_validate_option_aliases "$_map_value"
|
_validate_option_aliases "$_map_value"
|
||||||
elif [ "$_map_key" = "variable" ]; then
|
elif [ "$_map_key" = "variable" ]; then
|
||||||
_validate_option_variable "$_map_value"
|
_validate_option_variable "$_map_value"
|
||||||
|
_assign "${_mapping_option_prefix}_min_args" 1
|
||||||
|
_assign "${_mapping_option_prefix}_max_args" 1
|
||||||
elif [ "$_map_key" = "description" ]; then
|
elif [ "$_map_key" = "description" ]; then
|
||||||
_validate_option_description "$_map_value"
|
_validate_option_description "$_map_value"
|
||||||
elif [ "$_map_key" = "max_args" ]; then
|
elif [ "$_map_key" = "max_args" ]; then
|
||||||
@@ -345,6 +379,31 @@ _validate_command_name() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_validate_command_arg_variable() {
|
||||||
|
if [ -n "$(_var_value "${_mapping_command_prefix}_arg_variable")" ]; then
|
||||||
|
_err "Command #${_command_index} arg variable is already mapped."
|
||||||
|
fi
|
||||||
|
|
||||||
|
_min_args=$(_var_value "${_mapping_command_prefix}_min_args")
|
||||||
|
_max_args=$(_var_value "${_mapping_command_prefix}_max_args")
|
||||||
|
|
||||||
|
if { [ -n "$_min_args" ] && [ "$_min_args" -ne 1 ]; } || { [ -n "$_max_args" ] && [ "$_max_args" -ne 1 ]; }; then
|
||||||
|
_err "Command #${_command_index} arg variable can only be used with commands that requires single argument."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
_err "Command #${_command_index} arg variable cannot be empty."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _is_valid_var_name "$1"; then
|
||||||
|
_err "Command #${_command_index} arg variable is invalid: $1. Must be a valid variable name."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _description=$(_is_free_var_name "$1"); then
|
||||||
|
_err "Command #${_command_index} ${_description}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
_validate_option_aliases() {
|
_validate_option_aliases() {
|
||||||
if [ -n "$(_var_value "${_mapping_option_prefix}_aliases")" ]; then
|
if [ -n "$(_var_value "${_mapping_option_prefix}_aliases")" ]; then
|
||||||
_err "Option #${_option_index} aliases are already mapped."
|
_err "Option #${_option_index} aliases are already mapped."
|
||||||
@@ -444,14 +503,9 @@ _validate_option_variable() {
|
|||||||
_err "Option #${_option_index} variable is invalid: $1. Must be a valid variable name."
|
_err "Option #${_option_index} variable is invalid: $1. Must be a valid variable name."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_i=1
|
if ! _description=$(_is_free_var_name "$1"); then
|
||||||
while [ "$_i" -le "$_mapped_options_count" ]; do
|
_err "Option #${_option_index} ${_description}"
|
||||||
if [ "$1" = "$(_var_value "_options_${_i}_variable")" ]; then
|
|
||||||
_err "Option #${_option_index} variable is already mapped for option #${_i}: $1."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_i=$(_math "$_i + 1")
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_validate_option_description() {
|
_validate_option_description() {
|
||||||
@@ -477,10 +531,6 @@ _validate_option_max_args() {
|
|||||||
_err "Option #${_option_index} max args is invalid: $1. Must be a non-negative integer."
|
_err "Option #${_option_index} max args is invalid: $1. Must be a non-negative integer."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$(_var_value "${_mapping_option_prefix}_variable")" ] && [ "$1" -ne 1 ]; then
|
|
||||||
_err "Option #${_option_index} max args is invalid: $1. Implicitly set to 1 when option variable was set."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if (_is "$(_var_value "${_mapping_option_prefix}_required")") && [ "$1" -eq 0 ]; then
|
if (_is "$(_var_value "${_mapping_option_prefix}_required")") && [ "$1" -eq 0 ]; then
|
||||||
_err "Option #${_option_index} must be removed as constant. It is required without arguments."
|
_err "Option #${_option_index} must be removed as constant. It is required without arguments."
|
||||||
fi
|
fi
|
||||||
@@ -498,10 +548,6 @@ _validate_option_min_args() {
|
|||||||
if ! _is_int "$1"; then
|
if ! _is_int "$1"; then
|
||||||
_err "Option #${_option_index} min args is invalid: $1. Must be a non-negative integer."
|
_err "Option #${_option_index} min args is invalid: $1. Must be a non-negative integer."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$(_var_value "${_mapping_option_prefix}_variable")" ] && [ "$1" -ne 1 ]; then
|
|
||||||
_err "Option #${_option_index} min args is invalid: $1. Implicitly set to 1 when option variable was set."
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_validate_option_required() {
|
_validate_option_required() {
|
||||||
@@ -640,25 +686,36 @@ _parse_positional_args() {
|
|||||||
_err "Positional arguments must be placed before options: $1."
|
_err "Positional arguments must be placed before options: $1."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$_command_index" ]; then
|
if [ -n "$_command_index" ]; then
|
||||||
_max_args_count="$_default_max_positional_args"
|
_max_args=$(_var_value "_commands_${_command_index}_max_args")
|
||||||
else
|
_arg_variable="$(_var_value "_commands_${_command_index}_arg_variable")"
|
||||||
_max_args_count=$(_var_value "_commands_${_command_index}_max_args")
|
fi
|
||||||
|
|
||||||
|
if [ -z "$_max_args" ]; then
|
||||||
|
_max_args=$_default_max_positional_args
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$_arg_variable" ]; then
|
||||||
|
_arg_variable="$_default_positional_arg_variable"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
_positional_arg_index=$(_math "$_positional_args_count + 1")
|
_positional_arg_index=$(_math "$_positional_args_count + 1")
|
||||||
|
|
||||||
if [ -n "$_max_args_count" ] && [ "$_positional_arg_index" -gt "$_max_args_count" ]; then
|
if [ -n "$_max_args" ] && [ "$_positional_arg_index" -gt "$_max_args" ]; then
|
||||||
if [ -z "$_command_index" ]; then
|
if [ -z "$_command_index" ]; then
|
||||||
_err "Maximum $_max_args_count positional argument(s) allowed."
|
_err "Maximum $_max_args positional argument(s) allowed."
|
||||||
else
|
else
|
||||||
_err "Maximum $_max_args_count positional argument(s) allowed for command: $(_var_value "_commands_${_command_index}_name")."
|
_err "Maximum $_max_args positional argument(s) allowed for command: $(_var_value "_commands_${_command_index}_name")."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_assign "_positional_args_${_positional_arg_index}" "$1"
|
_assign "_positional_args_${_positional_arg_index}" "$1"
|
||||||
_positional_args_count=$_positional_arg_index
|
_assign "_positional_args_count" "$_positional_arg_index"
|
||||||
|
|
||||||
|
if [ -n "$_arg_variable" ]; then
|
||||||
|
_assign "$_arg_variable" "$1"
|
||||||
|
fi
|
||||||
|
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user