Skip to content
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

feat: Implementation of --all --graph flags #3944

Merged
merged 9 commits into from
Feb 28, 2025
Merged

Conversation

levkohimins
Copy link
Contributor

@levkohimins levkohimins commented Feb 27, 2025

Description

https://linear.app/gruntwork/issue/TG-604/add-all-to-run-command

TODOs

Read the Gruntwork contribution guidelines.

  • Update the docs.
  • Run the relevant tests successfully, including pre-commit checks.
  • Ensure any 3rd party code adheres with our license policy or delete this line if its not applicable.
  • Include release notes. If this PR is backward incompatible, include a migration guide.

Release Notes (draft)

Added / Removed / Updated [X].

Migration Guide

Summary by CodeRabbit

  • New Features

    • Enhanced CLI commands offer improved flag management and streamlined execution flows for multi-directory operations and graph-related actions.
    • Several operations (e.g., formatting, JSON rendering, input validation) now run more consistently.
  • Breaking Changes

    • Legacy options such as certain flags have been removed.
    • Pre-execution checks for experimental features have been introduced.
  • Tests

    • Integration tests have been updated to support dynamic command arguments and improve overall reliability.

Copy link

vercel bot commented Feb 27, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
terragrunt-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 28, 2025 9:04pm

Copy link
Contributor

coderabbitai bot commented Feb 27, 2025

Walkthrough

This PR refactors several Terragrunt CLI commands by introducing additional wrapping layers using the runall.WrapCommand and graph.WrapCommand functions. Multiple command modules now construct a command object first and then apply these wrappers to enrich behavior. Flag management is streamlined across commands, with some deprecated or obsolete flags removed, and test cases updated to allow flexible command arguments. Import paths are also adjusted to reflect a reorganization of common functionality.

Changes

File(s) Change Summary
cli/commands/aws-provider-patch/command.go, cli/commands/graph-dependencies/command.go, cli/commands/hclfmt/command.go, cli/commands/render-json/command.go, cli/commands/terragrunt-info/command.go, cli/commands/validate-inputs/command.go, cli/commands/run/command.go Updated command initialization: create a command object and then wrap it with runall.WrapCommand and graph.WrapCommand to modify execution behavior.
cli/commands/common/graph/action.go, cli/commands/common/graph/command.go, cli/commands/common/runall/command.go, cli/commands/run-all/command.go, cli/commands/run/flags.go Revised flag management and action logic: new flag definitions via helper functions, removal of obsolete flags (--all, --graph), and replacement of old action routines with calls to updated run functions.
cli/commands/common/runall/action_test.go, cli/commands/stack/action.go Updated import paths to reflect the new location of the runall functionality and minor adjustments in test references.
test/integration_graph_test.go, test/integration_test.go Enhanced testing: added an args field to test case structs and restructured loops to allow dynamic command argument formation.

Sequence Diagram(s)

sequenceDiagram
    participant User as CLI User
    participant Cmd as Command Object
    participant RunAll as runall.WrapCommand
    participant Graph as graph.WrapCommand
    participant Action as Underlying Command Action

    User->>Cmd: Invoke Command
    Cmd->>RunAll: Wrap command for stack execution
    RunAll->>Graph: Enhance command with graph behavior
    Graph->>Action: Execute wrapped command action
Loading

Possibly related PRs

Suggested reviewers

  • denis256
  • yhakbar

Poem

In layers our commands now reside,
With wrappers neat by each side,
RunAll and Graph join the parade,
Old flags and tests are gently remade,
Code flows smooth with a joyful stride! 🚀

Cheers to refactoring done right!

✨ Finishing Touches
  • 📝 Generate Docstrings

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (2)
cli/commands/common/runall/command.go (1)

18-19: Redundant constant definitions detected

The constants DeprecatedOutDirFlagName and OutDirFlagName have identical values ("out-dir"), and similarly for the JSON versions. This appears redundant and could cause confusion for maintainers.

-const (
-	AllFlagName        = "all"
-	OutDirFlagName     = "out-dir"
-	JSONOutDirFlagName = "json-out-dir"
-
-	DeprecatedOutDirFlagName     = "out-dir"
-	DeprecatedJSONOutDirFlagName = "json-out-dir"
-)
+const (
+	AllFlagName        = "all"
+	OutDirFlagName     = "out-dir"
+	JSONOutDirFlagName = "json-out-dir"
+
+	// If these are intended to be identical to non-deprecated versions,
+	// consider using the non-deprecated constants directly
+	DeprecatedOutDirFlagName     = OutDirFlagName
+	DeprecatedJSONOutDirFlagName = JSONOutDirFlagName
+)
test/integration_test.go (1)

3812-3846: Great refactoring with a test case-driven approach!

You've improved the TestStorePlanFilesJsonRelativePath function by using a table-driven test pattern that verifies multiple command formats. This:

  1. Tests various ways to use the new --all flag (both as a subcommand and as a flag)
  2. Ensures all command variants produce the same results
  3. Makes adding future test cases easier

This approach provides excellent coverage for the new CLI patterns while maintaining backward compatibility with existing commands.

Could you add a brief comment explaining the purpose of each test case variant? It would help make the differences between these commands more obvious to future maintainers.

 testCases := []struct {
     args string
 }{
+    // Legacy syntax with run-all subcommand
     {"run-all plan --terragrunt-non-interactive --log-level trace --working-dir %s --out-dir test --json-out-dir json"},
+    // New syntax with --all flag after run
     {"run --all plan --experiment cli-redesign --non-interactive --log-level trace --working-dir %s --out-dir test --json-out-dir json"},
+    // New syntax with --all flag after plan
     {"run plan --all --experiment cli-redesign --non-interactive --log-level trace --working-dir %s --out-dir test --json-out-dir json"},
+    // New syntax with command after -- separator
     {"run --all --experiment cli-redesign --non-interactive --log-level trace --working-dir %s --out-dir test --json-out-dir json -- plan"},
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7fa958f and f1e66e5.

📒 Files selected for processing (17)
  • cli/commands/aws-provider-patch/command.go (2 hunks)
  • cli/commands/common/graph/action.go (2 hunks)
  • cli/commands/common/graph/command.go (1 hunks)
  • cli/commands/common/runall/action_test.go (1 hunks)
  • cli/commands/common/runall/command.go (1 hunks)
  • cli/commands/graph-dependencies/command.go (2 hunks)
  • cli/commands/graph/command.go (2 hunks)
  • cli/commands/hclfmt/command.go (2 hunks)
  • cli/commands/render-json/command.go (2 hunks)
  • cli/commands/run-all/command.go (2 hunks)
  • cli/commands/run/command.go (5 hunks)
  • cli/commands/run/flags.go (0 hunks)
  • cli/commands/stack/action.go (1 hunks)
  • cli/commands/terragrunt-info/command.go (2 hunks)
  • cli/commands/validate-inputs/command.go (2 hunks)
  • test/integration_graph_test.go (2 hunks)
  • test/integration_test.go (2 hunks)
💤 Files with no reviewable changes (1)
  • cli/commands/run/flags.go
✅ Files skipped from review due to trivial changes (2)
  • cli/commands/stack/action.go
  • cli/commands/common/runall/action_test.go
🔇 Additional comments (54)
cli/commands/graph-dependencies/command.go (3)

5-6: Good addition of runall and graph packages

These new imports bring in the functionality needed for the --all and --graph flag implementations, which matches the PR objectives. Well-structured approach to reuse shared code.


17-23: Clean refactoring to prepare for command wrapping

Breaking this down into initializing a command variable first, rather than returning directly, makes the code more readable and maintainable.


24-27: Great implementation of command wrapping pattern

I like how you've applied a consistent wrapping pattern that will provide the --all and --graph functionality across multiple commands. This approach keeps the core command logic intact while layering on additional features.

cli/commands/validate-inputs/command.go (3)

6-7: Consistent imports across commands

Good job maintaining consistency with the same imports as other command files, making the codebase more predictable.


39-45: Nicely refactored command initialization

Breaking out the command initialization to a separate step before wrapping is clean and consistent with other command implementations.


46-49: Consistent command wrapping implementation

Following the same pattern as in other commands - first wrapping with runall, then with graph functionality. This consistency makes the codebase easier to understand and maintain.

cli/commands/terragrunt-info/command.go (3)

5-7: Consistent imports across commands

Maintaining the same import pattern across all command files is good practice - it makes the codebase more predictable and easier to follow.


17-23: Clean command initialization

Breaking out the command initialization allows for the subsequent wrapping steps in a readable way.


24-27: Consistent command wrapping pattern

The same wrapping pattern is applied here as in other commands - this consistency is excellent and ensures that all commands behave similarly with respect to the new flags.

cli/commands/render-json/command.go (3)

5-7: Consistent import approach

Good job maintaining the same import structure across all command files, which helps with codebase consistency.


58-65: Clean command initialization

This follows the same pattern as other command files - initializing the command first before applying wrappers.


66-69: Command wrapping implementation follows consistent pattern

The wrapping order (runall first, then graph) is maintained consistently with other commands. This consistency ensures predictable behavior across all commands.

cli/commands/aws-provider-patch/command.go (4)

33-34: Nice addition of the graph and runall imports.
They look well-organized, and it’s great that you grouped them under common for reusability.


66-72: Command creation logic looks straightforward.
Building the command as a struct gives you flexibility. This approach is consistent with the other commands, so everything remains nice and uniform.


74-75: Check wrap order if the outcome depends on the wrapper sequence.
Wrapping first with runall and then with graph might have consequences on flags or subcommands. If you’re confident in this order, carry on! Otherwise, consider reversing or double-checking.


77-77: Returning the final wrapped command.
This final step is a no-fuss approach, so all good here.

cli/commands/hclfmt/command.go (4)

5-6: runall and graph imports fit well.
It's great that you’re keeping each subcommand consistent with the broader wrapper strategy.


79-85: Command struct is nicely laid out.
Good job keeping the flags in a sorted arrangement. This ensures users see them in a predictable order.


87-88: Same wrap-order consideration.
runall then graph might matter for how flags get appended or how the commands chain together. Just verify that’s the intended flow.


90-90: Clean exit.
Returning the wrapped command keeps everything tidy. No issues spotted.

test/integration_graph_test.go (10)

89-93: Introducing args in the test struct is a good call.
It lets you parametrize the commands conveniently without rewriting separate test cases for each scenario. Sweet approach!


95-99: graph apply test variant.
This scenario sets up your CLI usage nicely, verifying that the base case and its additional flags play well together.


101-105: run --graph apply test scenario.
This coverage is great—it ensures your rewriting of the command under an experimental flag does what you expect.


107-111: run apply --graph with short-form flags.
Having a permutation with slightly rearranged flags is smart to confirm order isn’t messing up the logic.


122-122: Formatting the CLI command string for tests.
Double-check that the %s placeholders always match the number of arguments you pass in. It looks fine, but it’s a classic spot for mistakes if someone changes the usage later.


150-154: New test cases for non-Terraform command execution.
These expansions ensure coverage of multiple argument forms (like graph render-json). Super helpful for catching corner cases.


158-159: Friendly test naming approach.
In-line naming keeps logs quite readable if something goes south. Good stuff.


161-163: Flexible environment prep.
Parallel tests plus the environment copy is a sleek approach for verifying your test fixture consistency.


167-169: Run command with custom arguments.
Again, verify that your placeholders and arguments align. This is basic but critical for stable tests.


171-175: Verifying output files.
Awesome to see you’re ensuring the “graph” or “rendered” artifacts actually appear where expected. This helps prevent silent test regressions.

cli/commands/common/graph/action.go (2)

7-7: Swapping to the new runall import.
Consistent usage under common/runall packages helps keep everything tidy.


17-20: Reading and validating the Terragrunt config.
Neat approach. This fails early without leftover side effects if the config is missing or unreadable. A+ error handling.

cli/commands/graph/command.go (4)

9-9: Good addition of the common graph package

This import allows you to leverage functionality from the shared graph package, which supports the implementation of the --graph flag.


25-27: Nice refactoring of flag management

You've improved code organization by:

  1. Using the common graph package's NewFlags function
  2. Filtering out GraphRootFlagName to avoid duplication
  3. Appending run-specific flags

This approach centralizes flag definition and makes the code more maintainable.


32-32: Clean flag handling

Using the Sort() method directly on the flags makes the code more concise and readable.


50-50: Appropriate delegation to common package

Calling graph.Run from the common package properly delegates execution responsibility and maintains separation of concerns.

cli/commands/common/graph/command.go (3)

12-17: Well-defined flag constants

The constants are clearly defined and include appropriate naming for both current and deprecated flags. This supports backward compatibility while preparing for future improvements.


19-40: Well-structured flag creation function

The NewFlags function:

  1. Handles prefixes appropriately
  2. Creates flags with clear usage descriptions
  3. Properly sets up environment variable support
  4. Includes handling for deprecated flags with appropriate controls

This is a good example of encapsulating complex flag setup in a reusable function.


42-63: Great implementation of the command wrapper pattern

The WrapCommand function implements a clean wrapper approach that:

  1. Adds graph-specific flags to existing commands
  2. Conditionally executes graph functionality only when the flag is set
  3. Preserves the original command action for the non-graph case
  4. Takes care of sorting flags for consistent help output

This pattern makes the --graph flag functionality easily reusable across multiple commands.

cli/commands/run/command.go (5)

8-9: Good imports for new functionality

These imports enable the integration of the graph and runall features.


22-51: Improved command structure with feature checks

The restructured command now:

  1. Uses variable assignment for better readability
  2. Adds a Before hook to check for the CLI redesign experiment flag
  3. Maintains backward compatibility through experiment checks
  4. Preserves the original action logic

Nice job keeping the experimental feature behind a feature flag.


37-43: Good experimental feature protection

The Before function ensures the new CLI redesign is only used when explicitly enabled through experimentation flags. This is a solid approach for rolling out breaking changes safely.


53-56: Elegant command wrapping implementation

Wrapping the command with both runall and graph functionality:

  1. Keeps the base command focused on its core responsibilities
  2. Adds the --all and --graph features in a modular way
  3. Follows separation of concerns principles

This is a clean way to extend command functionality.


65-75: Improved variable usage for subcommand creation

Using a variable for subcommand creation before assignment improves clarity and makes debugging easier. Good refactoring.

cli/commands/run-all/command.go (4)

9-9: Good import for common runall functionality

This import enables reuse of the shared runall implementation, supporting the --all flag feature.


25-27: Well-structured flag management

This approach:

  1. Uses the common runall.NewFlags function with specific filtering
  2. Appends run-specific flags
  3. Keeps flag handling consistent with other commands

Good job centralizing flag definitions while customizing for specific command needs.


34-34: Clean flag assignment

Using the sorted flags directly in the command structure improves readability.


49-49: Proper delegation to common package

Calling runall.Run from the common package maintains separation of concerns and ensures consistent behavior across command implementations.

cli/commands/common/runall/command.go (5)

32-33: Great cross-tool compatibility

I like that the usage text explicitly mentions both OpenTofu and Terraform. This makes it clear to users that the functionality works with either tool, which is increasingly important as some users migrate to OpenTofu.


41-41: Flag registration is well-implemented

The use of the WithDeprecatedNames function to maintain backward compatibility while moving toward the new flag naming convention is a good practice. This ensures users with existing scripts won't experience breakage while encouraging adoption of the new flag format.


57-68: Elegant command wrapping implementation

This implementation nicely separates concerns by using the "action wrapping" pattern. If the --all flag isn't set, it just passes through to the original action. If it is set, it updates the Terragrunt options and redirects to the stack-wide implementation. This keeps the code clean and maintainable.


70-71: Good flag organization practice

Sorting the flags after combining them ensures a consistent order in help output, which improves the user experience. This is a small but thoughtful detail that makes the CLI more professional.


53-74:

❓ Verification inconclusive

Verify the Run function dependency

The WrapCommand function calls an external Run function that's not defined in this file. Make sure this function exists and is properly exported from the relevant package. While it's likely that this function is defined elsewhere in the codebase, it's worth verifying to avoid potential runtime errors.


🏁 Script executed:

#!/bin/bash
# Search for the Run function that's being called from the WrapCommand function
rg -A 1 -B 1 "func Run\(.*\*cli\.Context" --type go

Length of output: 53


Double-check the Run function existence

The WrapCommand function calls an external Run function, but our initial search didn’t return any results. Please verify manually that the Run function is indeed defined and properly exported from its package. If it’s defined elsewhere in the codebase, ensure that it’s correctly imported in this file to prevent any runtime errors.

test/integration_test.go (1)

17-17: Good addition of the runall import

The new import for runall package aligns with the goal of implementing the --all flag functionality.

path string
expectedModules []string
notExpectedModules []string
}{
{
args: "graph apply --terragrunt-non-interactive --terragrunt-working-dir %s --terragrunt-graph-root %s",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see it, so I'm going to ask to be sure: Do we have a check to see if a user is using both --all and --graph? What happens in that circumstance?

Copy link
Contributor Author

@levkohimins levkohimins Feb 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work. What to do in this case, return error disallowed to use --all and --graph flags simultaneously?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya. Users have asked for the ability to do this, but we don't support it, so we should throw an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this message OK?

Using the `--all` and `--graph` flags simultaneously is not supported.

@yhakbar
Copy link
Collaborator

yhakbar commented Feb 27, 2025

We're missing docs updates here, and a status update on the experiment. We'll either want to do that before we merge or shortly afterwards.

yhakbar
yhakbar previously approved these changes Feb 27, 2025
yhakbar
yhakbar previously approved these changes Feb 28, 2025
@yhakbar yhakbar merged commit 79a24f1 into main Feb 28, 2025
5 of 8 checks passed
@yhakbar yhakbar deleted the feat/all-graph-flag branch February 28, 2025 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants