Files
cligen/utils/flag_matrix.sh
T
tristan 4cce5cc45c Modified a few things:
- Finished implementing relative date parsing and migrated date parsing
  from Flag(T) to it's own dedicated module. Additionally added a
  the ability to do "recursive" relative operations for time searching.
- Additionally made a Struct & Enum for containing relative operations
  around dates.
- Added additional checks in App & CommandNode(T) around checking
  env_vars of flags & checking for duplicate commands
- Added a CommandMeta record to contain the classname of the
  CommandNode(T)
- Seperated out all of the monolitic files (command_node.cr & file.cr).
  Moved the base classes and records into their own files in the dir
  with the same name of their generic counterparts.
- Fixed a number of macro related bugs around Command.argument &
  CliGen.add_global_flag
- My ass hurts from sitting here for hours and doing these changes and
  arguing with claude over what needs to be done. Fun tho.
2026-08-30 22:13:39 -05:00

88 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
# Copyright 2026 Tristan Ancelet
#
# Runs flag_matrix.cr across every value source (default / env / CLI) for both
# a global flag and a command argument, and checks each result.
#
# Each case needs its own process because env vars must be set before startup,
# which is why this lives here rather than in spec/.
#
# ./utils/flag_matrix.sh (runnable from anywhere)
#
# Exits non-zero if any case does not match.
set -u
# Build from the PROJECT ROOT, not utils/. Two things depend on the CWD:
# - `require "cligen"` resolves via ./lib/cligen (the self-symlink)
# - command_node.cr renders ECR from the hardcoded relative path
# "lib/cligen/src/cligen/template/cmd_help.ecr"
# Building inside utils/ breaks both.
cd "$(dirname "$0")/.."
SRC=utils/flag_matrix.cr
BIN=utils/flag_matrix
pass=0
fail=0
echo "building..."
if ! crystal build "$SRC" -o "$BIN" 2>&1 | grep -v sframe; then :; fi
[ -x "$BIN" ] || { echo "build failed"; exit 1; }
echo
# check <label> <expected-substring> <env-assignments> <args...>
#
# Matches against the FULL output, not just the last line - multi-line output
# such as help text would otherwise only ever be compared against its footer.
# Only the last line is echoed back, to keep the report readable.
check() {
local label="$1" want="$2" envs="$3"; shift 3
local got shown
got=$(env $envs "$BIN" "$@" 2>&1)
shown=$(printf '%s' "$got" | tail -1)
if [[ "$got" == *"$want"* ]]; then
printf ' ok %-44s %s\n' "$label" "$shown"
pass=$((pass + 1))
else
printf ' FAIL %-44s %s\n' "$label" "$shown"
printf ' %-44s want substring: %s\n' "" "$want"
fail=$((fail + 1))
fi
}
echo "== defaults =="
check "no env, no flags" "retries=3 level=1 name=world" "" greet
echo
echo "== global flag: --retries (env RETRIES, valid 0..10) =="
check "env valid" "retries=7" "RETRIES=7" greet
check "env invalid -> rejected" "validation failed for --retries" "RETRIES=99" greet
check "cli valid" "retries=5" "" greet -r 5
check "cli invalid -> rejected" "validation failed for --retries" "" greet -r 99
check "cli overrides env" "retries=2" "RETRIES=8" greet -r 2
echo
echo "== command arg: --level (env GREET_LEVEL, valid < 5) =="
check "env valid" "level=3" "GREET_LEVEL=3" greet
check "env invalid -> rejected" "validation failed for --level" "GREET_LEVEL=9" greet
check "cli valid" "level=4" "" greet --level 4
check "cli invalid -> rejected" "validation failed for --level" "" greet --level 9
check "cli overrides env" "level=2" "GREET_LEVEL=4" greet --level 2
check "un-namespaced LEVEL ignored" "level=1" "LEVEL=9" greet
echo
echo "== command arg: --name (no validation) =="
check "env" "name=Bob" "GREET_NAME=Bob" greet
check "cli" "name=Alice" "" greet --name Alice
echo
echo "== help output =="
check "root help lists globals" "--retries" "" --help
check "command help lists args" "--level" "" greet --help
echo
echo "$pass passed, $fail failed"
rm -f "$BIN"
[ "$fail" -eq 0 ]