github.com/gettyimages/terraform@v0.7.6-0.20161219132226-dc052c5707a3/config/config_string.go (about) 1 package config 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 "strings" 8 ) 9 10 // TestString is a Stringer-like function that outputs a string that can 11 // be used to easily compare multiple Config structures in unit tests. 12 // 13 // This function has no practical use outside of unit tests and debugging. 14 func (c *Config) TestString() string { 15 if c == nil { 16 return "<nil config>" 17 } 18 19 var buf bytes.Buffer 20 if len(c.Modules) > 0 { 21 buf.WriteString("Modules:\n\n") 22 buf.WriteString(modulesStr(c.Modules)) 23 buf.WriteString("\n\n") 24 } 25 26 if len(c.Variables) > 0 { 27 buf.WriteString("Variables:\n\n") 28 buf.WriteString(variablesStr(c.Variables)) 29 buf.WriteString("\n\n") 30 } 31 32 if len(c.ProviderConfigs) > 0 { 33 buf.WriteString("Provider Configs:\n\n") 34 buf.WriteString(providerConfigsStr(c.ProviderConfigs)) 35 buf.WriteString("\n\n") 36 } 37 38 if len(c.Resources) > 0 { 39 buf.WriteString("Resources:\n\n") 40 buf.WriteString(resourcesStr(c.Resources)) 41 buf.WriteString("\n\n") 42 } 43 44 if len(c.Outputs) > 0 { 45 buf.WriteString("Outputs:\n\n") 46 buf.WriteString(outputsStr(c.Outputs)) 47 buf.WriteString("\n") 48 } 49 50 return strings.TrimSpace(buf.String()) 51 } 52 53 func modulesStr(ms []*Module) string { 54 result := "" 55 order := make([]int, 0, len(ms)) 56 ks := make([]string, 0, len(ms)) 57 mapping := make(map[string]int) 58 for i, m := range ms { 59 k := m.Id() 60 ks = append(ks, k) 61 mapping[k] = i 62 } 63 sort.Strings(ks) 64 for _, k := range ks { 65 order = append(order, mapping[k]) 66 } 67 68 for _, i := range order { 69 m := ms[i] 70 result += fmt.Sprintf("%s\n", m.Id()) 71 72 ks := make([]string, 0, len(m.RawConfig.Raw)) 73 for k, _ := range m.RawConfig.Raw { 74 ks = append(ks, k) 75 } 76 sort.Strings(ks) 77 78 result += fmt.Sprintf(" source = %s\n", m.Source) 79 80 for _, k := range ks { 81 result += fmt.Sprintf(" %s\n", k) 82 } 83 } 84 85 return strings.TrimSpace(result) 86 } 87 88 func outputsStr(os []*Output) string { 89 ns := make([]string, 0, len(os)) 90 m := make(map[string]*Output) 91 for _, o := range os { 92 ns = append(ns, o.Name) 93 m[o.Name] = o 94 } 95 sort.Strings(ns) 96 97 result := "" 98 for _, n := range ns { 99 o := m[n] 100 101 result += fmt.Sprintf("%s\n", n) 102 103 if len(o.DependsOn) > 0 { 104 result += fmt.Sprintf(" dependsOn\n") 105 for _, d := range o.DependsOn { 106 result += fmt.Sprintf(" %s\n", d) 107 } 108 } 109 110 if len(o.RawConfig.Variables) > 0 { 111 result += fmt.Sprintf(" vars\n") 112 for _, rawV := range o.RawConfig.Variables { 113 kind := "unknown" 114 str := rawV.FullKey() 115 116 switch rawV.(type) { 117 case *ResourceVariable: 118 kind = "resource" 119 case *UserVariable: 120 kind = "user" 121 } 122 123 result += fmt.Sprintf(" %s: %s\n", kind, str) 124 } 125 } 126 } 127 128 return strings.TrimSpace(result) 129 } 130 131 // This helper turns a provider configs field into a deterministic 132 // string value for comparison in tests. 133 func providerConfigsStr(pcs []*ProviderConfig) string { 134 result := "" 135 136 ns := make([]string, 0, len(pcs)) 137 m := make(map[string]*ProviderConfig) 138 for _, n := range pcs { 139 ns = append(ns, n.Name) 140 m[n.Name] = n 141 } 142 sort.Strings(ns) 143 144 for _, n := range ns { 145 pc := m[n] 146 147 result += fmt.Sprintf("%s\n", n) 148 149 keys := make([]string, 0, len(pc.RawConfig.Raw)) 150 for k, _ := range pc.RawConfig.Raw { 151 keys = append(keys, k) 152 } 153 sort.Strings(keys) 154 155 for _, k := range keys { 156 result += fmt.Sprintf(" %s\n", k) 157 } 158 159 if len(pc.RawConfig.Variables) > 0 { 160 result += fmt.Sprintf(" vars\n") 161 for _, rawV := range pc.RawConfig.Variables { 162 kind := "unknown" 163 str := rawV.FullKey() 164 165 switch rawV.(type) { 166 case *ResourceVariable: 167 kind = "resource" 168 case *UserVariable: 169 kind = "user" 170 } 171 172 result += fmt.Sprintf(" %s: %s\n", kind, str) 173 } 174 } 175 } 176 177 return strings.TrimSpace(result) 178 } 179 180 // This helper turns a resources field into a deterministic 181 // string value for comparison in tests. 182 func resourcesStr(rs []*Resource) string { 183 result := "" 184 order := make([]int, 0, len(rs)) 185 ks := make([]string, 0, len(rs)) 186 mapping := make(map[string]int) 187 for i, r := range rs { 188 k := r.Id() 189 ks = append(ks, k) 190 mapping[k] = i 191 } 192 sort.Strings(ks) 193 for _, k := range ks { 194 order = append(order, mapping[k]) 195 } 196 197 for _, i := range order { 198 r := rs[i] 199 result += fmt.Sprintf( 200 "%s (x%s)\n", 201 r.Id(), 202 r.RawCount.Value()) 203 204 ks := make([]string, 0, len(r.RawConfig.Raw)) 205 for k, _ := range r.RawConfig.Raw { 206 ks = append(ks, k) 207 } 208 sort.Strings(ks) 209 210 for _, k := range ks { 211 result += fmt.Sprintf(" %s\n", k) 212 } 213 214 if len(r.Provisioners) > 0 { 215 result += fmt.Sprintf(" provisioners\n") 216 for _, p := range r.Provisioners { 217 result += fmt.Sprintf(" %s\n", p.Type) 218 219 ks := make([]string, 0, len(p.RawConfig.Raw)) 220 for k, _ := range p.RawConfig.Raw { 221 ks = append(ks, k) 222 } 223 sort.Strings(ks) 224 225 for _, k := range ks { 226 result += fmt.Sprintf(" %s\n", k) 227 } 228 } 229 } 230 231 if len(r.DependsOn) > 0 { 232 result += fmt.Sprintf(" dependsOn\n") 233 for _, d := range r.DependsOn { 234 result += fmt.Sprintf(" %s\n", d) 235 } 236 } 237 238 if len(r.RawConfig.Variables) > 0 { 239 result += fmt.Sprintf(" vars\n") 240 241 ks := make([]string, 0, len(r.RawConfig.Variables)) 242 for k, _ := range r.RawConfig.Variables { 243 ks = append(ks, k) 244 } 245 sort.Strings(ks) 246 247 for _, k := range ks { 248 rawV := r.RawConfig.Variables[k] 249 kind := "unknown" 250 str := rawV.FullKey() 251 252 switch rawV.(type) { 253 case *ResourceVariable: 254 kind = "resource" 255 case *UserVariable: 256 kind = "user" 257 } 258 259 result += fmt.Sprintf(" %s: %s\n", kind, str) 260 } 261 } 262 } 263 264 return strings.TrimSpace(result) 265 } 266 267 // This helper turns a variables field into a deterministic 268 // string value for comparison in tests. 269 func variablesStr(vs []*Variable) string { 270 result := "" 271 ks := make([]string, 0, len(vs)) 272 m := make(map[string]*Variable) 273 for _, v := range vs { 274 ks = append(ks, v.Name) 275 m[v.Name] = v 276 } 277 sort.Strings(ks) 278 279 for _, k := range ks { 280 v := m[k] 281 282 required := "" 283 if v.Required() { 284 required = " (required)" 285 } 286 287 declaredType := "" 288 if v.DeclaredType != "" { 289 declaredType = fmt.Sprintf(" (%s)", v.DeclaredType) 290 } 291 292 if v.Default == nil || v.Default == "" { 293 v.Default = "<>" 294 } 295 if v.Description == "" { 296 v.Description = "<>" 297 } 298 299 result += fmt.Sprintf( 300 "%s%s%s\n %v\n %s\n", 301 k, 302 required, 303 declaredType, 304 v.Default, 305 v.Description) 306 } 307 308 return strings.TrimSpace(result) 309 }