Skip to content

feat: interpolate variables at script-run time#20

Merged
lesnik512 merged 6 commits into
mainfrom
feat/runtime-variable-interpolation
Jul 9, 2026
Merged

feat: interpolate variables at script-run time#20
lesnik512 merged 6 commits into
mainfrom
feat/runtime-variable-interpolation

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Summary

${VAR} interpolation was resolved at script-generation time (against compose2pod's own os.environ, added in #18). For the tool's real use case — generate a script now, run it later in CI where the secrets/tokens actually exist — that baked any variable unset at generation time to an empty string. This branch defers interpolation to script-run time: compose-derived values are emitted as double-quoted POSIX-shell fragments whose variable references stay live, so the generated script's own shell expands them against the environment present when it runs.

Design and rationale: planning/changes/2026-07-08.07-runtime-variable-interpolation.md.

What changed

  • New compose2pod/shell.py: to_shell() re-encodes a compose string into a shell fragment ($$$, bare $VAR${VAR-} so an unset var expands to empty and survives set -eu, operator forms pass through, command substitution and literal specials escaped); variable_names() extracts referenced names.
  • emit classifies each token as literal (shlex.quote) or expandable (_Expandto_shell). environment, image, command, volumes, tmpfs, env_file, and healthcheck test interpolate at run time; tool/CLI values (--project-dir, --image, pod name, --command) stay literal.
  • CLI drops the generation-time resolution and prints one informational stderr note listing the variables the script references at run time (emit.referenced_variables, sourced from the same tokens to_shell renders).
  • Removed compose2pod/interpolate.py and its generation-time interpolate export; to_shell replaces it in the public API.
  • architecture/supported-subset.md and README.md updated.

Consequences (deliberate)

  • No more generation-time "variable not set" warning (it was a false positive in this flow); an unset bare ${VAR} expands to empty at run time.
  • ${VAR:?msg} now fails the script at run time when unset/empty (POSIX sh enforces it, aborting before podman runs) instead of failing generation.
  • The emitted script is no longer self-contained — its effect depends on the runtime environment.

Testing

just test-ci passes at 100% line coverage (119 tests); just lint-ci clean. test_shell.py executes emitted fragments under real sh -euc to prove runtime expansion, the ${VAR:?} abort, and command-substitution inertness.

🤖 Generated with Claude Code

@lesnik512 lesnik512 merged commit 66c0c0b into main Jul 9, 2026
6 checks passed
@lesnik512 lesnik512 deleted the feat/runtime-variable-interpolation branch July 9, 2026 04:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant