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

command/providers: Show provider requirements tree #25190

Merged
merged 1 commit into from Jun 10, 2020

Conversation

alisdair
Copy link
Member

@alisdair alisdair commented Jun 9, 2020

Providers can be required from multiple sources. The previous implementation of the providers sub-command displayed only a flat list of provider requirements, which made it difficult to see which modules required each provider.

This commit reintroduces the tree display of provider requirements, and adds a separate output block for providers required by existing state.

Screenshots

Configuration with nested modules:

nested

Un-upgraded configuration with providers required by configuration and state:

state

Providers can be required from multiple sources. The previous
implementation of the providers sub-command displayed only a flat list
of provider requirements, which made it difficult to see which modules
required each provider.

This commit reintroduces the tree display of provider requirements, and
adds a separate output block for providers required by existing state.
@alisdair alisdair requested a review from a team June 9, 2020 18:34
@alisdair alisdair self-assigned this Jun 9, 2020
@codecov
Copy link

codecov bot commented Jun 9, 2020

Codecov Report

Merging #25190 into master will increase coverage by 0.01%.
The diff coverage is 94.11%.

Impacted Files Coverage Δ
command/providers.go 55.81% <88.88%> (+5.16%) ⬆️
configs/config.go 76.29% <100.00%> (+2.52%) ⬆️
dag/marshal.go 52.27% <0.00%> (-1.14%) ⬇️
backend/remote/backend_common.go 54.57% <0.00%> (-0.68%) ⬇️

Copy link
Member Author

@alisdair alisdair left a comment

Choose a reason for hiding this comment

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

📝

td := tempDir(t)
copy.CopyDir(testFixturePath("providers/modules"), td)
defer os.RemoveAll(td)
defer testChdir(t, td)()
Copy link
Member Author

Choose a reason for hiding this comment

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

Fixing a bug which left dangling .terraform state when running tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

🎉 thank you! that had even been pointed out to me and i forgot 🤦

@@ -10,6 +10,6 @@ provider "bar" {
version = "2.0.0"
}

module "child" {
module "kiddo" {
source = "./child"
Copy link
Member Author

Choose a reason for hiding this comment

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

Renamed so that the module didn't match the source directory, so we can verify that the name is shown in the tree.

Copy link
Contributor

Choose a reason for hiding this comment

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

love kiddo/kinder, excellent choices

Module *Module
Requirements getproviders.Requirements
Children map[string]*ModuleRequirements
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This type and the method which returns an instance of it below are intended to be used in an upcoming improvement to the init command's diagnostics when providers fail to install. That's why the Module member is here, and also why it's in the configs package instead of command.

Copy link
Contributor

Choose a reason for hiding this comment

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

thank you for this extra context!

Copy link
Contributor

@mildwonkey mildwonkey left a comment

Choose a reason for hiding this comment

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

This looks fantastic @alisdair! 🎉 This is going to be a huge help for users (and us!) ❤️

I left one question, but it's absolutely not meant to indicate you need to change anything - just curious, no objections.

td := tempDir(t)
copy.CopyDir(testFixturePath("providers/modules"), td)
defer os.RemoveAll(td)
defer testChdir(t, td)()
Copy link
Contributor

Choose a reason for hiding this comment

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

🎉 thank you! that had even been pointed out to me and i forgot 🤦

c.showDiagnostics(diags)
if diags.HasErrors() {
return 1
}
return 0
}

func providersCommandPopulateTreeNode(node treeprint.Tree, deps getproviders.Requirements) {
for fqn, dep := range deps {
func (c *ProvidersCommand) populateTreeNode(tree treeprint.Tree, node *configs.ModuleRequirements) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Was there a specific reason or benefit to make this a method on the ProvidersCommand? I'm not opposed per se, but I don't see it using anything from the ProvidersCommand to explain the change - without this other commands could call this function.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, no good reason. I'm happy to change it back if you prefer!

In prototyping this feature I added another function to this file, and since it was also very providers-command specific I named it providersCommandWhatever as well. Then that made me realize that if we want to signal that the purpose of the function is specific to this command, making it a method is probably clearer than a long name prefix, so I did that for both. Then I removed that function and forgot about this one.

I think we have both patterns elsewhere in the command package: methods which don't reference the receiver, and package-scoped functions which are really only related to one struct. I slightly prefer the former but only at a 2/5 level.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nah, my approval stands 😄

At the absolute "worst" (ie, no problem at all, a totally normal and fine situation), we make a future change if we decide to use some of that functionality in another command (and even then the method would likely remain, and the other bits factored out).

@@ -10,6 +10,6 @@ provider "bar" {
version = "2.0.0"
}

module "child" {
module "kiddo" {
source = "./child"
Copy link
Contributor

Choose a reason for hiding this comment

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

love kiddo/kinder, excellent choices

@ghost
Copy link

ghost commented Jul 11, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@hashicorp hashicorp locked and limited conversation to collaborators Jul 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants