summaryrefslogtreecommitdiff
path: root/src/lib/config.spec.source.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/config.spec.source.sh')
-rw-r--r--src/lib/config.spec.source.sh126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/lib/config.spec.source.sh b/src/lib/config.spec.source.sh
new file mode 100644
index 0000000..d4778a9
--- /dev/null
+++ b/src/lib/config.spec.source.sh
@@ -0,0 +1,126 @@
+# ----------------------------------------------------------------------------
+# Config field registry (single source of truth, task mr0)
+# ----------------------------------------------------------------------------
+# CONFIG_SPECS is the one place a config field's cross-cutting facts are
+# declared. Before mr0 the same knowledge (default value, CLI-overridability,
+# validation rule, how it prints) was restated in ~6 hand-maintained lists --
+# apply_config_defaults, CLI_CONFIG_OVERRIDE_TARGETS, validate_common_config,
+# print_config, and parts of log_configured_action / the dry-run plan -- so
+# adding or renaming an option was shotgun surgery and the lists drifted (the
+# TARBALL_INCLUDE default once flipped to 'no' here while shuriken.default.conf
+# still said 'yes', fixed in 7r0). Those consumers now DERIVE from this registry,
+# so a field's facts live in exactly one entry.
+#
+# Each entry is a '|'-delimited spec, the same encoding used by ACTION_SPECS
+# (action.source.sh) and TEMPLATE_RENDER_FIELD_SPECS (template.source.sh):
+#
+# name|default|has_default|cli_overridable|validation|print_kind
+#
+# name the config variable name (also the env/override key).
+# default the value apply_config_defaults applies via
+# VAR="${VAR:-$default}" when has_default=yes. May be empty
+# (e.g. FAVICON, HEIGHT default to the empty string).
+# has_default yes -> apply the scalar default above. no -> never apply a
+# scalar default: either a required var (TITLE, THUMBHEIGHT,
+# ...) that must be set in the config, or an array
+# (TAR_OPTS / SYNC_DESTINATIONS) defaulted separately via a
+# `declare -p` guard in apply_config_defaults.
+# cli_overridable yes -> the field appears in CLI_CONFIG_OVERRIDE_TARGETS, i.e.
+# a CLI flag (declared in CLI_OPTION_SPEC) can override it. The
+# rich per-flag table (argument names, flag/value pairs) stays
+# in CLI_OPTION_SPEC; this facet only drives the override-target
+# list that used to be a separate hand-kept copy of it.
+# validation the rule validate_common_config applies. Empty means
+# validate_common_config does not check this field (SYNC_DELETE,
+# the timeouts only checked on their own paths, etc. are
+# validated elsewhere). One of:
+# required require_config_var (non-empty)
+# required-posint require_config_var + positive integer
+# posint positive integer (no non-empty requirement)
+# opt-posint positive integer only if set (HEIGHT)
+# percentage integer 0..100
+# yesno literal yes or no
+# favicon validate_favicon_config (readable file/empty)
+# print_kind how print_config emits the field. scalar -> %s=%q. array ->
+# %s=( ... ) via the resolve_*-fed array printer. Empty means
+# print_config does not emit it (none today). CONFIG_SOURCE is
+# printed separately (it is the resolved config path, not a
+# config variable) and so is not a registry entry.
+#
+# Entry order is the canonical print order (print_config emits in this order).
+# validate_common_config does NOT reuse this order directly: it runs all
+# `required*` checks before any kind check (so a missing required var is reported
+# before a malformed one -- see test_config_validators_fail_fast_without_errexit),
+# which it achieves with two filtered passes over the registry.
+#
+# Declared -g so it survives being sourced from inside a function (the test
+# harness sources the lib via test::source_shuriken_lib); a plain `declare -r`
+# would be function-local and vanish on return.
+declare -gra CONFIG_SPECS=(
+ 'INCOMING_DIR||no|yes|required|scalar'
+ 'DIST_DIR||no|yes|required|scalar'
+ 'TEMPLATE_DIR||no|yes|required|scalar'
+ 'FAVICON||yes|yes|favicon|scalar'
+ 'SOURCE_URL|https://codeberg.org/snonux/shuriken.sh|yes|yes||scalar'
+ 'TITLE||no|yes|required|scalar'
+ 'HEIGHT||yes|yes|opt-posint|scalar'
+ 'THUMBHEIGHT||no|yes|required-posint|scalar'
+ 'MAXPREVIEWS||no|yes|required-posint|scalar'
+ 'THUMB_SUBDIVIDE_PERCENT|30|yes|yes|percentage|scalar'
+ 'THUMB_FEATURE_PERCENT|10|yes|yes|percentage|scalar'
+ 'IMAGE_JOBS|3|yes|yes|required-posint|scalar'
+ 'IMAGEMAGICK_TIMEOUT|60|yes|no|posint|scalar'
+ 'RANDOM_SEED||yes|yes||scalar'
+ 'SHUFFLE|no|yes|yes|yesno|scalar'
+ 'SPLASH_PAGE|yes|yes|yes|yesno|scalar'
+ 'STATS_PAGE|no|yes|yes|yesno|scalar'
+ 'TARBALL_INCLUDE|yes|yes|yes|yesno|scalar'
+ 'TARBALL_SUFFIX|.tar|yes|no||scalar'
+ 'TAR_TIMEOUT|120|yes|no|posint|scalar'
+ 'TAR_OPTS||no|no||array'
+ 'SYNC_DELETE|yes|yes|yes||scalar'
+ 'SYNC_TIMEOUT|300|yes|no|posint|scalar'
+ 'SYNC_DESTINATIONS||no|no||array'
+ 'ORIGINAL_BASEPATH||yes|no||scalar'
+)
+
+# Split one CONFIG_SPECS entry into the caller's named array (IFS='|' read), the
+# same accessor pattern action_spec_field uses for ACTION_SPECS. Field indices:
+# 0 name 1 default 2 has_default 3 cli_overridable 4 validation 5 print_kind
+config_spec_split() {
+ local -r spec="$1"; shift
+ # shellcheck disable=SC2178
+ local -n fields_ref="$1"; shift
+
+ # fields_ref is a nameref output array filled for the caller; shellcheck
+ # cannot see the indirect use through the nameref.
+ # shellcheck disable=SC2034
+ IFS='|' read -r -a fields_ref <<< "$spec"
+}
+
+# Populate CLI_CONFIG_OVERRIDE_TARGETS from the registry: every field marked
+# cli_overridable=yes. This is the list apply_cli_overrides iterates to copy
+# parsed --flag values onto their config var. Declared (empty) in src/shuriken.sh
+# before the libs are sourced; filled here, once CONFIG_SPECS exists. Replaces the
+# hand-kept copy of CLI_OPTION_SPEC's config= targets that used to drift (mr0).
+# Iteration order is registry order; it is unobservable because each override
+# targets a distinct variable, so no field can shadow another.
+build_cli_config_override_targets() {
+ local spec
+ local -a fields=()
+
+ CLI_CONFIG_OVERRIDE_TARGETS=()
+ for spec in "${CONFIG_SPECS[@]}"; do
+ config_spec_split "$spec" fields
+ if [ "${fields[3]}" = yes ]; then
+ CLI_CONFIG_OVERRIDE_TARGETS+=("${fields[0]}")
+ fi
+ done
+}
+
+# Build the override-target list at source time so it is ready before any CLI
+# parsing. Guarded so sourcing this module without the shuriken.sh-level
+# declaration (e.g. a narrowly scoped unit test) is a no-op rather than an error.
+if declare -p CLI_CONFIG_OVERRIDE_TARGETS >/dev/null 2>&1; then
+ build_cli_config_override_targets
+fi