feat: add -prefix flag for variable filtering#73
Open
nicholasklem wants to merge 3 commits into
Open
Conversation
Add --prefix flag to substitute only variables matching a given prefix.
Variables not matching the prefix are left as literal text in the output.
This enables use cases like:
envsubst --prefix ARGOCD_ENV_ < template.yaml
Which will only substitute $ARGOCD_ENV_* variables, leaving other
variable references (like $OTHER_VAR) intact.
Key behavior:
- Variables matching the prefix are processed normally
- Unset variables matching prefix use defaults (${VAR:-default})
- Variables not matching prefix are preserved as literal text
- Level 1 variable nesting in defaults works (${VAR:-$VAR2})
Known limitation:
- Deeply nested defaults like ${VAR:-${VAR2:-default}} have issues
with extra closing braces (pre-existing parser limitation)
Comprehensive tests added for:
- VarFilter prefix matching
- All substitution operators (:- - := :+)
- Mixed allowed/disallowed variables
- Variable defaults with different prefixes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4 tasks
Upstream a8m/envsubst treats $$ as a shell-style escape that collapses to $ (since 2018, commit e89c09c "parse: add support for escaping expressions"). That silently mangles inputs containing literal $$ — most notably the KEDA Helm chart, which embeds Kubernetes' own env-var expansion docs in CRD schema descriptions: "Double $$ are reduced to a single $". Result: ArgoCD shows perpetual $$ → $ drift on KEDA resources, since rendered manifests have $ but live cluster has $$ (or vice versa, depending on which side of the apply you read). This fork is scoped to ArgoCD CMP rendering with --prefix filtering, not generic shell templating. There is no use case here for shell-style $$ escapes; the only effect is unintended mangling of literal text. Drop the l.ignore() that throws away the first $ in the lexer's $$ branch, so $$ emits as literal text instead of collapsing. Also reframes the README: this fork is now documented as an envsubst variant tuned for ArgoCD CMP rendering, with two deliberate deviations from upstream (the existing --prefix flag and this $$ change). It is not a generic shell-templating tool; users who want shell-style escapes should use upstream a8m/envsubst. Tests: 4 existing escape tests in parse_test.go + 2 in lex_test.go updated to assert new semantics. Added 4 KEDA-flavored regression cases covering CRD descriptions, kubelet $$(VAR_NAME) escapes, and $$ mixed with prefix-allowed substitutions. Verified end-to-end against actual kustomize build --enable-helm output of keda/environments/production: 18 $$ occurrences in rendered chart, 18 preserved after envsubst -prefix ARGOCD_ENV_, IAM annotation substitution still works correctly.
…on tests Address self-review feedback on PR #1: - README "About this fork": clarify which shell operators are preserved vs dropped. List all the kept operators explicitly so readers don't have to guess. Only the $$ escape is removed. - README new section "Combining literal $$ with a substitution": document the four forms users are likely to try, with verified behavior. The only working forms are $$$VAR (triple-dollar) and $$ ${VAR} (space- separated). $$VAR and $${VAR} both fail to substitute because the $$ consumes both dollars, leaving the variable name as plain text. Initial draft of this section claimed $${VAR} would substitute — that was wrong, verified empirically before commit. - Tests: pin the four documented forms as regression cases in parseTests, so README and behavior can't drift apart silently. Also add two cases for $$ inside substitution operands (${VAR:-pre$$post}) — that path is unchanged by this fork but worth pinning so a future refactor of lexSubstitution doesn't regress it. All 6 new test cases pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add
-prefixflag to substitute only variables matching a given prefix, leaving other variable references as literal text.This is a simpler alternative to #72 (GNU SHELL-FORMAT compatibility), which I've converted to draft. The
-prefixapproach is easier to use in practice.Use Case
When templating files that contain variable references you want to preserve, you can use a prefix convention to distinguish which variables should be substituted:
Input:
Output:
Behavior
:-,-,:=,:+)${MY_X:-$OTHER}→ substitutesMY_X, preserves$OTHERif used as defaultTest Plan
🤖 Generated with Claude Code