expected structural change for 5.x
This commit is contained in:
+49
@@ -104,6 +104,55 @@ version-bump.
|
||||
|
||||
---
|
||||
|
||||
## Structure
|
||||
|
||||
- [ ] **Helpers must not stay in the environment (do first)** — internal
|
||||
functions (`_` prefix, `helpers/`) are not part of the user interface, yet 16
|
||||
of them are `export -f`, so they leak into the environment of every child
|
||||
process. By design they should only exist where they are needed:
|
||||
- stop exporting helpers by default; unset the ones only needed at load time
|
||||
(as `profile.sh` already does for `parse_conf`, `load_alias`, ...);
|
||||
- a helper stays exported only when an exported public function calls it and
|
||||
must work in a child bash (`bash -c`, `find -exec`, `xargs`), which has to
|
||||
be checked and documented one by one (otherwise that public function is no
|
||||
longer exported either, or waits for the stub mechanism below);
|
||||
- add a check (shellcheck-like script or `bats` test) listing exported
|
||||
functions starting with `_`, so none comes back unnoticed.
|
||||
This is the first step: it does not depend on the lazy loading below, which
|
||||
builds on it. **[medium]**
|
||||
- [ ] **Load code on demand (stubs, lazy loading, optional unloading)** —
|
||||
today every module is sourced at startup (about 63 ms, 109 functions) and 80
|
||||
functions are exported (about 250 KB of environment inherited by every
|
||||
external command, which makes each one about 25 % slower and eats `ARG_MAX`).
|
||||
Replace this by:
|
||||
- *Stubs*: each lazy command is a tiny generated function
|
||||
(`rain() { _lazy rain "$@"; }`), the only thing exported. The stubs come
|
||||
from a command-to-module index, built at upgrade time from a
|
||||
`# provides: ...` header in each module (so `help`, `type` and completion
|
||||
still see every command).
|
||||
- *Lazy loading* (`_try_load`): the first call sources the module and its
|
||||
`helpers/<module>.sh` (and the modules it depends on, declared in the
|
||||
header), then runs the real function (`_exec`). The code stays loaded
|
||||
afterwards. Helpers and implementations are no longer exported, which also
|
||||
removes them from the environment of child shells.
|
||||
- *Optional unloading* (`_free`, e.g. `PROFILE_UNLOAD=1`): after the call,
|
||||
put the stub back instead of unsetting the function. Must be idempotent
|
||||
(Ctrl-C or `return` skip the cleanup), must not free code still referenced
|
||||
by a trap (`_rain_stop`, WINCH handler) or used by a running caller
|
||||
(reference count), and costs about 4 ms per call, so it is not the default.
|
||||
- *Always resident*: `disp`, `conf`, `debug`, `prompt` (and the `DEBUG` timer
|
||||
hook), `lang` shortcuts and `help`. With unloading, state kept across calls
|
||||
(`pwd` pool, current theme, `settrace`) must live in variables that are not
|
||||
freed. Lazy candidates: `compress`,
|
||||
`filefct`, `fun`, `git`, `info`, `net`, `packages`, `processes`, `pwd`,
|
||||
`rain`, `ssh`, `updates`.
|
||||
- *To solve*: `load_conf`/`CONF_*` must stay available at call time; child
|
||||
shells need `MYPATH` and the loader exported to resolve stubs; tracebacks
|
||||
show the loader frames. Do it after the test suite exists, as regressions
|
||||
would be silent. **[hard]**
|
||||
|
||||
---
|
||||
|
||||
## Infrastructure
|
||||
|
||||
- [ ] **Test suite** — add a `test/` directory with `bats` (Bash Automated
|
||||
|
||||
Reference in New Issue
Block a user