#!/usr/bin/env python3 """Run a command with one or more Docker-style env files. Values are parsed literally rather than sourced by a shell. Tokens containing `$`, `#`, spaces or shell metacharacters therefore remain unchanged. """ from __future__ import annotations import os import pathlib import sys def load_env(path: pathlib.Path) -> None: if not path.is_file(): raise SystemExit(f"secret environment file is missing: {path}") for raw in path.read_text(encoding="utf-8").splitlines(): line = raw.strip() if not line or line.startswith("#"): continue if line.startswith("export "): line = line[7:].lstrip() if "=" not in line: raise SystemExit(f"invalid environment line in {path}: {raw!r}") key, value = line.split("=", 1) key = key.strip() if not key or not key.replace("_", "A").isalnum() or key[0].isdigit(): raise SystemExit(f"invalid environment variable in {path}: {key!r}") value = value.strip() if len(value) >= 2 and value[0] == value[-1] and value[0] in "\"'": value = value[1:-1] os.environ[key] = value def main() -> None: if len(sys.argv) < 3: raise SystemExit("usage: run-with-env ENV_FILE [ENV_FILE ...] -- COMMAND [ARG ...]") try: separator = sys.argv.index("--") except ValueError as exc: raise SystemExit("missing -- before command") from exc env_files = [pathlib.Path(item) for item in sys.argv[1:separator]] command = sys.argv[separator + 1 :] if not env_files or not command: raise SystemExit("at least one env file and a command are required") for env_file in env_files: load_env(env_file) os.execvp(command[0], command) if __name__ == "__main__": main()