Files
stack/scripts/selector.sh
T
jason.woltje f198cfd47b selector: --org and --business in each CLI parser's own scope
Rename design r2, "Selector scopes and parser matrix". packages/business/src/selector.mjs
and scripts/selector.sh carry one rule set: in a parser's scope each spelling appears once,
and a second spelling must carry exactly the same value; a repeated spelling, a missing or
flag-shaped value, an invalid id and unequal values refuse. The file family
(--business-file/--org-file) compares paths as given.

Every CLI parser that took --business now takes --org through orgSelector, and the old
global --org rewrite in main() is gone, so a value another option consumes is never read as
a selector. The id is checked while parsing (OrgError org-invalid, exit 3), so grants admin
set no longer reads the token and proxy init no longer prompts for the key before an
invalid id refuses. access gains the same local id check.
2026-11-08 21:14:11 -06:00

53 lines
3.0 KiB
Bash

# Sourced, not run: organization selector options, the shell half of
# packages/business/src/selector.mjs (rename design r2, "Selector scopes and parser matrix"). A
# script in the same checkout sources it; it defines functions only and runs no other program.
#
# --org and --business are one option family (id), and --org-file and --business-file are another
# (file). A scope is one parser's own options, so the caller's own loop decides which tokens are
# selectors; text after a separator or a value another option consumes is never passed here. In a
# scope each spelling may appear once, and a second spelling must carry exactly the same value.
#
# selector_take SCOPE FAMILY REFUSE VALID FLAG [VALUE]
# SCOPE [a-z0-9_]+, the scope's name; each keeps its own spellings and value
# FAMILY id or file
# REFUSE a function called as REFUSE KIND MESSAGE that must exit; KIND is missing, flag,
# repeated, invalid or differ, so each script keeps its exit codes and wording
# VALID a predicate called as VALID VALUE, or - when the caller checks the value itself
# FLAG the spelling given
# VALUE absent when the argument list ended there; pass "${@:2:1}" from a loop on "$@"
# selector_value SCOPE prints the scope's value, nothing when none was given
#
# A missing or empty value, one starting with "-", one VALID refuses, a repeated spelling and two
# spellings with different values all refuse. File values are compared as given, not as paths.
selector__bug() { echo "selector.sh: $*" >&2; exit 70; }
selector_take() {
[ $# -ge 5 ] && [ $# -le 6 ] || selector__bug "selector_take takes 5 or 6 arguments, not $#"
local scope="$1" family="$2" refuse="$3" valid="$4" flag="$5"
[[ "$scope" =~ ^[a-z0-9_]+$ ]] || selector__bug "bad scope name $scope"
case "$family:$flag" in
id:--business|id:--org|file:--business-file|file:--org-file) ;;
*) selector__bug "$flag is not a $family selector" ;;
esac
local seen_name="SELECTOR_SEEN_$scope" value_name="SELECTOR_VALUE_$scope"
local seen="${!seen_name-}" current="${!value_name-}" first
case " $seen " in *" $flag "*) "$refuse" repeated "$flag given twice"; selector__bug "$refuse returned" ;; esac
if [ $# -lt 6 ] || [ -z "$6" ]; then "$refuse" missing "$flag needs one value"; selector__bug "$refuse returned"; fi
local value="$6"
case "$value" in -*) "$refuse" flag "$flag needs one value, not $value"; selector__bug "$refuse returned" ;; esac
if [ "$valid" != - ] && ! "$valid" "$value"; then "$refuse" invalid "$flag $value is not valid"; selector__bug "$refuse returned"; fi
first="${seen%% *}"
if [ -n "$seen" ] && [ "$current" != "$value" ]; then
"$refuse" differ "$first $current and $flag $value conflict"; selector__bug "$refuse returned"
fi
printf -v "$seen_name" '%s' "${seen:+$seen }$flag"
printf -v "$value_name" '%s' "$value"
}
selector_value() {
[[ "${1-}" =~ ^[a-z0-9_]+$ ]] || selector__bug "bad scope name ${1-}"
local value_name="SELECTOR_VALUE_$1"
printf '%s' "${!value_name-}"
}