-
-
Notifications
You must be signed in to change notification settings - Fork 153
fix: Resolve file-scoped locals in stack configurations #1939
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
fc0d48e
fix file-scoped locals, add tests, add PRD and blog post
aknysh b733e9b
Address CodeRabbit review: verify output content in tests, use Debug …
aknysh 7f62be6
address comments
aknysh bab6408
address comments, add unit and integration tests, implement `atmos de…
aknysh e64061f
address comments, add tests
aknysh 56adaa2
implement `atmos describe locals <component> -s <stack>`, add tests
aknysh 6f34d31
update PRDs and docs
aknysh 63266c4
update PRDs and docs
aknysh fa24dfb
address comments, fix tests
aknysh 84fd259
address comments, fix tests
aknysh 5653580
address comments
aknysh 3352849
Merge branch 'main' into aknysh/fix-locals-1
aknysh 375448c
Merge branch 'main' into aknysh/fix-locals-1
aknysh c58dfed
Merge branch 'main' into aknysh/fix-locals-1
aknysh 40e3fd0
add component-level locals, add tests
aknysh a8311e5
update docs
aknysh a8780d8
update `atmos describe locals` commands and docs
aknysh bb7bfca
update docs and PRDs
aknysh a9103fa
update docs and PRDs
aknysh 847ae38
fix tests
aknysh 32e7841
address comments
aknysh dde1c8d
address comments
aknysh 0c5af47
address comments, add tests
aknysh 623a2bd
address comments, add tests
aknysh a12b267
address comments, add tests, update `atmos describe locals` command
aknysh 5dd6a00
address comments, add tests
aknysh 4d4db37
address comments, add tests
aknysh cd98be3
address comments, add tests
aknysh 03138e2
[autofix.ci] apply automated fixes
autofix-ci[bot] 723d6b6
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] befe171
address comments
aknysh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| package cmd | ||
|
|
||
| import ( | ||
| "fmt" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| "github.com/spf13/pflag" | ||
|
|
||
| errUtils "github.com/cloudposse/atmos/errors" | ||
| "github.com/cloudposse/atmos/internal/exec" | ||
| cfg "github.com/cloudposse/atmos/pkg/config" | ||
| "github.com/cloudposse/atmos/pkg/perf" | ||
| "github.com/cloudposse/atmos/pkg/schema" | ||
| ) | ||
|
|
||
| const stackFlagName = "stack" | ||
|
|
||
| // describeLocalsCmd describes locals for stacks. | ||
| var describeLocalsCmd = &cobra.Command{ | ||
| Use: "locals [component] -s <stack>", | ||
| Short: "Display locals from Atmos stack manifests", | ||
| Long: `This command displays the locals defined in Atmos stack manifests. | ||
|
|
||
| When called with --stack, it shows the locals defined in that stack manifest file. | ||
| When a component is also specified, it shows the merged locals that would be | ||
| available to that component (global + section-specific + component-level).`, | ||
| Example: ` # Show locals for a specific stack | ||
| atmos describe locals --stack deploy/dev | ||
|
|
||
| # Show locals for a specific stack (using logical stack name) | ||
| atmos describe locals -s prod-us-east-1 | ||
|
|
||
| # Show locals for a component in a stack | ||
| atmos describe locals vpc -s prod | ||
|
|
||
| # Output as JSON | ||
| atmos describe locals --stack dev --format json | ||
|
|
||
| # Query specific values | ||
| atmos describe locals -s deploy/dev --query '.["deploy/dev"].locals.namespace'`, | ||
| Args: cobra.MaximumNArgs(1), | ||
| RunE: getRunnableDescribeLocalsCmd(getRunnableDescribeLocalsCmdProps{ | ||
| checkAtmosConfig: checkAtmosConfig, | ||
| processCommandLineArgs: exec.ProcessCommandLineArgs, | ||
| initCliConfig: cfg.InitCliConfig, | ||
| validateStacks: exec.ValidateStacks, | ||
| newDescribeLocalsExecFactory: exec.NewDescribeLocalsExec, | ||
| }), | ||
| } | ||
|
|
||
| type getRunnableDescribeLocalsCmdProps struct { | ||
| checkAtmosConfig func(opts ...AtmosValidateOption) | ||
| processCommandLineArgs func( | ||
| componentType string, | ||
| cmd *cobra.Command, | ||
| args []string, | ||
| additionalArgsAndFlags []string, | ||
| ) (schema.ConfigAndStacksInfo, error) | ||
| initCliConfig func(configAndStacksInfo schema.ConfigAndStacksInfo, processStacks bool) (schema.AtmosConfiguration, error) | ||
| validateStacks func(atmosConfig *schema.AtmosConfiguration) error | ||
| newDescribeLocalsExecFactory func() exec.DescribeLocalsExec | ||
| } | ||
|
|
||
| func getRunnableDescribeLocalsCmd( | ||
| g getRunnableDescribeLocalsCmdProps, | ||
| ) func(cmd *cobra.Command, args []string) error { | ||
| return func(cmd *cobra.Command, args []string) error { | ||
| defer perf.Track(nil, "cmd.describeLocals")() | ||
|
|
||
| // Fail fast: check --stack before expensive init operations. | ||
| // Cobra has already parsed flags by the time RunE is called. | ||
| stackFlag, _ := cmd.Flags().GetString(stackFlagName) | ||
| if stackFlag == "" { | ||
| return errUtils.ErrStackRequired | ||
| } | ||
|
|
||
| // Check Atmos configuration. | ||
| g.checkAtmosConfig() | ||
|
|
||
| // Pass args to ensure config-selection flags (--base-path, --config, etc.) are parsed. | ||
| // The component positional arg is extracted separately below. | ||
| info, err := g.processCommandLineArgs("", cmd, args, nil) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| atmosConfig, err := g.initCliConfig(info, true) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| err = g.validateStacks(&atmosConfig) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| describeArgs := &exec.DescribeLocalsArgs{} | ||
|
|
||
| // Extract component from positional argument if provided. | ||
| if len(args) > 0 { | ||
| describeArgs.Component = args[0] | ||
| } | ||
|
|
||
| err = setCliArgsForDescribeLocalsCli(cmd.Flags(), describeArgs) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Create executor lazily to avoid init-time side effects. | ||
| executor := g.newDescribeLocalsExecFactory() | ||
| err = executor.Execute(&atmosConfig, describeArgs) | ||
| return err | ||
| } | ||
| } | ||
|
|
||
| func setCliArgsForDescribeLocalsCli(flags *pflag.FlagSet, args *exec.DescribeLocalsArgs) error { | ||
| var err error | ||
|
|
||
| if flags.Changed(stackFlagName) { | ||
| args.FilterByStack, err = flags.GetString(stackFlagName) | ||
| if err != nil { | ||
| return fmt.Errorf("%w: read --stack: %w", errUtils.ErrInvalidFlag, err) | ||
| } | ||
| } | ||
|
|
||
| if flags.Changed("format") { | ||
| args.Format, err = flags.GetString("format") | ||
| if err != nil { | ||
| return fmt.Errorf("%w: read --format: %w", errUtils.ErrInvalidFlag, err) | ||
| } | ||
| } | ||
|
|
||
| if flags.Changed("file") { | ||
| args.File, err = flags.GetString("file") | ||
| if err != nil { | ||
| return fmt.Errorf("%w: read --file: %w", errUtils.ErrInvalidFlag, err) | ||
| } | ||
| } | ||
|
|
||
| if flags.Changed("query") { | ||
| args.Query, err = flags.GetString("query") | ||
| if err != nil { | ||
| return fmt.Errorf("%w: read --query: %w", errUtils.ErrInvalidFlag, err) | ||
| } | ||
| } | ||
aknysh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Set default format. | ||
| if args.Format == "" { | ||
| args.Format = "yaml" | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func init() { | ||
| // Use Flags() instead of PersistentFlags() since this command has no subcommands. | ||
| describeLocalsCmd.Flags().StringP(stackFlagName, "s", "", | ||
| "Stack to display locals for (required)\n"+ | ||
| "Supports top-level stack manifest names (including subfolder paths) and logical stack names (derived from context vars)\n"+ | ||
| "Parse errors in the matched stack are reported; errors in other stacks are skipped during the search", | ||
| ) | ||
| AddStackCompletion(describeLocalsCmd) | ||
|
|
||
| describeLocalsCmd.Flags().StringP("format", "f", "yaml", "Specify the output format (`yaml` is default)") | ||
|
|
||
| describeLocalsCmd.Flags().String("file", "", "Write the result to file") | ||
|
|
||
| describeLocalsCmd.Flags().StringP("query", "q", "", "Query the result using `yq` expression") | ||
|
|
||
| describeCmd.AddCommand(describeLocalsCmd) | ||
| } | ||
aknysh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.