A stack can now ship <name>.env and <name>.sh next to its compose files. The
hook is sourced with the tag helpers available, which is what the computing
.mk files of the catalogue were using make for: 29 of its 44 .mk files only
exist to build variables like the fabio tags.
Converting stack/host/fabio.mk by hand gives byte-identical output for the
route tag, and drops a trailing comma the make version left in the listener
list.
Also: APP_HOST and APP_URI are computed (the tag helpers build on them),
--color controls the escape codes rather than always emitting them, and
make test-portability runs the CLI under busybox ash and dash.
Setting IFS to a newline to pass the environment also stopped the command
line from splitting, so '-f a -f b' went out as a single argument and the two
words 'docker compose' were looked up as one program name. Every real command
was broken; only --dry-run, which prints a string, looked right.
The variables are now exported in a subshell instead of going through env(1),
which keeps values with spaces intact and leaves the command line to normal
word splitting.
The tests only checked what --dry-run printed, which is why they missed it.
spec/unit/compose_spec.sh now asserts the argv that is actually executed, for
both the plugin and the standalone binary.
An install under a custom prefix (--prefix ~/.local) could not find the
catalogue it had just cloned into <prefix>/share/myos: only the three system
paths were searched.
holcommon's empty .env made the loader evaluate one blank line, which
tripped set -u. Verified afterwards on holcommon's real host stack: the CLI
and the make engine resolve the same five files and render a byte-identical
241-line compose config.
A stack is a directory of compose files; the current directory is a stack when
it holds one. The same command works for a project, a catalogue stack, a group
and a host singleton, and stacks sharing a project are now a single compose
call.
Two traps of the make engine are closed on the way: an unknown command is an
error instead of a silent success, and a group is only expanded when its name
is lowercase, so an environment variable can no longer be mistaken for one.
That guard spells out its character class because a-z matches uppercase too
under a dictionary collation.
config: dotenv files are parsed, never sourced, so a value can hold a # or a
$(...) without breaking or executing. The make engine included .env with
make syntax, which neither allowed.
compose: one call per project instead of one per sub-stack.
Replaces the 500-character stack_path expression of
make/apps/def.docker.mk:159 and its leaked $(stackz) loop variable with
three readable functions, covered by 20 assertions.
Ported from make/utils.mk, make/def.mk, make/apps/def.docker.mk and
make/apps/def.mk, with the examples that sat as dead comments in
make/apps/def.mk turned into actual assertions.
Two deviations from the make macros are pinned and documented in DELTAS.md;
both only show up on code paths nothing uses.