1 Commits

Author SHA1 Message Date
librelad
7a66801ead feat(lazy-load): function manifest generator + lpRegen wiring (Phase 2)
scripts/source/files/generate_function_manifest.sh — scans every .sh in
scripts/ (skip-list matches generate_arrays.sh, plus excludes peer_shell.sh
which is a standalone forced-command target) and emits
scripts/source/files/arrays/function_manifest.sh:

  declare -gA LP_FN_MAP=(
      [acquireSingletonLock]="crontab/task/crontab_task_processor.sh"
      [adoptDockerSubnet]="checks/requirements/check_docker_network.sh"
      ...                                  # 698 entries
  )
  LP_EAGER_FILES=(
      "backup/db/backup_db.sh"
      "source/files/arrays/files_app.sh"
      ...                                  # 32 entries (~7% of files)
  )

The lazy loader (Phase 3) consumes LP_FN_MAP to install autoload stubs of
the form `name() { source "$LP_FN_MAP[name]"; name "$@"; }`. First call
sources the real file, which redefines the stub with the real body;
subsequent calls hit the real one. LP_EAGER_FILES enumerates files with
top-level side effects (variable assignments, source calls, bare commands
outside any function) — those MUST always source so the side effects fire.

Heuristic correctness, in order of importance:
- Function header detection requires EMPTY parens (`name()`), not just
  `name(` — otherwise lines like `if (...)`, `for (...)`, `while (...)`
  in embedded awk/perl get misread as bash function defs.
- Handles three function styles: `name() {` (same line), `name()\n{`
  (LibrePortal convention), and one-liners `name() { body; }`.
- Tracks { } balance for inside-function depth, with the safe fallback that
  ambiguous cases get marked eager (false positive = no behaviour change;
  false negative would skip a needed source).
- Files containing embedded awk/perl with their own { } blocks (about 6 of
  them: cli_debug_commands.sh, crontab_task_processor.sh, backup_db.sh,
  backup_files.sh, etc.) get false-positive flagged eager — acceptable
  because they just stay eager-loaded, matching today's behaviour.
- Collisions report to stderr (last-write wins, same as eager-load
  semantics); no collisions found in the current tree.

Wiring:
- lpRegenArrays (`libreportal regen arrays`) now also runs the manifest
  generator when the existing arrays need regen, keeping the two in sync.
- update.sh's quick-deploy regen step does the same after copying files
  to the live install. Best-effort: failures don't abort because lazy
  loading is opt-in (LP_LAZY=1) in Phase 3 and not the default yet.

Scanned: 454 files, indexed 698 function definitions, 32 eager (9 real,
23 auto-generated arrays + the manifest itself). 0 name collisions.

No behaviour change in this commit — the manifest is just data the loader
in Phase 3 will use. The default eager loading path is untouched.

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-26 20:47:54 +01:00