mirror of
https://github.com/dredx/prole.git
synced 2026-09-27 19:04:30 +00:00
- Introduce lib/shell helpers and keep etc/* scripts thin via compatibility shims - Move Kerberos validation to scripts/validation/check_kerberos.sh and update callers - Add deterministic shellspec unit tests under tests/shellspec/ and wire Maven to run them - Add minimal Spring Boot authority module with startup + /health endpoint and Maven wiring - Document the new layout in docs/layout.md Co-authored-by: Junie <junie@jetbrains.com>
766 lines
21 KiB
Bash
766 lines
21 KiB
Bash
#shellcheck shell=sh disable=SC2016
|
|
|
|
: "${SHELLSPEC_SHELL_TYPE:=}" "${SHELLSPEC_SHELL_VERSION:=}"
|
|
SHELLSPEC_SH_VERSION=$(eval 'echo "${.sh.version}"' 2>/dev/null) ||:
|
|
: "${SHELLSPEC_SH_VERSION:=${SH_VERSION:-}}"
|
|
: "${SHELLSPEC_SH_VERSION:=${NETBSD_SHELL:-}}"
|
|
|
|
shellspec_shell_info() {
|
|
SHELLSPEC_SHELL_TYPE='sh'
|
|
shellspec_shell_version bash BASH_VERSION && return 0
|
|
shellspec_shell_version zsh ZSH_VERSION && return 0
|
|
shellspec_shell_version yash YASH_VERSION && return 0
|
|
shellspec_shell_version posh POSH_VERSION && return 0
|
|
if shellspec_shell_version ksh KSH_VERSION; then
|
|
case $SHELLSPEC_SHELL_VERSION in
|
|
*MIRBSD* ) SHELLSPEC_SHELL_TYPE=mksh ;;
|
|
*LEGACY* ) SHELLSPEC_SHELL_TYPE=lksh ;;
|
|
*PD\ KSH*) SHELLSPEC_SHELL_TYPE=pdksh ;;
|
|
esac
|
|
else
|
|
SHELLSPEC_SHELL_VERSION=$SHELLSPEC_SH_VERSION
|
|
case $SHELLSPEC_SHELL_VERSION in
|
|
*BUILD* ) SHELLSPEC_SHELL_TYPE="sh" ;;
|
|
*PD\ KSH*) SHELLSPEC_SHELL_TYPE="pdksh" ;;
|
|
*pbosh* ) SHELLSPEC_SHELL_TYPE="pbosh" ;;
|
|
*bosh* ) SHELLSPEC_SHELL_TYPE="bosh" ;;
|
|
?* ) SHELLSPEC_SHELL_TYPE="ksh" ;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
shellspec_shell_version() {
|
|
SHELLSPEC_SHELL_TYPE='sh' SHELLSPEC_SHELL_VERSION=''
|
|
eval "[ \${$2+x} ] &&:" || return 1
|
|
eval "SHELLSPEC_SHELL_TYPE=\$1 SHELLSPEC_SHELL_VERSION=\${$2}"
|
|
}
|
|
|
|
shellspec_shell_info
|
|
|
|
shellspec_constants() {
|
|
set -- "${1:-}"
|
|
|
|
SHELLSPEC_EVAL="
|
|
${1}SOH='\\001' ${1}STX='\\002' ${1}ETX='\\003' ${1}EOT='\\004' \
|
|
${1}ENQ='\\005' ${1}ACK='\\006' ${1}BEL='\\007' ${1}BS='\\010' \
|
|
${1}HT='\\011' ${1}TAB='\\011' ${1}LF='\\012' ${1}VT='\\013' \
|
|
${1}FF='\\014' ${1}CR='\\015' ${1}SO='\\016' ${1}SI='\\017' \
|
|
${1}DLE='\\020' ${1}DC1='\\021' ${1}DC2='\\022' ${1}DC3='\\023' \
|
|
${1}DC4='\\024' ${1}NAK='\\025' ${1}SYN='\\026' ${1}ETB='\\027' \
|
|
${1}CAN='\\030' ${1}EM='\\031' ${1}SUB='\\032' ${1}ESC='\\033' \
|
|
${1}FS='\\034' ${1}GS='\\035' ${1}RS='\\036' ${1}US='\\037' \
|
|
"
|
|
# shellcheck disable=SC2059
|
|
eval "$("$SHELLSPEC_PRINTF" "$SHELLSPEC_EVAL")"
|
|
|
|
# Workaround: Variable CR is empty on MSYS
|
|
if eval "[ \${#${1}CR} -eq 0 ] &&:"; then
|
|
set -- "$1" "$("$SHELLSPEC_PRINTF" '\015_')"
|
|
eval "${1}CR=\${2%_}"
|
|
fi
|
|
}
|
|
|
|
shellspec_constants SHELLSPEC_
|
|
# shellcheck disable=SC2153,SC2034
|
|
SHELLSPEC_IFS=" ${SHELLSPEC_TAB}${SHELLSPEC_LF}"
|
|
|
|
if [ "$SHELLSPEC_DEFECT_EMPTYPARAMS" ]; then
|
|
shellspec_proxy() {
|
|
eval "$1() { case \$# in (0) $2 ;; (*) $2 \"\$@\" ;; esac; }"
|
|
}
|
|
else
|
|
shellspec_proxy() {
|
|
eval "$1() { $2 \"\$@\"; }"
|
|
}
|
|
fi
|
|
|
|
shellspec_import() {
|
|
shellspec_find_module "$SHELLSPEC_LOAD_PATH" "$1" "SHELLSPEC_SOURCE"
|
|
shift
|
|
if [ $# -eq 0 ]; then
|
|
shellspec_source "$SHELLSPEC_SOURCE"
|
|
else
|
|
shellspec_source "$SHELLSPEC_SOURCE" "$@"
|
|
fi
|
|
}
|
|
|
|
shellspec_resolve_module_path() {
|
|
shellspec_find_module "$SHELLSPEC_LOAD_PATH" "$2" "$1"
|
|
}
|
|
|
|
shellspec_module_exists() {
|
|
set -- "$1" "${2:-$SHELLSPEC_LOAD_PATH}"
|
|
[ -e "${2%%$SHELLSPEC_PATHSEP*}/$1.sh" ] && return 0
|
|
[ -e "${2%%$SHELLSPEC_PATHSEP*}/$1/$1.sh" ] && return 0
|
|
case $2 in (*$SHELLSPEC_PATHSEP*)
|
|
shellspec_module_exists "$1" "${2#*$SHELLSPEC_PATHSEP}" &&:
|
|
return $?
|
|
esac
|
|
return 1
|
|
}
|
|
|
|
shellspec_find_module() {
|
|
if [ -e "${1%%$SHELLSPEC_PATHSEP*}/$2.sh" ]; then
|
|
eval "$3=\${1%%\$SHELLSPEC_PATHSEP*}/\$2.sh"
|
|
return 0
|
|
fi
|
|
if [ -e "${1%%$SHELLSPEC_PATHSEP*}/$2/$2.sh" ]; then
|
|
eval "$3=\${1%%\$SHELLSPEC_PATHSEP*}/\$2/\$2.sh"
|
|
return 0
|
|
fi
|
|
case $1 in (*$SHELLSPEC_PATHSEP*)
|
|
shellspec_find_module "${1#*$SHELLSPEC_PATHSEP}" "$2" "$3"
|
|
return 0
|
|
esac
|
|
shellspec_error "The required module '$2' is not found in SHELLSPEC_LOAD_PATH."
|
|
}
|
|
|
|
shellspec_source() {
|
|
SHELLSPEC_SOURCE=$1
|
|
shift
|
|
# shellcheck disable=SC1090
|
|
. "$SHELLSPEC_SOURCE"
|
|
}
|
|
|
|
if [ "${ZSH_VERSION:-}" ]; then
|
|
shellspec_find_files() {
|
|
if eval '[[ -o nonomatch ]]'; then
|
|
shellspec_find_files_ "$@"
|
|
else
|
|
setopt nonomatch
|
|
shellspec_find_files_ "$@"
|
|
unsetopt nonomatch
|
|
fi
|
|
}
|
|
else
|
|
shellspec_proxy shellspec_find_files shellspec_find_files_
|
|
fi
|
|
shellspec_find_files_() {
|
|
SHELLSPEC_EVAL="
|
|
shift; \
|
|
while [ \$# -gt 0 ]; do \
|
|
case \$1 in (*/[*]) shift; continue; esac; \
|
|
if [ -d \"\$1\" ]; then \
|
|
shellspec_find_files__ \"$1\" \"\${1%/}\"; \
|
|
else \
|
|
\"$1\" \"\$1\"; \
|
|
fi; \
|
|
shift; \
|
|
done \
|
|
"
|
|
eval "$SHELLSPEC_EVAL"
|
|
}
|
|
shellspec_find_files__() {
|
|
SHELLSPEC_EVAL="
|
|
SHELLSPEC_IFSORIG=\$IFS; IFS=''; set -- \$2/*; IFS=\$SHELLSPEC_IFSORIG; \
|
|
if [ \$# -gt 0 ]; then shellspec_find_files_ \"$1\" \"\$@\"; fi
|
|
"
|
|
eval "$SHELLSPEC_EVAL"
|
|
}
|
|
# Workaround for posh 0.10.2. do not glob with set -u.
|
|
if [ "${POSH_VERSION:-}" ] && [ "$(set -u; echo /*)" = '/*' ]; then
|
|
shellspec_find_files__() {
|
|
SHELLSPEC_EVAL="
|
|
SHELLSPEC_IFSORIG=\$IFS; IFS=''; \
|
|
case \$- in (*u*) set +u ;; esac; \
|
|
set -- \$2/*; set -u; IFS=\$SHELLSPEC_IFSORIG; \
|
|
if [ \$# -gt 0 ]; then shellspec_find_files_ \"$1\" \"\$@\"; fi \
|
|
"
|
|
eval "$SHELLSPEC_EVAL"
|
|
}
|
|
fi
|
|
|
|
shellspec_printf() {
|
|
eval '"$SHELLSPEC_PRINTF"' ${1+'"$@"'}
|
|
}
|
|
|
|
# `echo` not has portability, and external 'printf' command is slow.
|
|
# Use shellspec_puts or shellspec_putsn replacement of 'echo'.
|
|
# Those commands output arguments as it. (not interpret -n and escape sequence)
|
|
shellspec_puts() {
|
|
[ "$SHELLSPEC_BUILTIN_PRINTF" ] && return 0
|
|
if [ "$SHELLSPEC_BUILTIN_PRINT" ]; then
|
|
[ "${ZSH_VERSION:-}" ] && return 1 || return 2
|
|
fi
|
|
if [ "${POSH_VERSION:-}" ]; then
|
|
[ "${1#*\\}" ] && return 3 || return 4
|
|
fi
|
|
return 9
|
|
}
|
|
shellspec_puts "\\" &&:
|
|
case $? in
|
|
0 | 9)
|
|
# Use built-in or external 'printf'.
|
|
shellspec_puts() {
|
|
IFS=" $IFS"; "$SHELLSPEC_PRINTF" '%s' "${*:-}"; IFS=${IFS#?}
|
|
}
|
|
shellspec_putsn() {
|
|
IFS=" $IFS"; "$SHELLSPEC_PRINTF" '%s\n' "${*:-}"; IFS=${IFS#?}
|
|
}
|
|
;;
|
|
1)
|
|
# zsh 3.1.9, 4.0.4
|
|
shellspec_puts() { builtin print -nr -- "${@:-}"; }
|
|
shellspec_putsn() { builtin print -r -- "${@:-}"; }
|
|
;;
|
|
2)
|
|
# ksh88, mksh (depends on compile option), OpenBSD ksh (loksh, oksh), pdksh
|
|
shellspec_puts() { command print -nr -- "${@:-}"; }
|
|
shellspec_putsn() { command print -r -- "${@:-}"; }
|
|
;;
|
|
3)
|
|
# posh 0.3.14, 0.5.4 + workaround for parameter expansion bug
|
|
shellspec_puts() {
|
|
if [ $# -eq 1 ] && [ "$1" = "-n" ]; then
|
|
builtin echo -n -; builtin echo -n n; return 0
|
|
fi
|
|
IFS=" $IFS"; set -- "${*:-}\\" ""; IFS=${IFS#?}
|
|
while [ "$1" ]; do set -- "${1#*\\\\}" "$2${2:+\\\\}${1%%\\\\*}"; done
|
|
builtin echo -n "$2"
|
|
}
|
|
shellspec_putsn() { [ $# -gt 0 ] && shellspec_puts "$@"; builtin echo; }
|
|
;;
|
|
4)
|
|
# posh
|
|
shellspec_puts() {
|
|
if [ $# -eq 1 ] && [ "$1" = "-n" ]; then
|
|
builtin echo -n -; builtin echo -n n; return 0
|
|
fi
|
|
IFS=" $IFS"; set -- "${*:-}\\" ""; IFS=${IFS#?}
|
|
while [ "$1" ]; do set -- "${1#*\\}" "$2${2:+\\\\}${1%%\\*}"; done
|
|
builtin echo -n "$2"
|
|
}
|
|
shellspec_putsn() { [ $# -gt 0 ] && shellspec_puts "$@"; builtin echo; }
|
|
;;
|
|
esac
|
|
|
|
shellspec_error() { shellspec_putsn "$*" >&2; exit 1; }
|
|
|
|
# $1: callback, $2-: parameters
|
|
shellspec_each() {
|
|
[ $# -gt 1 ] || return 0
|
|
eval "shift; shellspec_each_ $1 1 \"\$@\""
|
|
}
|
|
shellspec_each_() {
|
|
eval "$1 \"\${$(($2 + 2))}\" $2 $(($# - 2))"
|
|
[ "$2" -lt "$(($# - 2))" ] || return 0
|
|
eval "shift 2; shellspec_each_ $1 $(($2 + 1)) \"\$@\""
|
|
}
|
|
|
|
# $1: callback, $2: from, $3: to $4: step
|
|
shellspec_sequence() {
|
|
if [ "$2" -lt "$3" ]; then
|
|
shellspec_sequence_ "$1" "$2" "$3" "${4:-1}" -le
|
|
else
|
|
shellspec_sequence_ "$1" "$2" "$3" "${4:--1}" -ge
|
|
fi
|
|
}
|
|
shellspec_sequence_() {
|
|
eval "[ \"$2\" \"$5\" \"$3\" ] &&:" || return 0
|
|
"$1" "$2"
|
|
shellspec_sequence_ "$1" $(($2 + $4)) "$3" "$4" "$5"
|
|
}
|
|
|
|
shellspec_loop() {
|
|
[ "$2" -gt 0 ] || return 0
|
|
"$1"
|
|
shellspec_loop "$1" $(($2 - 1))
|
|
}
|
|
|
|
shellspec_get_line() {
|
|
[ "$2" -le 0 ] && set -- "$1" "$2" ""
|
|
while [ "$2" -gt 1 ]; do
|
|
case $3 in
|
|
*$SHELLSPEC_LF*) set -- "$1" $(($2 - 1)) "${3#*$SHELLSPEC_LF}" ;;
|
|
*) set -- "$1" "$2" "" && break
|
|
esac
|
|
done
|
|
[ "$3" ] && eval "$1=\${3%%\$SHELLSPEC_LF*}" && return 0
|
|
unset "$1" ||:
|
|
}
|
|
|
|
shellspec_count_lines() {
|
|
set -- "$1" "$2" 0
|
|
while [ "$2" ]; do
|
|
case $2 in
|
|
*$SHELLSPEC_LF*) set -- "$1" "${2#*$SHELLSPEC_LF}" $(($3 + 1)) ;;
|
|
*) set -- "$1" "$2" $(($3 + 1)) && break
|
|
esac
|
|
done
|
|
eval "$1=\$3"
|
|
}
|
|
|
|
# $1: variable, $2: string, $3 N times
|
|
shellspec_padding() {
|
|
eval "$1=''"
|
|
shellspec_padding_ "$1" "$2" "$3"
|
|
}
|
|
shellspec_padding_() {
|
|
[ "$3" -eq 0 ] && return 0
|
|
eval "$1=\"\${$1:-}\$2\""
|
|
shellspec_padding_ "$1" "$2" $(($3 - 1))
|
|
}
|
|
|
|
shellspec_wrap() {
|
|
[ ! "$2" ] && eval "$1=" && return 0
|
|
case $2 in
|
|
*"$SHELLSPEC_LF") set -- "$1" "$2" "${3:-}" "${4:-}" "" "" ;;
|
|
*) set -- "$1" "$2${SHELLSPEC_LF}" "${3:-}" "${4:-}" "" x ;;
|
|
esac
|
|
while [ "$2" ]; do
|
|
set -- "$1" "${2#*$SHELLSPEC_LF}" "$3" "$4" \
|
|
"$5$3${2%%$SHELLSPEC_LF*}$4${SHELLSPEC_LF}" "$6"
|
|
done
|
|
[ "$6" ] && set -- "$1" "$2" "$3" "$4" "${5%$SHELLSPEC_LF}"
|
|
eval "$1=\$5"
|
|
}
|
|
|
|
shellspec_readfile() {
|
|
set -- "$1" "$2" ""
|
|
eval "$1="
|
|
while IFS= read -r "$1"; do
|
|
eval "set -- \"\$1\" \"\$2\" \"\$3\${$1}\$SHELLSPEC_LF\""
|
|
done < "$2" &&:
|
|
eval "$1=\"\$3\${$1}\""
|
|
}
|
|
|
|
shellspec_capturefile() {
|
|
shellspec_readfile "$@"
|
|
shellspec_chomp "$@"
|
|
}
|
|
|
|
shellspec_trim() {
|
|
SHELLSPEC_EVAL="
|
|
$1=\${2:-}; [ \"\$$1\" ] || return 0; \
|
|
$1=\${$1#\"\${$1%%[!\$SHELLSPEC_IFS]*}\"}; \
|
|
$1=\${$1%\"\${$1##*[!\$SHELLSPEC_IFS]}\"}
|
|
"
|
|
eval "$SHELLSPEC_EVAL"
|
|
}
|
|
|
|
# $1: ret, $2: from, $3: to
|
|
# $1: ret, $2: value, $3: from, $4: to
|
|
shellspec_replace_all_fast() {
|
|
if [ $# -lt 4 ]; then
|
|
eval "$1=\${$1//\"\$2\"/\"\$3\"}"
|
|
else
|
|
eval "$1=\${2//\"\$3\"/\"\$4\"}"
|
|
fi
|
|
}
|
|
|
|
# $1: ret, $2: from, $3: to
|
|
# $1: ret, $2: value, $3: from, $4: to
|
|
shellspec_replace_all_posix() {
|
|
if [ $# -lt 4 ]; then
|
|
eval "set -- \"\$1\" \"\${$1}\" \"\$2\" \"\$3\" \"\""
|
|
else
|
|
set -- "$1" "$2" "$3" "$4" ""
|
|
fi
|
|
until [ _"$2" = _"${2#*"$3"}" ] && eval "$1=\$5\$2"; do
|
|
set -- "$1" "${2#*"$3"}" "$3" "$4" "$5${2%%"$3"*}$4"
|
|
done
|
|
}
|
|
|
|
# $1: ret, $2: from, $3: to
|
|
# $1: ret, $2: value, $3: from, $4: to
|
|
shellspec_replace_all_fallback() {
|
|
[ $# -lt 4 ] && eval "set -- \"\$1\" \"\${$1}\" \"\$2\" \"\$3\""
|
|
shellspec_meta_escape "$1" "$3"
|
|
eval "set -- \"\$1\" \"\$2\" \"\${$1}\" \"\$4\" \"\""
|
|
until eval "[ _\"\$2\" = _\"\${2#*$3}\" ] && $1=\$5\$2"; do
|
|
eval "set -- \"\$1\" \"\${2#*$3}\" \"\$3\" \"\$4\" \"\$5\${2%%$3*}\$4\""
|
|
done
|
|
}
|
|
|
|
shellspec_includes_posix() {
|
|
case $1 in (*"$2"*) ;; (*) false ;; esac
|
|
}
|
|
|
|
shellspec_starts_with_posix() {
|
|
case $1 in ("$2"*) ;; (*) false ;; esac
|
|
}
|
|
|
|
shellspec_ends_with_posix() {
|
|
case $1 in (*"$2") ;; (*) false ;; esac
|
|
}
|
|
|
|
# shellcheck disable=SC2154
|
|
shellspec_includes_fallback() {
|
|
shellspec_meta_escape shellspec_includes_fallback "$2"
|
|
eval "[ ! \"\${1#*$shellspec_includes_fallback}\" = \"\$1\" ] &&:" &&:
|
|
}
|
|
|
|
# shellcheck disable=SC2154
|
|
shellspec_starts_with_fallback() {
|
|
shellspec_meta_escape shellspec_starts_with_fallback "$2"
|
|
eval "[ ! \"\${1#$shellspec_starts_with_fallback*}\" = \"\$1\" ] &&:" &&:
|
|
}
|
|
|
|
# shellcheck disable=SC2154
|
|
shellspec_ends_with_fallback() {
|
|
shellspec_meta_escape shellspec_ends_with_fallback "$2"
|
|
eval "[ ! \"\${1%*$shellspec_ends_with_fallback}\" = \"\$1\" ] &&:" &&:
|
|
}
|
|
|
|
shellspec_meta_escape() {
|
|
# shellcheck disable=SC1003
|
|
if [ "${1#*\?}" ]; then
|
|
# posh <= 0.5.4
|
|
set -- '\\\\:\\\\\\\\' '\\\[:[[]' '\\\?:[?]' '\\\*:[*]' '\\\$:[$]'
|
|
elif [ "${2%%\\*}" ]; then
|
|
# bosh = all (>= 20181007), busybox <= 1.22.0
|
|
set -- '\\\\:\\\\\\\\' '\[:[[]' '\?:[?]' '\*:[*]' '\$:[$]'
|
|
else
|
|
# POSIX compliant
|
|
set -- '\\:\\\\' '\[:[[]' '\?:[?]' '\*:[*]' '\$:[$]' '\#:[#]' '\~:[~]'
|
|
fi
|
|
|
|
set "$@" '\(:\\(' '\):\\)' '\|:\\|' '\":\\\"' '\`:\\\`' '\{:\\{' '\}:\\}' \
|
|
"\\':\\\\'" '\ :\\ ' '\&:\\&' '\=:\\=' '\<:\\<' '\>:\\>' '\;:\\;' '\^:\\^'\
|
|
'${SHELLSPEC_LF}:\${SHELLSPEC_LF}' '${SHELLSPEC_TAB}:\${SHELLSPEC_TAB}' \
|
|
'${SHELLSPEC_CR}:\${SHELLSPEC_CR}' '${SHELLSPEC_VT}:\${SHELLSPEC_VT}' end
|
|
|
|
echo 'shellspec_meta_escape() { set -- "$1" "$2" ""'
|
|
until [ "$1" = "end" ] && shift && "$SHELLSPEC_PRINTF" '%s\n' "$@"; do
|
|
set -- "${1%:*}" "${1#*:}" "$@"
|
|
set -- "$@" 'until [ _"$2" = _"${2#*'"$1"'}" ] && set -- "$1" "$3$2" ""; do'
|
|
set -- "$@" ' set -- "$1" "${2#*'"$1"'}" "$3${2%%'"$1"'*}'"$2"'"'
|
|
set -- "$@" 'done'
|
|
shift 3
|
|
done
|
|
echo 'eval "$1=\"\$2\""; }'
|
|
}
|
|
eval "$(shellspec_meta_escape "a?" "\\")"
|
|
|
|
shellspec_replace_all() {
|
|
(eval 'v="*#*/" p="#*/"; [ "${v//"$p"/-}" = "*-" ]') 2>/dev/null && return 0
|
|
[ "${1#"$2"}" = "a*b" ] && return 1 || return 2
|
|
}
|
|
eval 'shellspec_replace_all "a*b" "a[*]" &&:' &&:
|
|
case $? in
|
|
0)
|
|
# Fast version (Not POSIX compliant)
|
|
# ash(busybox)>=1.30.1, bash>=3.1.17, dash>=none, ksh>=93?, mksh>=54
|
|
# yash>=?, zsh>=?, pdksh=none, posh=none, bosh=none
|
|
shellspec_replace_all() { shellspec_replace_all_fast "$@"; }
|
|
shellspec_includes() { shellspec_includes_posix "$@"; }
|
|
shellspec_starts_with() { shellspec_starts_with_posix "$@"; }
|
|
shellspec_ends_with() { shellspec_ends_with_posix "$@"; }
|
|
;;
|
|
1)
|
|
# POSIX version (POSIX compliant)
|
|
# ash(busybox)>=1.1.3, bash>=2.05b, dash>=0.5.2, ksh>=93q, mksh>=40
|
|
# yash>=2.30?, zsh>=3.1.9?, pdksh=none, posh=none, bosh>=2020/04/27
|
|
shellspec_replace_all() { shellspec_replace_all_posix "$@"; }
|
|
shellspec_includes() { shellspec_includes_posix "$@"; }
|
|
shellspec_starts_with() { shellspec_starts_with_posix "$@"; }
|
|
shellspec_ends_with() { shellspec_ends_with_posix "$@"; }
|
|
;;
|
|
2)
|
|
# Fallback version
|
|
shellspec_replace_all() { shellspec_replace_all_fallback "$@"; }
|
|
shellspec_includes() { shellspec_includes_fallback "$@"; }
|
|
shellspec_starts_with() { shellspec_starts_with_fallback "$@"; }
|
|
shellspec_ends_with() { shellspec_ends_with_fallback "$@"; }
|
|
esac
|
|
|
|
# $2: pattern should be escaped
|
|
shellspec_match() {
|
|
( eval "export LC_ALL=C; case \${1:-} in ($2) :;; (*) false;; esac" ) &&:
|
|
}
|
|
|
|
shellspec_escape_quote() {
|
|
[ $# -lt 2 ] && eval "set -- \"\$1\" \"\$${1}\""
|
|
shellspec_replace_all "$1" "$2" "'" "'\"'\"'"
|
|
}
|
|
|
|
shellspec_pack() {
|
|
SHELLSPEC_EVAL="
|
|
$1=''; shift; \
|
|
for $1; do \
|
|
shellspec_escape_quote $1 \"\${$1}\"; \
|
|
set -- \"\$@\" \"'\${$1}'\"; \
|
|
shift; \
|
|
done; \
|
|
IFS=\" \$IFS\"; set -- \"\${*:-}\"; IFS=\${IFS#?}; unset $1; $1=\$1
|
|
"
|
|
eval "$SHELLSPEC_EVAL"
|
|
}
|
|
|
|
shellspec_match_pattern_escape() {
|
|
shellspec_replace_all "$1" \\ \\\\
|
|
shellspec_replace_all "$1" \" \\\"
|
|
shellspec_replace_all "$1" \# \\\#
|
|
shellspec_replace_all "$1" \$ \\\$
|
|
shellspec_replace_all "$1" \& \\\&
|
|
shellspec_replace_all "$1" \' \\\'
|
|
shellspec_replace_all "$1" \( \\\(
|
|
shellspec_replace_all "$1" \) \\\)
|
|
shellspec_replace_all "$1" \; \\\;
|
|
shellspec_replace_all "$1" \< \\\<
|
|
shellspec_replace_all "$1" \> \\\>
|
|
shellspec_replace_all "$1" \` \\\`
|
|
shellspec_replace_all "$1" \~ \\\~
|
|
shellspec_replace_all "$1" '=' '\='
|
|
shellspec_replace_all "$1" '^' '\^'
|
|
shellspec_replace_all "$1" ' ' '" "'
|
|
shellspec_replace_all "$1" "$SHELLSPEC_TAB" '${SHELLSPEC_TAB}'
|
|
shellspec_replace_all "$1" "$SHELLSPEC_LF" '${SHELLSPEC_LF}'
|
|
shellspec_replace_all "$1" "$SHELLSPEC_CR" '${SHELLSPEC_CR}'
|
|
shellspec_replace_all "$1" "$SHELLSPEC_VT" '${SHELLSPEC_VT}'
|
|
}
|
|
|
|
shellspec_match_pattern() {
|
|
[ "${2:-}" ] || return 1
|
|
shellspec_match_pattern=$2
|
|
shellspec_match_pattern_escape shellspec_match_pattern
|
|
set -- "$1" "$shellspec_match_pattern" /dev/null
|
|
( eval "export LC_ALL=C; case \$1 in ($2) :;; (*) false;; esac" ) 2>"$3" &&:
|
|
}
|
|
|
|
shellspec_join() {
|
|
[ $# -le 3 ] && eval "$1=\${3:-}" && return 0
|
|
SHELLSPEC_EVAL="
|
|
$1=\$3 && shift 3; \
|
|
while [ \$# -gt 0 ]; do $1=\"\${$1}$2\$1\" && shift; done \
|
|
"
|
|
eval "$SHELLSPEC_EVAL"
|
|
}
|
|
|
|
shellspec_shift10() {
|
|
while [ "$3" -gt 0 ]; do
|
|
case $2 in
|
|
*.*)
|
|
set -- "$1" "${2%.*}" "${2#*.}" "$3"
|
|
set -- "$1" $(($2 * 10)) "${3%"${3#?}"}" "${3#?}" "$4"
|
|
set -- "$1" "$(($2 + $3))${4:+.}$4" $(($5 - 1))
|
|
;;
|
|
*) set -- "$1" $(($2 * 10)) $(($3 - 1))
|
|
esac
|
|
done
|
|
|
|
while [ "$3" -lt 0 ]; do
|
|
case $2 in
|
|
*.*)
|
|
set -- "$1" "${2%.*}" "${2#*.}" "$3"
|
|
set -- "$1" "$(($2 / 10)).${2#"${2%?}"}$3" $(($4 + 1))
|
|
;;
|
|
*) set -- "$1" "$(($2 / 10)).${2#"${2%?}"}" $(($3 + 1))
|
|
esac
|
|
done
|
|
|
|
eval "$1=$2"
|
|
}
|
|
|
|
shellspec_chomp() {
|
|
SHELLSPEC_EVAL="
|
|
until case \$$1 in (*\$SHELLSPEC_LF) false; esac; do \
|
|
$1=\${$1%\$SHELLSPEC_LF}; \
|
|
done
|
|
"
|
|
eval "$SHELLSPEC_EVAL"
|
|
}
|
|
|
|
if [ "${ZSH_VERSION:-}" ]; then
|
|
shellspec_get_nth() {
|
|
set -- "$1" "$2" "${3#"${3%%[1-9]*}"}" "${4:-}" "$IFS"
|
|
IFS=${4:-$SHELLSPEC_IFS}
|
|
eval "set -- \"\$@\" \${=2}"
|
|
IFS=$5
|
|
[ $# -ge $(($3 + 5)) ] && eval "$1=\${$(($3 + 5))}"
|
|
}
|
|
else
|
|
shellspec_get_nth() {
|
|
set -f -u -- "$1" "$2" "${3#"${3%%[1-9]*}"}" "${4:-}" "$IFS" "$-"
|
|
IFS=${4:-$SHELLSPEC_IFS}
|
|
# shellcheck disable=SC2086
|
|
set -- "$@" $2
|
|
IFS=$5
|
|
[ "${6#*f}" = "$6" ] && set +f
|
|
# Workaround for posh 0.10.2: glob does not expand when set -u
|
|
[ "${6#*u}" = "$6" ] && set +u
|
|
[ $# -ge $(($3 + 6)) ] && eval "$1=\${$(($3 + 6))} &&:"
|
|
}
|
|
fi
|
|
|
|
shellspec_which() {
|
|
set -- "$1" "${PATH%$SHELLSPEC_PATHSEP}${SHELLSPEC_PATHSEP}"
|
|
while [ "${2%$SHELLSPEC_PATHSEP}" ]; do
|
|
if [ -x "${2%%$SHELLSPEC_PATHSEP*}/$1" ]; then
|
|
shellspec_putsn "${2%%$SHELLSPEC_PATHSEP*}/$1"
|
|
return 0
|
|
fi
|
|
set -- "$1" "${2#*$SHELLSPEC_PATHSEP}"
|
|
done
|
|
return 1
|
|
}
|
|
|
|
shellspec_is_empty_file() {
|
|
[ "${1:-}" ] && [ -f "${1:-}" ] && [ ! -s "${1:-}" ]
|
|
}
|
|
|
|
shellspec_is_empty_directory() {
|
|
[ -d "$1" ] || return 1
|
|
|
|
# This subshell is used to revert changes directory, variables and shell flags
|
|
( CDPATH=
|
|
# set -- "$DIR"/* not working properly in posh 0.10.2
|
|
cd "$1" || return 1
|
|
|
|
# workaround for posh 0.10.2: glob does not expand when set -u
|
|
set +o noglob +u
|
|
# shellcheck disable=SC2039
|
|
[ "${SHELLSPEC_FAILGLOB_AVAILABLE:-}" ] && shopt -u failglob
|
|
[ "${SHELLSPEC_NOMATCH_AVAILABLE:-}" ] && setopt NO_NOMATCH
|
|
|
|
for found in * .*; do
|
|
case $found in (.|..) continue; esac
|
|
[ -e "$found" ] && return 1
|
|
done &&:
|
|
return 0
|
|
)
|
|
}
|
|
|
|
shellspec_pluralize() {
|
|
[ $# -eq 2 ] && set -- "$1" "" "$2"
|
|
[ "${3%% *}" ] || return 0
|
|
[ "${3%% *}" -eq 1 ] && eval "$1=\${$1}\${2}\${3}\${4:-}" && return 0
|
|
case $3 in
|
|
*x) eval "$1=\${$1}\${2}\${3}es\${4:-}" ;;
|
|
*) eval "$1=\${$1}\${2}\${3}s\${4:-}" ;;
|
|
esac
|
|
}
|
|
|
|
shellspec_exists_file() {
|
|
[ -e "$1" ]
|
|
}
|
|
|
|
shellspec_unsetf() {
|
|
if shellspec_is_function "$1"; then
|
|
# Workaround for posh.
|
|
# Define function that run external command instead of unset function.
|
|
# Unset the function cause not be able to run external command with posh.
|
|
eval "$1() { case \$# in (0) command $1;; (*) command $1 \"\$@\"; esac; }"
|
|
return 0
|
|
fi
|
|
if [ "$SHELLSPEC_BUILTIN_TYPESETF" ]; then
|
|
# shellcheck disable=SC2039
|
|
typeset -f "$1" >/dev/null 2>&1 || return 0
|
|
elif [ "${POSH_VERSION:-}" ]; then
|
|
( unset -f "$1" 2>/dev/null ) || return 0
|
|
fi
|
|
unset -f "$1" 2>/dev/null ||:
|
|
return 0
|
|
}
|
|
|
|
if [ "$SHELLSPEC_DEFECT_EXPORTP" ]; then
|
|
shellspec_exportp() { export; }
|
|
else
|
|
shellspec_exportp() { export -p; }
|
|
fi
|
|
|
|
shellspec_list_envkeys() {
|
|
set -- "$1" "shellspec_list_envkeys"
|
|
eval "$2_callback() { $1 \"\$@\"; }; $(shellspec_exportp | "$2_rework")" &&:
|
|
}
|
|
shellspec_list_envkeys_rework() {
|
|
set -- printf '%s\n'
|
|
while IFS= read -r line; do
|
|
shellspec_list_envkeys_sanitize line "$line"
|
|
set -- "$@" "shellspec_list_envkeys_parse $line || return \$?"
|
|
done
|
|
"$@"
|
|
}
|
|
shellspec_list_envkeys_parse() {
|
|
while [ $# -gt 2 ]; do
|
|
case $2 in
|
|
*=*) break ;;
|
|
*) shift ;;
|
|
esac
|
|
done
|
|
[ $# -gt 1 ] && shift
|
|
shellspec_list_envkeys_callback "${1%%[=]*}"
|
|
}
|
|
|
|
# Sanitize to avoid security risk when environment variable name
|
|
# contains meta characters
|
|
#
|
|
# e.g.
|
|
# $ env 'FOO; echo bad; # =aaa' ksh -c 'export -p | grep FOO'
|
|
# export FOO; echo bad; # =aaa
|
|
shellspec_list_envkeys_sanitize() {
|
|
set -- "$IFS" "$1" "_$2_"
|
|
IFS='!#&()*;<>?[]`{|}~'
|
|
eval "set -- \"\$1\" \"\$2\" \${${ZSH_VERSION:+=}3}"
|
|
IFS="_$1"
|
|
eval "shift 2; $2=\"\$*\"; $2=\${$2%_}; $2=\${$2#_}"
|
|
IFS=${IFS#_}
|
|
}
|
|
|
|
shellspec_exists_envkey() {
|
|
(
|
|
key="$1"
|
|
callback() { [ ! "$1" = "$key" ] &&:; }
|
|
shellspec_list_envkeys callback && return 1
|
|
return 0
|
|
) &&:
|
|
}
|
|
|
|
shellspec_is_readonly() {
|
|
eval "[ \"\${$1+x}\" ] &&:" || return 1
|
|
eval "set -- \"\$1\" \"\${$1}\""
|
|
( eval "$1=_\$1 && [ ! \"\${$1}\" = \"\$2\" ]" ) 2>/dev/null && return 1
|
|
return 0
|
|
}
|
|
|
|
shellspec_abspath() {
|
|
case $PWD in
|
|
[a-zA-Z]:* | //*) shellspec_abspath_win "$@" ;;
|
|
*) shellspec_abspath_unix "$@" ;;
|
|
esac
|
|
}
|
|
|
|
shellspec_abspath_unix() {
|
|
case $2 in
|
|
/*) set -- "$1" "$2/" "" "" ;;
|
|
*) set -- "$1" "${3:-$PWD}/$2/" "" ""
|
|
esac
|
|
|
|
while [ "$2" ]; do
|
|
case ${2%%/*} in
|
|
"" | .) set -- "$1" "${2#*/}" "${2%%/*}" "$4" ;;
|
|
..) set -- "$1" "${2#*/}" "${2%%/*}" "${4%/*}" ;;
|
|
*) set -- "$1" "${2#*/}" "${2%%/*}" "$4/${2%%/*}"
|
|
esac
|
|
done
|
|
eval "$1=\"/\${4#/}\""
|
|
}
|
|
|
|
shellspec_chdrv() { cd "$1:" 2>/dev/null || exit; }
|
|
|
|
shellspec_abspath_win() {
|
|
set -- "$1" "$2" "${3:-$PWD}"
|
|
|
|
case $2 in (//*) # UNC path
|
|
shellspec_abspath_unix "$1" "${2#/}"
|
|
eval "$1=\"/\${$1}\""
|
|
return 0
|
|
esac
|
|
|
|
case $2 in
|
|
[a-zA-Z]:/*) set -- "$1" "/$2" ;;
|
|
[a-zA-Z]:*)
|
|
set -- "$1" "$2" "$(shellspec_chdrv "${2%%:*}" && echo "$3")"
|
|
set -- "$1" "/${3%/}/${2#?:}" ;;
|
|
/*) set -- "$1" "/${3%%:*}:$2" ;;
|
|
*) set -- "$1" "/${3%/}/$2" ;;
|
|
esac
|
|
shellspec_abspath_unix "$@"
|
|
eval "$1=\"\${$1#/}\""
|
|
}
|
|
|
|
shellspec_mv() { "$SHELLSPEC_MV" "$@"; }
|
|
shellspec_rm() { "$SHELLSPEC_RM" "$@"; }
|
|
shellspec_chmod() { "$SHELLSPEC_CHMOD" "$@"; }
|
|
shellspec_sleep() { "$SHELLSPEC_SLEEP" "$@"; }
|