]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/plugin/discovery/meta_set.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / plugin / discovery / meta_set.go
1 package discovery
2
3 // A PluginMetaSet is a set of PluginMeta objects meeting a certain criteria.
4 //
5 // Methods on this type allow filtering of the set to produce subsets that
6 // meet more restrictive criteria.
7 type PluginMetaSet map[PluginMeta]struct{}
8
9 // Add inserts the given PluginMeta into the receiving set. This is a no-op
10 // if the given meta is already present.
11 func (s PluginMetaSet) Add(p PluginMeta) {
12 s[p] = struct{}{}
13 }
14
15 // Remove removes the given PluginMeta from the receiving set. This is a no-op
16 // if the given meta is not already present.
17 func (s PluginMetaSet) Remove(p PluginMeta) {
18 delete(s, p)
19 }
20
21 // Has returns true if the given meta is in the receiving set, or false
22 // otherwise.
23 func (s PluginMetaSet) Has(p PluginMeta) bool {
24 _, ok := s[p]
25 return ok
26 }
27
28 // Count returns the number of metas in the set
29 func (s PluginMetaSet) Count() int {
30 return len(s)
31 }
32
33 // ValidateVersions returns two new PluginMetaSets, separating those with
34 // versions that have syntax-valid semver versions from those that don't.
35 //
36 // Eliminating invalid versions from consideration (and possibly warning about
37 // them) is usually the first step of working with a meta set after discovery
38 // has completed.
39 func (s PluginMetaSet) ValidateVersions() (valid, invalid PluginMetaSet) {
40 valid = make(PluginMetaSet)
41 invalid = make(PluginMetaSet)
42 for p := range s {
43 if _, err := p.Version.Parse(); err == nil {
44 valid.Add(p)
45 } else {
46 invalid.Add(p)
47 }
48 }
49 return
50 }
51
52 // WithName returns the subset of metas that have the given name.
53 func (s PluginMetaSet) WithName(name string) PluginMetaSet {
54 ns := make(PluginMetaSet)
55 for p := range s {
56 if p.Name == name {
57 ns.Add(p)
58 }
59 }
60 return ns
61 }
62
63 // WithVersion returns the subset of metas that have the given version.
64 //
65 // This should be used only with the "valid" result from ValidateVersions;
66 // it will ignore any plugin metas that have invalid version strings.
67 func (s PluginMetaSet) WithVersion(version Version) PluginMetaSet {
68 ns := make(PluginMetaSet)
69 for p := range s {
70 gotVersion, err := p.Version.Parse()
71 if err != nil {
72 continue
73 }
74 if gotVersion.Equal(version) {
75 ns.Add(p)
76 }
77 }
78 return ns
79 }
80
81 // ByName groups the metas in the set by their Names, returning a map.
82 func (s PluginMetaSet) ByName() map[string]PluginMetaSet {
83 ret := make(map[string]PluginMetaSet)
84 for p := range s {
85 if _, ok := ret[p.Name]; !ok {
86 ret[p.Name] = make(PluginMetaSet)
87 }
88 ret[p.Name].Add(p)
89 }
90 return ret
91 }
92
93 // Newest returns the one item from the set that has the newest Version value.
94 //
95 // The result is meaningful only if the set is already filtered such that
96 // all of the metas have the same Name.
97 //
98 // If there isn't at least one meta in the set then this function will panic.
99 // Use Count() to ensure that there is at least one value before calling.
100 //
101 // If any of the metas have invalid version strings then this function will
102 // panic. Use ValidateVersions() first to filter out metas with invalid
103 // versions.
104 //
105 // If two metas have the same Version then one is arbitrarily chosen. This
106 // situation should be avoided by pre-filtering the set.
107 func (s PluginMetaSet) Newest() PluginMeta {
108 if len(s) == 0 {
109 panic("can't call NewestStable on empty PluginMetaSet")
110 }
111
112 var first = true
113 var winner PluginMeta
114 var winnerVersion Version
115 for p := range s {
116 version, err := p.Version.Parse()
117 if err != nil {
118 panic(err)
119 }
120
121 if first == true || version.NewerThan(winnerVersion) {
122 winner = p
123 winnerVersion = version
124 first = false
125 }
126 }
127
128 return winner
129 }
130
131 // ConstrainVersions takes a set of requirements and attempts to
132 // return a map from name to a set of metas that have the matching
133 // name and an appropriate version.
134 //
135 // If any of the given requirements match *no* plugins then its PluginMetaSet
136 // in the returned map will be empty.
137 //
138 // All viable metas are returned, so the caller can apply any desired filtering
139 // to reduce down to a single option. For example, calling Newest() to obtain
140 // the highest available version.
141 //
142 // If any of the metas in the set have invalid version strings then this
143 // function will panic. Use ValidateVersions() first to filter out metas with
144 // invalid versions.
145 func (s PluginMetaSet) ConstrainVersions(reqd PluginRequirements) map[string]PluginMetaSet {
146 ret := make(map[string]PluginMetaSet)
147 for p := range s {
148 name := p.Name
149 allowedVersions, ok := reqd[name]
150 if !ok {
151 continue
152 }
153 if _, ok := ret[p.Name]; !ok {
154 ret[p.Name] = make(PluginMetaSet)
155 }
156 version, err := p.Version.Parse()
157 if err != nil {
158 panic(err)
159 }
160 if allowedVersions.Allows(version) {
161 ret[p.Name].Add(p)
162 }
163 }
164 return ret
165 }
166
167 // OverridePaths returns a new set where any existing plugins with the given
168 // names are removed and replaced with the single path given in the map.
169 //
170 // This is here only to continue to support the legacy way of overriding
171 // plugin binaries in the .terraformrc file. It treats all given plugins
172 // as pre-versioning (version 0.0.0). This mechanism will eventually be
173 // phased out, with vendor directories being the intended replacement.
174 func (s PluginMetaSet) OverridePaths(paths map[string]string) PluginMetaSet {
175 ret := make(PluginMetaSet)
176 for p := range s {
177 if _, ok := paths[p.Name]; ok {
178 // Skip plugins that we're overridding
179 continue
180 }
181
182 ret.Add(p)
183 }
184
185 // Now add the metadata for overriding plugins
186 for name, path := range paths {
187 ret.Add(PluginMeta{
188 Name: name,
189 Version: VersionZero,
190 Path: path,
191 })
192 }
193
194 return ret
195 }