Skip to content

Commit

Permalink
feat: new module l.parse_args. And l.parse_params is deprecated.
Browse files Browse the repository at this point in the history
User should use l.parse_args instead of l.parse_params.
The l.parse_params has some limitations on use. So it is deprecated and
will be removed in soon.
  • Loading branch information
adoyle-h committed Sep 6, 2024
1 parent cf27608 commit 2dc6505
Show file tree
Hide file tree
Showing 7 changed files with 728 additions and 70 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,19 @@ indent_style = tab
[{Dockerfile,Dockerfile.*,*.dockerfile}]
indent_style = space
indent_size = 2

[{/bin/*,/tools/*,**/*.{bats,bash,sh}}]

################################################################################
# Below are shfmt options. #
# See https://github.com/mvdan/sh/blob/master/cmd/shfmt/shfmt.1.scd#examples #
################################################################################
# --language-variant
shell_variant = auto
binary_next_line = false
# --case-indent
switch_case_indent = true
space_redirects = false
keep_padding = false
# --func-next-line
function_next_line = false
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ bump-minor:

bump-patch:
./tools/release patch

.PHONY: build
build:
./build -y ./dist/lobash.bash
107 changes: 37 additions & 70 deletions build
Original file line number Diff line number Diff line change
@@ -1,46 +1,10 @@
#!/usr/bin/env bash
# This script support Bash: 4.0+

set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
set -o errexit -o nounset -o pipefail -o errtrace
(shopt -p inherit_errexit &>/dev/null) && shopt -s inherit_errexit

readlinkf() { # Modified from https://github.com/ko1nksm/readlinkf
[ "${1:-}" ] || return 1

CDPATH='' # to avoid changing to an unexpected directory
local max_symlinks=40
local link
local target=$1

[ -e "${target%/}" ] || target=${1%"${1##*[!/]}"} # trim trailing slashes
[ -d "${target:-/}" ] && target="$target/"

cd -P . 2>/dev/null || return 1
while [ "$max_symlinks" -ge 0 ] && max_symlinks=$((max_symlinks - 1)); do
if [ ! "$target" = "${target%/*}" ]; then
case $target in
/*) cd -P "${target%/*}/" 2>/dev/null || break ;;
*) cd -P "./${target%/*}" 2>/dev/null || break ;;
esac
target=${target##*/}
fi

if [ ! -L "$target" ]; then
target="${PWD%/}${target:+/}${target}"
printf '%s\n' "${target:-/}"
return 0
fi

link=$(ls -dl -- "$target" 2>/dev/null) || break
target=${link#*" $target -> "}
done
return 1
}

SCRIPT_PATH="$(readlinkf "$0")"
SCRIPT_PATH="$(realpath "$0")"
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
readonly SCRIPT_PATH SCRIPT_DIR

Expand All @@ -49,9 +13,9 @@ source "$SCRIPT_DIR/tools/colors.bash"
# shellcheck source=./src/load_internals.bash
source "$SCRIPT_DIR/src/load_internals.bash"
_lobash.import_internals basic_meta_types module_meta rm erase_line
_lobash.imports ask choose parse_params array_include union_array is_tty_available is_gnu_sed relative
_lobash.imports ask choose parse_args array_include union_array is_tty_available is_gnu_sed relative

SUPPORTED_BASH_VERISONS=( 4.0 4.1 4.2 4.3 4.4 )
SUPPORTED_BASH_VERISONS=(4.0 4.1 4.2 4.3 4.4)

if l.is_gnu_sed; then
sedi() { sed -i "$@"; }
Expand Down Expand Up @@ -125,7 +89,7 @@ init_module() {
deps=$(_lobash.get_module_metadata "$module_name" "Dependent")
if [[ -n "$deps" ]]; then
# shellcheck disable=2206
deps=( ${deps//,/ } )
deps=(${deps//,/ })
for dep in "${deps[@]}"; do
init_module "$dep"
done
Expand All @@ -148,15 +112,15 @@ init_with_config_file() {
echo -e "${GREY}To import category ${category_name}${RESET_ALL}"
while read -r module_name; do
init_module "$module_name"
done < "$SCRIPT_DIR/src/internals/categories/${category_name,,}"
done <"$SCRIPT_DIR/src/internals/categories/${category_name,,}"
done

while read -r module_name; do
init_module "$module_name"
done < <(grep -E '^ - \[x\]' "$CONFIG_PATH" | sed -E 's/^ - \[x\] +(.+)/\1/')

# shellcheck disable=2207
module_names=( $(l.union_array module_names) )
module_names=($(l.union_array module_names))
}

# Supported functions: VERBOSE_1, VERBOSE_2, VERBOSE_3, VERBOSE_4
Expand All @@ -175,13 +139,13 @@ init_verbose() {
fi

local i=1
while (( i <= 4 )); do
if (( i <= VERBOSE )); then
while ((i <= 4)); do
if ((i <= VERBOSE)); then
eval "VERBOSE_$i() { printf '%b[v=$i][%s:%s] %s%b\n' \"\$GREY\" \"\${BASH_LINENO}\" \"\${FUNCNAME[1]}\" \"\$1\" \"\$RESET_ALL\"; }"
else
eval "VERBOSE_$i() { true; }"
fi
i=$(( i + 1 ))
i=$((i + 1))
done
}

Expand All @@ -191,7 +155,7 @@ Usage: $0 [OPTIONS] [<output>]
Options:
-h, --help Show usage.
-c, --config Config file for building. If set, option "-p" will not work.
-c, --config <filepath> Config file for building. If set, option "-p" will not work.
-p <prefix> Prefix of variable names. [Default: l.]
-y, --yes Overwrite output.
-v <level> Show verbose. 0 means off. [Value: 0~4] [Default: 0]
Expand All @@ -204,17 +168,17 @@ EOF

# Reuse the last UNIQ_KEY if found
set_uniq_key() {
UNIQ_KEY=$( grep -E '^# UNIQ_KEY: ' "$TARGET" 2>/dev/null | sed -E 's/^# UNIQ_KEY: (.+)/\1/' || true)
UNIQ_KEY=$(grep -E '^# UNIQ_KEY: ' "$TARGET" 2>/dev/null | sed -E 's/^# UNIQ_KEY: (.+)/\1/' || true)

if [[ -n $UNIQ_KEY ]]; then return 0; fi

# Lobash built by Lobash 0.4 has not "# UNIQ_KEY" label. So try to get it from "readonly _LOBASH_[_0-9]+_PREFIX="
UNIQ_KEY=$( grep -E '^readonly _LOBASH_[_0-9]+_PREFIX=' "$TARGET" 2>/dev/null | sed -E 's/^readonly _LOBASH_([-_0-9]+)_PREFIX=.+/\1/' || true )
UNIQ_KEY=$(grep -E '^readonly _LOBASH_[_0-9]+_PREFIX=' "$TARGET" 2>/dev/null | sed -E 's/^readonly _LOBASH_([-_0-9]+)_PREFIX=.+/\1/' || true)

if [[ -n $UNIQ_KEY ]]; then return 0; fi

# If not found UNIQ_KEY, generate one based on current lobash version and time.
UNIQ_KEY=${VERSION//[^[:alnum:]]/_}_$(( $(date '+%s') - LOBASH_POUCH_TIME ))_$RANDOM
UNIQ_KEY=${VERSION//[^[:alnum:]]/_}_$(($(date '+%s') - LOBASH_POUCH_TIME))_$RANDOM
}

init() {
Expand All @@ -225,7 +189,7 @@ init() {

init_verbose

if (( ${#args[@]} == 0 )); then
if ((${#args[@]} == 0)); then
TARGET=$PWD/lobash.bash
else
if [[ -d ${args[0]} ]]; then
Expand Down Expand Up @@ -300,12 +264,11 @@ clean() {
answer=$(l.ask "Existed file: ${TARGET}. Overwrite it?" N)
echo -e "${GREY}$answer${RESET_ALL}"
case $answer in
YES )
;;
* )
echo "Not overwrite it. No new Lobash file generated."
exit 0
;;
YES) ;;
*)
echo "Not overwrite it. No new Lobash file generated."
exit 0
;;
esac
fi

Expand All @@ -316,7 +279,7 @@ clean() {
}

write() {
printf -- '%s\n' "$*" >> "$TARGET"
printf -- '%s\n' "$*" >>"$TARGET"
}

fwrite() {
Expand All @@ -328,18 +291,16 @@ fwrite() {
VERBOSE_3 "sed -E \"s/${WORD_BOUNDARY}${_LOBASH_PUBLIC_CONST_PREFIX}([_a-zA-Z0-9]+)/${PUBLIC_CONST_PREFIX}\\1/g\""

if [[ $PREFIX == 'l.' ]]; then
<"$1" \
sed -E "/^# /d;s/${WORD_BOUNDARY}($prefixes)([_a-zA-Z0-9]+)/\\1${UNIQ_KEY}_\\2/g" \
| sed -E "s/${WORD_BOUNDARY}${_LOBASH_PUBLIC_CONST_PREFIX}([_a-zA-Z0-9]+)/${PUBLIC_CONST_PREFIX}\\1/g" \
>> "$TARGET"
<"$1" sed -E "/^# /d;s/${WORD_BOUNDARY}($prefixes)([_a-zA-Z0-9]+)/\\1${UNIQ_KEY}_\\2/g" |
sed -E "s/${WORD_BOUNDARY}${_LOBASH_PUBLIC_CONST_PREFIX}([_a-zA-Z0-9]+)/${PUBLIC_CONST_PREFIX}\\1/g" \
>>"$TARGET"
else
VERBOSE_3 "sed -E \"s/${WORD_BOUNDARY}${_LOBASH_PUBLIC_FUNC_PREFIX//\./\\.}([_a-zA-Z0-9]+)/${PREFIX}\\1/g\""

<"$1" \
sed -E "/^# /d;s/${WORD_BOUNDARY}($prefixes)([_a-zA-Z0-9]+)/\\1${UNIQ_KEY}_\\2/g" \
| sed -E "s/${WORD_BOUNDARY}${_LOBASH_PUBLIC_CONST_PREFIX}([_a-zA-Z0-9]+)/${PUBLIC_CONST_PREFIX}\\1/g" \
| sed -E "s/${WORD_BOUNDARY}${_LOBASH_PUBLIC_FUNC_PREFIX//\./\\.}([_a-zA-Z0-9]+)/${PREFIX}\\1/g" \
>> "$TARGET"
<"$1" sed -E "/^# /d;s/${WORD_BOUNDARY}($prefixes)([_a-zA-Z0-9]+)/\\1${UNIQ_KEY}_\\2/g" |
sed -E "s/${WORD_BOUNDARY}${_LOBASH_PUBLIC_CONST_PREFIX}([_a-zA-Z0-9]+)/${PUBLIC_CONST_PREFIX}\\1/g" |
sed -E "s/${WORD_BOUNDARY}${_LOBASH_PUBLIC_FUNC_PREFIX//\./\\.}([_a-zA-Z0-9]+)/${PREFIX}\\1/g" \
>>"$TARGET"
fi
}

Expand Down Expand Up @@ -415,7 +376,7 @@ generate() {
_lobash.scan_module_metadata "$module_name"
bashver=$(_lobash.get_module_metadata "$module_name" "Bash")
compare=$(_lobash.semver_compare "$BASH_MIN_VERSION" "$bashver")
if (( compare < 0 )); then
if ((compare < 0)); then
skips[$module_name]=true
fi
done
Expand All @@ -442,16 +403,22 @@ generate() {

set +u
local skip_count=${#skips[@]}
echo "Imported $(( ${#module_names[@]} - skip_count )) modules. Skipped ${skip_count} modules."
echo "Imported $((${#module_names[@]} - skip_count)) modules. Skipped ${skip_count} modules."
set -u
echo -e "Generated Lobash file: ${GREEN}$TARGET${RESET_ALL}"
}

declare -A opts=()
declare -a args=()
declare -A opts_def=(
[opts]=opts
[args]=args
[-y --yes]='bool'
[-h --help]='bool'
)

main() {
l.parse_params opts args "$@"
l.parse_args opts_def "$@"
init
clean
generate "$@"
Expand Down
47 changes: 47 additions & 0 deletions example/modules/parse_args
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash

set -o errexit -o nounset -o pipefail -o errtrace
(shopt -p inherit_errexit &>/dev/null) && shopt -s inherit_errexit

SCRIPT_DIR="$(cd -P -- "$(dirname -- "$0")" && pwd -P)"
readonly SCRIPT_DIR
# shellcheck source=./init.bash
source "$SCRIPT_DIR"/init.bash

declare -A opts=()
declare -a args=()
declare -A params_def=(
[opts]=opts
[args]=args
[-f --flag]='bool default:1'
[-b]='bool'
)

foo() {
l.parse_args params_def "$@"
}

foo -a 3 -b12 -c=5 foo -d= bar -e -3 -4 a -F=abc -gh w -ij=5 -km= -5n -xzy --beep=boop baz --no-wow

echo 'foo -a 3 -b12 -c=5 foo -d= bar -e -3 -4 a -F=abc -gh w -ij=5 -km= -5n -xzy --beep=boop baz --no-wow'
echo "[${#opts[@]} Options]"
for key in "${!opts[@]}"; do
echo "$key: ${opts[$key]}"
done

printf "\n[%s Arguments]\n" "${#args[@]}"
declare i=0
for key in "${args[@]}"; do
echo "$i: $key"
((i += 1))
done

echo "------Use Options------"

# NOTE: Use ${opts[c]:-} instead of ${opts[c]}. If `set -o nounset`, ${opts[c]} will throw error when option omitted.
if [[ -n ${opts[c]:-} ]]; then
echo "c=${opts[c]}"
fi

echo "------Use Arguments------"
echo "${args[0]} ${args[1]} ${args[2]}"
Loading

0 comments on commit 2dc6505

Please sign in to comment.