diff options
author | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
---|---|---|
committer | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
commit | 107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch) | |
tree | ca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/github.com/hashicorp/terraform/internal/earlyconfig | |
parent | 844b5a68d8af4791755b8f0ad293cc99f5959183 (diff) | |
download | terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.gz terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.zst terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.zip |
Upgrade to 0.12
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/internal/earlyconfig')
5 files changed, 378 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/internal/earlyconfig/config.go b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/config.go new file mode 100644 index 0000000..a9b8f98 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/config.go | |||
@@ -0,0 +1,123 @@ | |||
1 | package earlyconfig | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "sort" | ||
6 | |||
7 | version "github.com/hashicorp/go-version" | ||
8 | "github.com/hashicorp/terraform-config-inspect/tfconfig" | ||
9 | "github.com/hashicorp/terraform/addrs" | ||
10 | "github.com/hashicorp/terraform/moduledeps" | ||
11 | "github.com/hashicorp/terraform/plugin/discovery" | ||
12 | "github.com/hashicorp/terraform/tfdiags" | ||
13 | ) | ||
14 | |||
15 | // A Config is a node in the tree of modules within a configuration. | ||
16 | // | ||
17 | // The module tree is constructed by following ModuleCall instances recursively | ||
18 | // through the root module transitively into descendent modules. | ||
19 | type Config struct { | ||
20 | // RootModule points to the Config for the root module within the same | ||
21 | // module tree as this module. If this module _is_ the root module then | ||
22 | // this is self-referential. | ||
23 | Root *Config | ||
24 | |||
25 | // ParentModule points to the Config for the module that directly calls | ||
26 | // this module. If this is the root module then this field is nil. | ||
27 | Parent *Config | ||
28 | |||
29 | // Path is a sequence of module logical names that traverse from the root | ||
30 | // module to this config. Path is empty for the root module. | ||
31 | // | ||
32 | // This should only be used to display paths to the end-user in rare cases | ||
33 | // where we are talking about the static module tree, before module calls | ||
34 | // have been resolved. In most cases, an addrs.ModuleInstance describing | ||
35 | // a node in the dynamic module tree is better, since it will then include | ||
36 | // any keys resulting from evaluating "count" and "for_each" arguments. | ||
37 | Path addrs.Module | ||
38 | |||
39 | // ChildModules points to the Config for each of the direct child modules | ||
40 | // called from this module. The keys in this map match the keys in | ||
41 | // Module.ModuleCalls. | ||
42 | Children map[string]*Config | ||
43 | |||
44 | // Module points to the object describing the configuration for the | ||
45 | // various elements (variables, resources, etc) defined by this module. | ||
46 | Module *tfconfig.Module | ||
47 | |||
48 | // CallPos is the source position for the header of the module block that | ||
49 | // requested this module. | ||
50 | // | ||
51 | // This field is meaningless for the root module, where its contents are undefined. | ||
52 | CallPos tfconfig.SourcePos | ||
53 | |||
54 | // SourceAddr is the source address that the referenced module was requested | ||
55 | // from, as specified in configuration. | ||
56 | // | ||
57 | // This field is meaningless for the root module, where its contents are undefined. | ||
58 | SourceAddr string | ||
59 | |||
60 | // Version is the specific version that was selected for this module, | ||
61 | // based on version constraints given in configuration. | ||
62 | // | ||
63 | // This field is nil if the module was loaded from a non-registry source, | ||
64 | // since versions are not supported for other sources. | ||
65 | // | ||
66 | // This field is meaningless for the root module, where it will always | ||
67 | // be nil. | ||
68 | Version *version.Version | ||
69 | } | ||
70 | |||
71 | // ProviderDependencies returns the provider dependencies for the recieving | ||
72 | // config, including all of its descendent modules. | ||
73 | func (c *Config) ProviderDependencies() (*moduledeps.Module, tfdiags.Diagnostics) { | ||
74 | var diags tfdiags.Diagnostics | ||
75 | |||
76 | var name string | ||
77 | if len(c.Path) > 0 { | ||
78 | name = c.Path[len(c.Path)-1] | ||
79 | } | ||
80 | |||
81 | ret := &moduledeps.Module{ | ||
82 | Name: name, | ||
83 | } | ||
84 | |||
85 | providers := make(moduledeps.Providers) | ||
86 | for name, reqs := range c.Module.RequiredProviders { | ||
87 | inst := moduledeps.ProviderInstance(name) | ||
88 | var constraints version.Constraints | ||
89 | for _, reqStr := range reqs { | ||
90 | if reqStr != "" { | ||
91 | constraint, err := version.NewConstraint(reqStr) | ||
92 | if err != nil { | ||
93 | diags = diags.Append(wrapDiagnostic(tfconfig.Diagnostic{ | ||
94 | Severity: tfconfig.DiagError, | ||
95 | Summary: "Invalid provider version constraint", | ||
96 | Detail: fmt.Sprintf("Invalid version constraint %q for provider %s.", reqStr, name), | ||
97 | })) | ||
98 | continue | ||
99 | } | ||
100 | constraints = append(constraints, constraint...) | ||
101 | } | ||
102 | } | ||
103 | providers[inst] = moduledeps.ProviderDependency{ | ||
104 | Constraints: discovery.NewConstraints(constraints), | ||
105 | Reason: moduledeps.ProviderDependencyExplicit, | ||
106 | } | ||
107 | } | ||
108 | ret.Providers = providers | ||
109 | |||
110 | childNames := make([]string, 0, len(c.Children)) | ||
111 | for name := range c.Children { | ||
112 | childNames = append(childNames, name) | ||
113 | } | ||
114 | sort.Strings(childNames) | ||
115 | |||
116 | for _, name := range childNames { | ||
117 | child, childDiags := c.Children[name].ProviderDependencies() | ||
118 | ret.Children = append(ret.Children, child) | ||
119 | diags = diags.Append(childDiags) | ||
120 | } | ||
121 | |||
122 | return ret, diags | ||
123 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/internal/earlyconfig/config_build.go b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/config_build.go new file mode 100644 index 0000000..770d5df --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/config_build.go | |||
@@ -0,0 +1,144 @@ | |||
1 | package earlyconfig | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "sort" | ||
6 | "strings" | ||
7 | |||
8 | version "github.com/hashicorp/go-version" | ||
9 | "github.com/hashicorp/terraform-config-inspect/tfconfig" | ||
10 | "github.com/hashicorp/terraform/addrs" | ||
11 | "github.com/hashicorp/terraform/tfdiags" | ||
12 | ) | ||
13 | |||
14 | // BuildConfig constructs a Config from a root module by loading all of its | ||
15 | // descendent modules via the given ModuleWalker. | ||
16 | func BuildConfig(root *tfconfig.Module, walker ModuleWalker) (*Config, tfdiags.Diagnostics) { | ||
17 | var diags tfdiags.Diagnostics | ||
18 | cfg := &Config{ | ||
19 | Module: root, | ||
20 | } | ||
21 | cfg.Root = cfg // Root module is self-referential. | ||
22 | cfg.Children, diags = buildChildModules(cfg, walker) | ||
23 | return cfg, diags | ||
24 | } | ||
25 | |||
26 | func buildChildModules(parent *Config, walker ModuleWalker) (map[string]*Config, tfdiags.Diagnostics) { | ||
27 | var diags tfdiags.Diagnostics | ||
28 | ret := map[string]*Config{} | ||
29 | calls := parent.Module.ModuleCalls | ||
30 | |||
31 | // We'll sort the calls by their local names so that they'll appear in a | ||
32 | // predictable order in any logging that's produced during the walk. | ||
33 | callNames := make([]string, 0, len(calls)) | ||
34 | for k := range calls { | ||
35 | callNames = append(callNames, k) | ||
36 | } | ||
37 | sort.Strings(callNames) | ||
38 | |||
39 | for _, callName := range callNames { | ||
40 | call := calls[callName] | ||
41 | path := make([]string, len(parent.Path)+1) | ||
42 | copy(path, parent.Path) | ||
43 | path[len(path)-1] = call.Name | ||
44 | |||
45 | var vc version.Constraints | ||
46 | if strings.TrimSpace(call.Version) != "" { | ||
47 | var err error | ||
48 | vc, err = version.NewConstraint(call.Version) | ||
49 | if err != nil { | ||
50 | diags = diags.Append(wrapDiagnostic(tfconfig.Diagnostic{ | ||
51 | Severity: tfconfig.DiagError, | ||
52 | Summary: "Invalid version constraint", | ||
53 | Detail: fmt.Sprintf("Module %q (declared at %s line %d) has invalid version constraint %q: %s.", callName, call.Pos.Filename, call.Pos.Line, call.Version, err), | ||
54 | })) | ||
55 | continue | ||
56 | } | ||
57 | } | ||
58 | |||
59 | req := ModuleRequest{ | ||
60 | Name: call.Name, | ||
61 | Path: path, | ||
62 | SourceAddr: call.Source, | ||
63 | VersionConstraints: vc, | ||
64 | Parent: parent, | ||
65 | CallPos: call.Pos, | ||
66 | } | ||
67 | |||
68 | mod, ver, modDiags := walker.LoadModule(&req) | ||
69 | diags = append(diags, modDiags...) | ||
70 | if mod == nil { | ||
71 | // nil can be returned if the source address was invalid and so | ||
72 | // nothing could be loaded whatsoever. LoadModule should've | ||
73 | // returned at least one error diagnostic in that case. | ||
74 | continue | ||
75 | } | ||
76 | |||
77 | child := &Config{ | ||
78 | Parent: parent, | ||
79 | Root: parent.Root, | ||
80 | Path: path, | ||
81 | Module: mod, | ||
82 | CallPos: call.Pos, | ||
83 | SourceAddr: call.Source, | ||
84 | Version: ver, | ||
85 | } | ||
86 | |||
87 | child.Children, modDiags = buildChildModules(child, walker) | ||
88 | diags = diags.Append(modDiags) | ||
89 | |||
90 | ret[call.Name] = child | ||
91 | } | ||
92 | |||
93 | return ret, diags | ||
94 | } | ||
95 | |||
96 | // ModuleRequest is used as part of the ModuleWalker interface used with | ||
97 | // function BuildConfig. | ||
98 | type ModuleRequest struct { | ||
99 | // Name is the "logical name" of the module call within configuration. | ||
100 | // This is provided in case the name is used as part of a storage key | ||
101 | // for the module, but implementations must otherwise treat it as an | ||
102 | // opaque string. It is guaranteed to have already been validated as an | ||
103 | // HCL identifier and UTF-8 encoded. | ||
104 | Name string | ||
105 | |||
106 | // Path is a list of logical names that traverse from the root module to | ||
107 | // this module. This can be used, for example, to form a lookup key for | ||
108 | // each distinct module call in a configuration, allowing for multiple | ||
109 | // calls with the same name at different points in the tree. | ||
110 | Path addrs.Module | ||
111 | |||
112 | // SourceAddr is the source address string provided by the user in | ||
113 | // configuration. | ||
114 | SourceAddr string | ||
115 | |||
116 | // VersionConstraint is the version constraint applied to the module in | ||
117 | // configuration. | ||
118 | VersionConstraints version.Constraints | ||
119 | |||
120 | // Parent is the partially-constructed module tree node that the loaded | ||
121 | // module will be added to. Callers may refer to any field of this | ||
122 | // structure except Children, which is still under construction when | ||
123 | // ModuleRequest objects are created and thus has undefined content. | ||
124 | // The main reason this is provided is so that full module paths can | ||
125 | // be constructed for uniqueness. | ||
126 | Parent *Config | ||
127 | |||
128 | // CallRange is the source position for the header of the "module" block | ||
129 | // in configuration that prompted this request. | ||
130 | CallPos tfconfig.SourcePos | ||
131 | } | ||
132 | |||
133 | // ModuleWalker is an interface used with BuildConfig. | ||
134 | type ModuleWalker interface { | ||
135 | LoadModule(req *ModuleRequest) (*tfconfig.Module, *version.Version, tfdiags.Diagnostics) | ||
136 | } | ||
137 | |||
138 | // ModuleWalkerFunc is an implementation of ModuleWalker that directly wraps | ||
139 | // a callback function, for more convenient use of that interface. | ||
140 | type ModuleWalkerFunc func(req *ModuleRequest) (*tfconfig.Module, *version.Version, tfdiags.Diagnostics) | ||
141 | |||
142 | func (f ModuleWalkerFunc) LoadModule(req *ModuleRequest) (*tfconfig.Module, *version.Version, tfdiags.Diagnostics) { | ||
143 | return f(req) | ||
144 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/internal/earlyconfig/diagnostics.go b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/diagnostics.go new file mode 100644 index 0000000..9b2fd7f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/diagnostics.go | |||
@@ -0,0 +1,78 @@ | |||
1 | package earlyconfig | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | |||
6 | "github.com/hashicorp/terraform-config-inspect/tfconfig" | ||
7 | "github.com/hashicorp/terraform/tfdiags" | ||
8 | ) | ||
9 | |||
10 | func wrapDiagnostics(diags tfconfig.Diagnostics) tfdiags.Diagnostics { | ||
11 | ret := make(tfdiags.Diagnostics, len(diags)) | ||
12 | for i, diag := range diags { | ||
13 | ret[i] = wrapDiagnostic(diag) | ||
14 | } | ||
15 | return ret | ||
16 | } | ||
17 | |||
18 | func wrapDiagnostic(diag tfconfig.Diagnostic) tfdiags.Diagnostic { | ||
19 | return wrappedDiagnostic{ | ||
20 | d: diag, | ||
21 | } | ||
22 | } | ||
23 | |||
24 | type wrappedDiagnostic struct { | ||
25 | d tfconfig.Diagnostic | ||
26 | } | ||
27 | |||
28 | func (d wrappedDiagnostic) Severity() tfdiags.Severity { | ||
29 | switch d.d.Severity { | ||
30 | case tfconfig.DiagError: | ||
31 | return tfdiags.Error | ||
32 | case tfconfig.DiagWarning: | ||
33 | return tfdiags.Warning | ||
34 | default: | ||
35 | // Should never happen since there are no other severities | ||
36 | return 0 | ||
37 | } | ||
38 | } | ||
39 | |||
40 | func (d wrappedDiagnostic) Description() tfdiags.Description { | ||
41 | // Since the inspect library doesn't produce precise source locations, | ||
42 | // we include the position information as part of the error message text. | ||
43 | // See the comment inside method "Source" for more information. | ||
44 | switch { | ||
45 | case d.d.Pos == nil: | ||
46 | return tfdiags.Description{ | ||
47 | Summary: d.d.Summary, | ||
48 | Detail: d.d.Detail, | ||
49 | } | ||
50 | case d.d.Detail != "": | ||
51 | return tfdiags.Description{ | ||
52 | Summary: d.d.Summary, | ||
53 | Detail: fmt.Sprintf("On %s line %d: %s", d.d.Pos.Filename, d.d.Pos.Line, d.d.Detail), | ||
54 | } | ||
55 | default: | ||
56 | return tfdiags.Description{ | ||
57 | Summary: fmt.Sprintf("%s (on %s line %d)", d.d.Summary, d.d.Pos.Filename, d.d.Pos.Line), | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | |||
62 | func (d wrappedDiagnostic) Source() tfdiags.Source { | ||
63 | // Since the inspect library is constrained by the lowest common denominator | ||
64 | // between legacy HCL and modern HCL, it only returns ranges at whole-line | ||
65 | // granularity, and that isn't sufficient to populate a tfdiags.Source | ||
66 | // and so we'll just omit ranges altogether and include the line number in | ||
67 | // the Description text. | ||
68 | // | ||
69 | // Callers that want to return nicer errors should consider reacting to | ||
70 | // earlyconfig errors by attempting a follow-up parse with the normal | ||
71 | // config loader, which can produce more precise source location | ||
72 | // information. | ||
73 | return tfdiags.Source{} | ||
74 | } | ||
75 | |||
76 | func (d wrappedDiagnostic) FromExpr() *tfdiags.FromExpr { | ||
77 | return nil | ||
78 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/internal/earlyconfig/doc.go b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/doc.go new file mode 100644 index 0000000..a9cf10f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/doc.go | |||
@@ -0,0 +1,20 @@ | |||
1 | // Package earlyconfig is a specialized alternative to the top-level "configs" | ||
2 | // package that does only shallow processing of configuration and is therefore | ||
3 | // able to be much more liberal than the full config loader in what it accepts. | ||
4 | // | ||
5 | // In particular, it can accept both current and legacy HCL syntax, and it | ||
6 | // ignores top-level blocks that it doesn't recognize. These two characteristics | ||
7 | // make this package ideal for dependency-checking use-cases so that we are | ||
8 | // more likely to be able to return an error message about an explicit | ||
9 | // incompatibility than to return a less-actionable message about a construct | ||
10 | // not being supported. | ||
11 | // | ||
12 | // However, its liberal approach also means it should be used sparingly. It | ||
13 | // exists primarily for "terraform init", so that it is able to detect | ||
14 | // incompatibilities more robustly when installing dependencies. For most | ||
15 | // other use-cases, use the "configs" and "configs/configload" packages. | ||
16 | // | ||
17 | // Package earlyconfig is a wrapper around the terraform-config-inspect | ||
18 | // codebase, adding to it just some helper functionality for Terraform's own | ||
19 | // use-cases. | ||
20 | package earlyconfig | ||
diff --git a/vendor/github.com/hashicorp/terraform/internal/earlyconfig/module.go b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/module.go new file mode 100644 index 0000000..d2d6287 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/internal/earlyconfig/module.go | |||
@@ -0,0 +1,13 @@ | |||
1 | package earlyconfig | ||
2 | |||
3 | import ( | ||
4 | "github.com/hashicorp/terraform-config-inspect/tfconfig" | ||
5 | "github.com/hashicorp/terraform/tfdiags" | ||
6 | ) | ||
7 | |||
8 | // LoadModule loads some top-level metadata for the module in the given | ||
9 | // directory. | ||
10 | func LoadModule(dir string) (*tfconfig.Module, tfdiags.Diagnostics) { | ||
11 | mod, diags := tfconfig.LoadModule(dir) | ||
12 | return mod, wrapDiagnostics(diags) | ||
13 | } | ||