Repository navigation
feat: support environment name abbreviations for --env flag - #11
Conversation
Add normalizeEnvironment() to map short-forms and alternate spellings to the canonical authEnvironment constant before resolving IdP config: prod/production → prod staging/stage/stg → staging development/develop/dev → development - environment.go: add envAliases map and normalizeEnvironment(); update resolveEnvironment error message to list all accepted forms - auth.go: call normalizeEnvironment() in runAuthLogin; update --env flag Usage text to show alias groups - auth_test.go: add TestNormalizeEnvironment, TestResolveEnvironmentAliases, and TestResolveEnvironmentUnknown covering every alias + unknown-input path - README.md: add example lines showing alias usage Signed-off-by: Andres Tobon <andrest2455@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
67a4d12 to
c61eb14
Compare
|
Thanks for this — the alias mapping is correctly implemented and well-tested, but I'd like to push back on the overall approach before we merge. Concern: multiple string values mapping to one canonical valueHaving Alternative: discrete boolean flags per environmentConsider replacing the single
Backward compatibilityThis would be a breaking change for anyone already scripting RecommendationI'd suggest holding off on merging the alias table as-is. Given the scope of a discrete-flag redesign (plus deprecation), it's worth a quick design discussion / follow-up issue rather than iterating further on this PR in place. |
|
Thanks for the thorough review, @emsearcy — a couple of clarifications on the points raised: On the breaking change: the concern in your comment is about your own proposed alternative (removing On discrete flags: the alternative you describe would mean passing On did-you-mean and shell completion: both are fair observations. On maintenance burden: the alias map is 4 entries. The error message is one format string. The table-driven tests cover every alias in ~20 lines. I do not think this rises to the level of a meaningful ongoing cost. Happy to discuss further, but I do not think there is a correctness or compatibility issue that warrants holding the PR. If the design preference for discrete flags is strong, I would suggest we track that as a separate issue rather than blocking this additive change. |
Rename the canonical prod environment name to production (matching staging and development already being full words). --env's usage text and invalid-environment errors now mention only the three canonical names instead of enumerating every accepted alias. Add `lfx auth environments`, which lists each canonical name with its aliases and default API audience, so that detail stays discoverable without cluttering --env's own usage text. Every place that reads a previously persisted credstore.DeviceState.Environment (loadDeviceStateForBackend, resolveAccessToken, and the `auth status` display) now runs it through normalizeEnvironment, so state.json files written before the prod -> production rename keep resolving correctly (via the existing "prod" alias) without requiring a fresh `lfx auth login`. Also drop backticks from flag Usage strings (--backend, --env, --audience, --hostname): urfave/cli's help renderer treats the first backtick-quoted substring in a flag's Usage as its value placeholder (replacing the normal "string" type hint), so any backtick-quoted command name there hijacked that column instead of rendering as intended. Single quotes read the same without triggering it, in both the terminal help and generated Markdown docs. Also run go get -u ./... && go mod tidy, pinning golang.org/x/oauth2, golang.org/x/sys, and golang.org/x/term just below their latest patches (which now require go1.26) to keep go.mod's go directive at 1.25.14, matching this repo's toolchain policy of staying one minor version behind MegaLinter's bundled Go (1.26.x). Assisted-by: github-copilot:claude-sonnet-5 Signed-off-by: Eric Searcy <eric@linuxfoundation.org>
2a56b5e to
0229040
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Changing production’s canonical persisted value breaks rollback compatibility and contradicts the documented alias contract.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (1)
Resolved since last review (1)
dismissing so it's clear this is still waiting on a review
|
@andrest50 I'm starting review 1 of this pull request now (started 2026-09-28 16:09 UTC). This usually takes a few minutes — I'll update this comment with the summary when I'm done. @andrest50 thanks for the alias work — and thanks @emsearcy for the follow-up that renamed the canonical production value, added
Prior round: Copilot's upgrade-path break (discussion) is resolved in 0229040. Copilot's still-open request for a command-level ✅ Approved with minor comments |
dealako
left a comment
There was a problem hiding this comment.
@andrest50 alias mapping, the production rename, and the persisted-prod upgrade path look solid. One test-gap minor, a couple of nits, and a downgrade-compat question — none of them block merge.
- 🔴 Blocking: 0
- 🟡 Minor: 1 —
lfx auth loginnever exercises aliases end-to-end - ⚪ Nit: 2 — README leads with
dev;environmentsUsage still uses backticks - ❔ Question: 1 — new logins persist
production, which v1.0.x rejects
Agree with Copilot on the still-open auth environments command test (#11 (comment)); not repeating it here. Copilot's original prod→production upgrade break is fixed in 0229040.
✅ Approved with minor comments
| Usage: "Target environment: prod, staging, or development", | ||
| Value: string(envProd), | ||
| Usage: "Target environment; see 'lfx auth environments' for accepted values", | ||
| Value: string(envProduction), |
There was a problem hiding this comment.
[question] New logins persist "production", which released v1.0.x binaries reject
Issue: The renamed constant is also the value saved to DeviceState.Environment. A default lfx auth login (and --env=prod, after normalize) now writes "environment": "production" to state.json. Read-side normalize fixes the upgrade path; it does not help an older binary reading the new file.
Proof: --env defaults to string(envProduction) here. runAuthLogin normalizes to envProduction, then loginWithToken / loginWithDeviceCode persist Environment: string(env) (auth.go:179, auth.go:282). v1.0.1 (envProd = "prod", Latest) keys authDomains by "prod" and calls resolveEnvironment(authEnvironment(state.Environment)) with no alias step, so it errors invalid environment: "production".
Why it matters: Downgrading, or running a v1.0.x binary alongside this build against the same state dir, breaks lfx auth token / lfx api until the user logs in again with the older binary. Credentials stay in the keyring; only state.json becomes unreadable to v1.0.x.
Fix: If downgrade compatibility matters, keep writing the legacy production value ("prod") while still displaying production — normalizeEnvironment already reads both. If it does not, call that out in the release notes (going back to v1.0.x requires lfx auth login again).
| } | ||
|
|
||
| env := authEnvironment(cmd.String(envFlagName)) | ||
| env := normalizeEnvironment(cmd.String(envFlagName)) |
There was a problem hiding this comment.
[minor] No test exercises alias handling through lfx auth login
Issue: This is the only place aliases are applied to user input. The new tests cover normalizeEnvironment / resolveEnvironment in isolation. Dropping this call, or passing the raw flag into defaultAudienceForEnvironment, would break lfx auth login --env=dev while every test still passed.
Proof: No *_test.go references runAuthLogin or loginWithToken. The --with-token path does not hit the network: it reads stdin and saves through credStoreFromCommand. --insecure-storage plus t.Setenv("XDG_STATE_HOME", t.TempDir()) is already a tested seam elsewhere (api_test.go swaps stdin).
Why it matters: Accepting aliases in lfx auth login is the user-facing feature. Helper tests can stay green while the command itself is unwired.
Fix: Table-test a root command (Flags: CredentialStoreFlags, Commands: NewAuthCommand()) with --insecure-storage auth login --with-token --env=<alias> for prod / stg / dev, piping a dummy refresh token on stdin. Assert the saved DeviceState has the canonical Environment, matching IDPDomain, and that environment's default audience.
|
|
||
| # Log in against a non-production environment (aliases accepted). | ||
| lfx auth login --env staging # also: stage, stg | ||
| lfx auth login --env dev # also: develop, development |
There was a problem hiding this comment.
[nit] Show canonical --env names in the README and point to lfx auth environments
Issue: The staging example leads with the canonical name; the development example leads with the alias dev and lists development under "also". The README also never mentions the new lfx auth environments command, even though --backend already points at lfx auth backends.
Proof: Canonical names are production / staging / development (environment.go:21-25). After lfx auth login --env dev, auth status prints Environment: development because login persists the normalized value. AGENTS.md asks to update the README for user-facing changes.
Why it matters: The README teaches an alias as the primary spelling, which fights this PR's move to full-word canonical names and what auth status / auth environments print.
Fix: Lead with the canonical names and point at the new command, e.g.
# Aliases are accepted; run `lfx auth environments` for the full list.
lfx auth login --env staging # aliases: stage, stg
lfx auth login --env development # aliases: dev, develop
| func newAuthEnvironmentsCommand() *cli.Command { | ||
| return &cli.Command{ | ||
| Name: "environments", | ||
| Usage: "List --env values accepted by `lfx auth login`, including aliases and default audiences", |
There was a problem hiding this comment.
[nit] Use single quotes in the environments command Usage, like the rest of the help text
Issue: This PR switched flag Usage that names a command to single quotes ('lfx auth backends', 'lfx auth environments'). This new command Usage still wraps lfx auth login in backticks — it is now the only Usage string in internal/commands that still has them.
Proof: Flag Usage runs through urfave/cli's unquoteUsage (the original reason backticks were removed). Command Usage is printed as-is, so these backticks show up literally next to sibling commands that use no quoting, and next to --env's single-quoted 'lfx auth environments'.
Why it matters: Help output mixes quoting styles for the same kind of command reference. No behavioral break; consistency only.
Fix: Usage: "List --env values accepted by 'lfx auth login', including aliases and default audiences"


Summary
Adds support for abbreviated and alternate spellings of the
--envflag value when runninglfx auth login, so users can type shorter, more intuitive names without needing to remember the exact canonical string.Accepted aliases
prodproductionstagingstage,stgdevelopmentdevelop,devChanges
internal/commands/environment.go— addsenvAliasesmap andnormalizeEnvironment()function; updates error message to list all accepted formsinternal/commands/auth.go— callsnormalizeEnvironment()before resolving the environment; updates--envflag usage textinternal/commands/auth_test.go— addsTestNormalizeEnvironment,TestResolveEnvironmentAliases, andTestResolveEnvironmentUnknownREADME.md— adds example lines showing alias usageTesting
All existing tests pass; 3 new test functions covering every alias + the unknown-input error path.
Made with Cursor