Skip to content

0.1.8

Latest

Choose a tag to compare

@github-actions github-actions released this 09 Jul 05:08
ca24f96

compose2pod 0.1.8 — interpolation moves to run time

This release reverses 0.1.7: Compose ${VAR} interpolation now happens when
the generated script runs, not when compose2pod generates it. compose2pod
emits a script that runs later — typically in CI, where the real secrets and
config live — so resolving against compose2pod's own environment at generation
time baked any variable that was unset then to an empty string. References are
now emitted as live POSIX-shell fragments that the runtime shell expands.

Change

  • ${VAR} is interpolated at script-run time, not generation time.
    to_shell() (new compose2pod/shell.py) re-encodes every compose-derived
    value (environment, image, command, volumes, tmpfs, env_file,
    healthcheck test) into a double-quoted shell fragment whose variable
    references stay live, so the generated script's own shell resolves them
    against its runtime environment. All the 0.1.7 forms still work — $VAR,
    ${VAR}, ${VAR:-default}, ${VAR-default}, ${VAR:?msg}, ${VAR?msg},
    ${VAR:+alt}, ${VAR+alt}, $$ — mapping onto identical POSIX sh
    parameter expansion. A bare $VAR/${VAR} is emitted as ${VAR-} so an
    unset variable expands to empty under the script's set -eu instead of
    aborting; ${VAR:?msg} now fails the script at run time (not at generation).
    Command substitution and other shell metacharacters in literal text are
    escaped, so nothing but a variable reference is ever live. The CLI prints one
    informational note listing the variables the script references at run time.

Fix

  • environment null value is host passthrough. A null mapping value
    (KEY:) now emits a bare -e KEY — passing KEY through from the host,
    identical to the list form - KEY — instead of the literal -e KEY=None.
  • Malformed braced references are rejected. A braced reference whose text
    after the name is not a valid operator (e.g. ${FOO!bar}) now raises a clear
    UnsupportedComposeError instead of silently dropping the trailing text.

Packaging

  • Public API: the generation-time interpolate function is removed;
    to_shell is exported in its place. to_shell(value) returns a
    runtime-expandable shell fragment, not a resolved value.

Why

The 0.1.7 model resolved ${VAR} against os.environ at generation time. For
compose2pod's actual use — generate a script now, run it later in CI — that was
the wrong moment: the variables are supposed to be unset at generation and set
at run time, so 0.1.7 baked them to empty and emitted a spurious "variable not
set" warning. Deferring to the runtime shell resolves them where they exist.

Downstream

  • Compose files: set ${VAR} values in the runtime environment of the
    generated script (e.g. your CI job), not in the environment that runs
    compose2pod. An unset bare ${VAR} now expands to empty at run time; write
    ${VAR:?message} where you want a missing variable to fail the run.
  • API consumers: compose2pod.interpolate is gone. Use
    compose2pod.to_shell(value), which emits a runtime-expandable shell fragment
    rather than resolving the value in-process.

Internals

  • architecture/supported-subset.md rewritten to describe run-time expansion,
    the ${VAR-}/$$/${VAR:?} semantics, env_file interpolation, the
    reference note, null-value passthrough, and malformed-reference rejection.
  • 123 tests at 100% line coverage (enforced); ruff select=ALL, ty, and
    eof-fixer clean. test_shell.py executes emitted fragments under real
    sh -euc to prove run-time expansion, the ${VAR:?} abort, and
    command-substitution inertness.