-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Stacks: output #3796
Stacks: output #3796
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
cli/commands/stack/command.go (2)
26-52
: Add format validation and consider default format.The flag configuration looks good overall, but a few suggestions to make it more robust:
- Add validation for format values
- Consider setting a default format
- Document the precedence when multiple format flags are used
Here's a suggested improvement:
func NewFlags(opts *options.TerragruntOptions) cli.Flags { + // Set default format + if opts.StackOutputFormat == "" { + opts.StackOutputFormat = jsonOutputFormat + } return cli.Flags{ &cli.GenericFlag[string]{ Name: OutputFormatFlagName, EnvVar: OutputFormatEnvName, Destination: &opts.StackOutputFormat, Usage: "Stack output format. Valid values are: json, raw", + Action: func(ctx *cli.Context, value string) error { + if value != jsonOutputFormat && value != rawOutputFormat { + return fmt.Errorf("invalid format %q, valid values are: json, raw", value) + } + return nil + }, },
77-87
: Enhance output command documentation.The command implementation looks good, but the usage description could be more helpful. Based on the PR feedback, users would benefit from examples showing how to use the raw format for shell script integration.
Here's a suggested improvement:
&cli.Command{ Name: output, - Usage: "Run fetch stack output", + Usage: "Fetch stack output with optional formatting", + Description: `Examples: + # Get all outputs in JSON format + terragrunt stack output --format=json + + # Get specific output in raw format (useful for shell scripts) + terragrunt stack output --format=raw app1.url + + # Example shell script usage + curl -s "$(terragrunt stack output --format=raw services.service['service-1'].url)"`, Action: func(ctx *cli.Context) error {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
cli/commands/stack/command.go
(2 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
cli/commands/stack/command.go
14-14: ST1003: const JsonFormatFlagName should be JSONFormatFlagName
(stylecheck)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: unessential
- GitHub Check: build-and-test
- GitHub Check: Pull Request has non-contributor approval
cli/commands/stack/command.go
Outdated
JsonFormatFlagName = "json" | ||
RawFormatFlagName = "json" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix constant declarations for format flags.
There are a couple of issues with the flag name constants:
RawFormatFlagName
is incorrectly set to "json" - it should be "raw"JsonFormatFlagName
should beJSONFormatFlagName
to follow Go naming conventions
Here's how to fix these:
- JsonFormatFlagName = "json"
- RawFormatFlagName = "json"
+ JSONFormatFlagName = "json"
+ RawFormatFlagName = "raw"
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
JsonFormatFlagName = "json" | |
RawFormatFlagName = "json" | |
JSONFormatFlagName = "json" | |
RawFormatFlagName = "raw" |
🧰 Tools
🪛 golangci-lint (1.62.2)
14-14: ST1003: const JsonFormatFlagName should be JSONFormatFlagName
(stylecheck)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
cli/commands/stack/command.go (1)
14-14
: 🛠️ Refactor suggestionFollow Go naming conventions for JSON constant.
The constant name should be
JSONFormatFlagName
to follow Go's naming convention for acronyms.- JSONFormatFlagName = "json" + JSONFormatFlagName = "json"
🧹 Nitpick comments (1)
cli/commands/stack/command.go (1)
77-87
: Enhance the usage description for clarity.The current usage description "Run fetch stack output" could be more descriptive to help users understand what the command does.
- Usage: "Run fetch stack output", + Usage: "Fetch and display stack outputs with optional filtering by output name",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cli/commands/stack/command.go
(2 hunks)docs/_docs/04_reference/02-cli-options.md
(1 hunks)test/integration_stacks_test.go
(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/_docs/04_reference/02-cli-options.md
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build-and-test
- GitHub Check: Pull Request has non-contributor approval
🔇 Additional comments (2)
cli/commands/stack/command.go (1)
26-51
: Nice implementation of the output format flags!The flags are well-structured with clear usage descriptions and proper environment variable integration.
test/integration_stacks_test.go (1)
162-311
: Excellent test coverage! 👏The test suite is comprehensive and well-structured, covering:
- Different output formats (raw, JSON)
- Index-based filtering
- Both flag and format parameter approaches
- Proper validation of output content
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (6)
cli/commands/stack/action.go (1)
51-85
: Enhance error handling and switch statement robustnessA few suggestions to make the code more maintainable:
- Add more context to errors to help with debugging
- Handle invalid output formats explicitly
func RunOutput(ctx context.Context, opts *options.TerragruntOptions, index string) error { stacksEnabled := opts.Experiments[experiment.Stacks] if !stacksEnabled.Enabled { - return errors.New("stacks experiment is not enabled use --experiment stacks to enable it") + return errors.New("stacks experiment is not enabled - use --experiment stacks to enable it") } // collect outputs outputs, err := generateOutput(ctx, opts) if err != nil { - return errors.New(err) + return errors.WithPrefixf(err, "error generating stack output") } // write outputs writer := opts.Writer switch opts.StackOutputFormat { - default: + case "": if err := PrintOutputs(writer, outputs, index); err != nil { - return errors.New(err) + return errors.WithPrefixf(err, "error printing outputs") } case rawOutputFormat: if err := PrintRawOutputs(opts, writer, outputs, index); err != nil { - return errors.New(err) + return errors.WithPrefixf(err, "error printing raw outputs") } case jsonOutputFormat: if err := PrintJSONOutput(writer, outputs, index); err != nil { - return errors.New(err) + return errors.WithPrefixf(err, "error printing JSON output") } + default: + return errors.New("invalid output format: " + opts.StackOutputFormat) } return nil }cli/commands/stack/output.go (3)
23-46
: Improve error handling in generateOutputThe error handling could be more descriptive to help with debugging.
func generateOutput(ctx context.Context, opts *options.TerragruntOptions) (map[string]map[string]cty.Value, error) { opts.TerragruntStackConfigPath = filepath.Join(opts.WorkingDir, defaultStackFile) opts.Logger.Debugf("Generating output from %s", opts.TerragruntStackConfigPath) stackFile, err := config.ReadStackConfigFile(ctx, opts) if err != nil { - return nil, errors.New(err) + return nil, errors.WithPrefixf(err, "failed to read stack config file %s", opts.TerragruntStackConfigPath) } unitOutputs := make(map[string]map[string]cty.Value) // process each unit and get outputs for _, unit := range stackFile.Units { opts.Logger.Debugf("Processing unit %s", unit.Name) output, err := unit.ReadOutputs(ctx, opts) if err != nil { - return nil, errors.New(err) + return nil, errors.WithPrefixf(err, "failed to read outputs for unit %s", unit.Name) } unitOutputs[unit.Name] = output } return unitOutputs, nil }
47-79
: Enhance error handling in PrintRawOutputsThe function could handle errors more gracefully and provide better error messages.
func PrintRawOutputs(opts *options.TerragruntOptions, writer io.Writer, outputs map[string]map[string]cty.Value, outputIndex string) error { if len(outputIndex) == 0 { - return errors.New("output index is required in raw mode") + return errors.New("output index is required when using raw format (--format raw)") } filteredOutputs := FilterOutputs(outputs, outputIndex) if filteredOutputs == nil { - return nil + return errors.New("no outputs found for index: " + outputIndex) } if len(filteredOutputs) > 1 { - return errors.New("multiple outputs found, please specify only one index") + return errors.New("multiple outputs found for index '" + outputIndex + "', please specify a unique index") } for key, value := range filteredOutputs { valueStr, err := getValueString(value) if err != nil { opts.Logger.Warnf("Error fetching output for '%s': %v", key, err) continue } line := fmt.Sprintf("%s\n", valueStr) if _, err := writer.Write([]byte(line)); err != nil { - return errors.New(err) + return errors.WithPrefixf(err, "failed to write output for key %s", key) } } return nil }
137-173
: Simplify FilterOutputs functionThe function could be simplified and made more readable.
func FilterOutputs(outputs map[string]map[string]cty.Value, outputIndex string) map[string]cty.Value { if outputIndex == "" { - flattened := make(map[string]cty.Value) - for unit, values := range outputs { - flattened[unit] = cty.ObjectVal(values) - } - - return flattened + return flattenOutputs(outputs) } keys := strings.Split(outputIndex, ".") - currentMap := make(map[string]cty.Value) + result := make(map[string]cty.Value) for unit, values := range outputs { if !strings.HasPrefix(outputIndex, unit) { continue } value := cty.ObjectVal(values) - for _, key := range keys[1:] { - if value.Type().IsObjectType() { - mapVal := value.AsValueMap() - if v, exists := mapVal[key]; exists { - value = v - } else { - return nil - } - } else { - return nil - } + value, ok := traverseValue(value, keys[1:]) + if !ok { + return nil } - currentMap[outputIndex] = value + result[outputIndex] = value } - return currentMap + return result } + +func flattenOutputs(outputs map[string]map[string]cty.Value) map[string]cty.Value { + flattened := make(map[string]cty.Value) + for unit, values := range outputs { + flattened[unit] = cty.ObjectVal(values) + } + return flattened +} + +func traverseValue(value cty.Value, keys []string) (cty.Value, bool) { + for _, key := range keys { + if !value.Type().IsObjectType() { + return cty.NilVal, false + } + mapVal := value.AsValueMap() + var exists bool + value, exists = mapVal[key] + if !exists { + return cty.NilVal, false + } + } + return value, true +}test/integration_stacks_test.go (2)
246-257
: Consider adding more specific error assertionsThe test could be more specific about the expected error message.
func TestStackOutputsRawError(t *testing.T) { t.Parallel() helpers.CleanupTerraformFolder(t, testFixtureStacksOutputs) tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStacksOutputs) rootPath := util.JoinPath(tmpEnvPath, testFixtureStacksOutputs) helpers.RunTerragrunt(t, "terragrunt stack run apply --experiment stacks --terragrunt-non-interactive --terragrunt-working-dir "+rootPath) - _, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt stack output --format raw --experiment stacks --terragrunt-non-interactive --terragrunt-working-dir "+rootPath) - require.Error(t, err) + stdout, stderr, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt stack output --format raw --experiment stacks --terragrunt-non-interactive --terragrunt-working-dir "+rootPath) + require.Error(t, err) + assert.Contains(t, stderr, "output index is required when using raw format")
276-291
: Consider reducing test duplicationTestStackOutputsRawFlag and TestStackOutputsJsonFlag share similar setup code. Consider extracting common setup into a helper function.
+func setupStackOutputTest(t *testing.T) string { + t.Helper() + helpers.CleanupTerraformFolder(t, testFixtureStacksOutputs) + tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStacksOutputs) + rootPath := util.JoinPath(tmpEnvPath, testFixtureStacksOutputs) + helpers.RunTerragrunt(t, "terragrunt stack run apply --experiment stacks --terragrunt-non-interactive --terragrunt-working-dir "+rootPath) + return rootPath +} + func TestStackOutputsRawFlag(t *testing.T) { t.Parallel() - helpers.CleanupTerraformFolder(t, testFixtureStacksOutputs) - tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStacksOutputs) - rootPath := util.JoinPath(tmpEnvPath, testFixtureStacksOutputs) - - helpers.RunTerragrunt(t, "terragrunt stack run apply --experiment stacks --terragrunt-non-interactive --terragrunt-working-dir "+rootPath) + rootPath := setupStackOutputTest(t) stdout, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt stack output -raw filtered_app2.data --experiment stacks --terragrunt-non-interactive --terragrunt-working-dir "+rootPath) require.NoError(t, err) assert.Contains(t, stdout, "app2") assert.NotContains(t, stdout, "project2_app1 = {") assert.NotContains(t, stdout, "project2_app2 = {") } func TestStackOutputsJsonFlag(t *testing.T) { t.Parallel() - helpers.CleanupTerraformFolder(t, testFixtureStacksOutputs) - tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStacksOutputs) - rootPath := util.JoinPath(tmpEnvPath, testFixtureStacksOutputs) - - helpers.RunTerragrunt(t, "terragrunt stack run apply --experiment stacks --terragrunt-non-interactive --terragrunt-working-dir "+rootPath) + rootPath := setupStackOutputTest(t)Also applies to: 293-310
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cli/commands/stack/action.go
(1 hunks)cli/commands/stack/output.go
(1 hunks)test/integration_stacks_test.go
(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Pull Request has non-contributor approval
- GitHub Check: Pull Request has non-contributor approval
🔇 Additional comments (1)
test/integration_stacks_test.go (1)
162-183
: LGTM! Comprehensive test coverage.The test cases thoroughly validate the output functionality with different formats and scenarios.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (6)
cli/commands/stack/output.go (5)
22-45
: Consider enhancing error messages for better debugging.The error handling is good, but the messages could be more descriptive to help users troubleshoot issues. Consider wrapping the errors with additional context.
if err != nil { - return nil, errors.New(err) + return nil, errors.WithPrefixf(err, "Failed to read stack config file at %s", opts.TerragruntStackConfigPath) } if err != nil { - return nil, errors.New(err) + return nil, errors.WithPrefixf(err, "Failed to read outputs for unit %s", unit.Name) }
79-85
: Add validation for edge cases in value conversion.Consider adding validation for nil values and better error handling for complex types that might fail conversion.
func getValueString(value cty.Value) (string, error) { + if value.IsNull() { + return "", fmt.Errorf("cannot convert nil value to string") + } if value.Type() == cty.String { return value.AsString(), nil } - return config.CtyValueAsString(value) + str, err := config.CtyValueAsString(value) + if err != nil { + return "", fmt.Errorf("failed to convert %s to string: %w", value.Type().FriendlyName(), err) + } + return str, nil }
87-107
: Consider optimizing for large outputs and improving error handling.The function works well but could be more robust with better error handling and memory optimization.
func PrintOutputs(writer io.Writer, outputs map[string]map[string]cty.Value, outputIndex string) error { filteredOutputs := FilterOutputs(outputs, outputIndex) if filteredOutputs == nil { return nil } f := hclwrite.NewEmptyFile() rootBody := f.Body() + // Write outputs in chunks to optimize memory usage + const chunkSize = 1000 + chunk := make([]byte, 0, chunkSize) for key, value := range filteredOutputs { tokens := hclwrite.TokensForValue(value) + if tokens == nil { + return fmt.Errorf("failed to convert value for key %s to HCL tokens", key) + } rootBody.SetAttributeRaw(key, tokens) + + // Write in chunks if the buffer gets too large + if len(chunk) >= chunkSize { + if _, err := writer.Write(chunk); err != nil { + return errors.New(err) + } + chunk = chunk[:0] + } } - if _, err := writer.Write(f.Bytes()); err != nil { + // Write any remaining data + if _, err := writer.Write(chunk); err != nil { return errors.New(err) } return nil }
109-133
: Add configurable JSON formatting options.Consider adding options to control JSON formatting (e.g., indentation) and optimize for large outputs.
-func PrintJSONOutput(writer io.Writer, outputs map[string]map[string]cty.Value, outputIndex string) error { +func PrintJSONOutput(writer io.Writer, outputs map[string]map[string]cty.Value, outputIndex string, opts ...JSONOutputOption) error { + config := defaultJSONOutputConfig() + for _, opt := range opts { + opt(config) + } + filteredOutputs := FilterOutputs(outputs, outputIndex) if filteredOutputs == nil { return nil } topVal := cty.ObjectVal(filteredOutputs) rawJSON, err := ctyjson.Marshal(topVal, topVal.Type()) if err != nil { return errors.New(err) } - var pretty bytes.Buffer - if err := json.Indent(&pretty, rawJSON, "", " "); err != nil { - return errors.New(err) + if config.PrettyPrint { + var pretty bytes.Buffer + if err := json.Indent(&pretty, rawJSON, config.Prefix, config.Indent); err != nil { + return errors.New(err) + } + rawJSON = pretty.Bytes() } - if _, err := writer.Write(pretty.Bytes()); err != nil { + if _, err := writer.Write(rawJSON); err != nil { return errors.New(err) } return nil }
135-171
: Enhance output filtering capabilities.Consider adding support for array indexing and better handling of invalid paths.
func FilterOutputs(outputs map[string]map[string]cty.Value, outputIndex string) map[string]cty.Value { if outputIndex == "" { flattened := make(map[string]cty.Value) for unit, values := range outputs { flattened[unit] = cty.ObjectVal(values) } return flattened } keys := strings.Split(outputIndex, ".") + // Support array indexing with regex + arrayIndexRegex := regexp.MustCompile(`^(.+)\[(\d+)\]$`) currentMap := make(map[string]cty.Value) for unit, values := range outputs { if !strings.HasPrefix(outputIndex, unit) { continue } value := cty.ObjectVal(values) for _, key := range keys[1:] { + // Handle array indexing + if matches := arrayIndexRegex.FindStringSubmatch(key); matches != nil { + key = matches[1] + idx, _ := strconv.Atoi(matches[2]) + if value.Type().IsListType() { + if idx >= 0 && idx < value.LengthInt() { + value = value.Index(cty.NumberIntVal(int64(idx))) + continue + } + return nil + } + } + if value.Type().IsObjectType() { mapVal := value.AsValueMap() if v, exists := mapVal[key]; exists { value = v } else { + // Provide more context about the invalid path + log.Printf("Invalid path: key '%s' not found in object. Available keys: %v", + key, maps.Keys(mapVal)) return nil } } else { + log.Printf("Invalid path: expected object type but got %s", + value.Type().FriendlyName()) return nil } } currentMap[outputIndex] = value } return currentMap }docs/_docs/04_reference/02-cli-options.md (1)
823-957
: Enhance documentation with more examples and format comparisons.The documentation is good but could be more helpful with:
- Examples of array indexing for complex outputs
- A comparison table showing format differences
- More real-world use cases
Add these sections to the documentation:
+#### Array Indexing Examples + +Accessing elements in output arrays: +```bash +# Get the first URL from a list +$ terragrunt stack output --format=raw app1.urls[0] +https://example.com + +# Get a specific port from a list of services +$ terragrunt stack output --format=raw services.ports[2] +8080 +``` + +#### Format Comparison + +| Use Case | Default | JSON | Raw | +|----------|---------|------|-----| +| Shell scripts | ❌ | ❌ | ✅ | +| Parsing | ❌ | ✅ | ❌ | +| Human readable | ✅ | ✅ | ❌ | +| Complex types | ✅ | ✅ | ❌ | + +#### Real-world Examples + +```bash +# Deploy to the latest endpoint +$ kubectl apply -f "$(terragrunt stack output --format=raw k8s.manifest_path)" + +# Connect to the database +$ psql "$(terragrunt stack output --format=raw db.connection_string)" +```
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
cli/commands/stack/output.go
(1 hunks)docs/_docs/04_reference/02-cli-options.md
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Pull Request has non-contributor approval
- GitHub Check: build-and-test
- GitHub Check: Pull Request has non-contributor approval
func PrintRawOutputs(opts *options.TerragruntOptions, writer io.Writer, outputs map[string]map[string]cty.Value, outputIndex string) error { | ||
if len(outputIndex) == 0 { | ||
// output index is required in raw mode | ||
return errors.New("output index is required in raw mode") | ||
} | ||
|
||
filteredOutputs := FilterOutputs(outputs, outputIndex) | ||
|
||
if filteredOutputs == nil { | ||
return nil | ||
} | ||
|
||
if len(filteredOutputs) > 1 { | ||
// return error since in raw mode we want to print only one output | ||
return errors.New("multiple outputs found, please specify only one index") | ||
} | ||
|
||
for key, value := range filteredOutputs { | ||
valueStr, err := getValueString(value) | ||
if err != nil { | ||
opts.Logger.Warnf("Error fetching output for '%s': %v", key, err) | ||
continue | ||
} | ||
|
||
line := valueStr + "\n" | ||
if _, err := writer.Write([]byte(line)); err != nil { | ||
return errors.New(err) | ||
} | ||
} | ||
|
||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Modify raw output format to align with user feedback.
Based on yhakbar's feedback, the raw output format should only return the value without the key for easier shell script integration. This would enable use cases like:
curl -s "$(terragrunt stack output --format=raw services.service['service-1'].url)"
- line := valueStr + "\n"
+ line := valueStr
+ if !opts.RawFormat {
+ line = key + " = " + line
+ }
+ line += "\n"
if _, err := writer.Write([]byte(line)); err != nil {
return errors.New(err)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
docs/_docs/04_reference/02-cli-options.md (1)
875-884
: Heading Style for 'Output Formats' Section
The "Output Formats" title is currently emphasized using bold text. For better markdown compliance (e.g., MD036), consider converting it into an actual header (e.g., using "#### Output Formats"). This change would align with common markdown style conventions.🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
875-875: Emphasis used instead of a heading
null(MD036, no-emphasis-as-heading)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
docs/_docs/04_reference/02-cli-options.md
(1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
docs/_docs/04_reference/02-cli-options.md
875-875: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Pull Request has non-contributor approval
- GitHub Check: unessential
- GitHub Check: build-and-test
🔇 Additional comments (7)
docs/_docs/04_reference/02-cli-options.md (7)
823-829
: New 'stack output' Section Added
This new section clearly introduces theterragrunt stack output
command, explaining its purpose and how it aggregates outputs from multiple units. The language is plain and accessible, making it easy for users to understand the new functionality.
830-838
: Clear Example for Basic Usage
The provided basic usage example is straightforward and shows typical output formatting. It’s good to see explicit examples (with key/value pairs) so users know what to expect when not using output modifiers.
840-866
: Documentation of Targeted Retrieval
The instructions and examples for retrieving outputs for a specific unit (and even a specific field) are very useful. They guide the user on how to narrow down output data effectively.
868-874
: Concise Example for Single Output Retrieval
The example showing retrieval of a specific output value (e.g.,project1_app1.custom_value1
) is concise and clear. It demonstrates the command’s flexibility for detailed queries.
885-920
: Structured JSON Output Example is Well Detailed
The example demonstrating how to use--format json
is comprehensive. It clearly shows the JSON structure and includes nested objects and arrays. This detailed example will help users integrate Terragrunt output with other tools easily.
922-942
: Accessing Nested JSON Lists Example
The successive example for accessing a specific list within the JSON output is clear. It illustrates how users can extract data for further processing, which is especially useful in automation scenarios.
945-952
: Raw Format Example Demonstrates Simplified Output
The final example for retrieving a simple value using--format raw
is succinct and effective. It confirms that when the raw format is used, the output returns just the value, making it more script-friendly.
Description
Add stacks output command:
Example:
RFC: #3313
TODOs
Read the Gruntwork contribution guidelines.
Release Notes (draft)
Added / Removed / Updated [X].
Migration Guide
Summary by CodeRabbit
New Features
Documentation
Tests