github.com/shvar/terraform@v0.6.9-0.20151215234924-3365cd2231df/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.RawConfig.Variables) > 0 { 104 result += fmt.Sprintf(" vars\n") 105 for _, rawV := range o.RawConfig.Variables { 106 kind := "unknown" 107 str := rawV.FullKey() 108 109 switch rawV.(type) { 110 case *ResourceVariable: 111 kind = "resource" 112 case *UserVariable: 113 kind = "user" 114 } 115 116 result += fmt.Sprintf(" %s: %s\n", kind, str) 117 } 118 } 119 } 120 121 return strings.TrimSpace(result) 122 } 123 124 // This helper turns a provider configs field into a deterministic 125 // string value for comparison in tests. 126 func providerConfigsStr(pcs []*ProviderConfig) string { 127 result := "" 128 129 ns := make([]string, 0, len(pcs)) 130 m := make(map[string]*ProviderConfig) 131 for _, n := range pcs { 132 ns = append(ns, n.Name) 133 m[n.Name] = n 134 } 135 sort.Strings(ns) 136 137 for _, n := range ns { 138 pc := m[n] 139 140 result += fmt.Sprintf("%s\n", n) 141 142 keys := make([]string, 0, len(pc.RawConfig.Raw)) 143 for k, _ := range pc.RawConfig.Raw { 144 keys = append(keys, k) 145 } 146 sort.Strings(keys) 147 148 for _, k := range keys { 149 result += fmt.Sprintf(" %s\n", k) 150 } 151 152 if len(pc.RawConfig.Variables) > 0 { 153 result += fmt.Sprintf(" vars\n") 154 for _, rawV := range pc.RawConfig.Variables { 155 kind := "unknown" 156 str := rawV.FullKey() 157 158 switch rawV.(type) { 159 case *ResourceVariable: 160 kind = "resource" 161 case *UserVariable: 162 kind = "user" 163 } 164 165 result += fmt.Sprintf(" %s: %s\n", kind, str) 166 } 167 } 168 } 169 170 return strings.TrimSpace(result) 171 } 172 173 // This helper turns a resources field into a deterministic 174 // string value for comparison in tests. 175 func resourcesStr(rs []*Resource) string { 176 result := "" 177 order := make([]int, 0, len(rs)) 178 ks := make([]string, 0, len(rs)) 179 mapping := make(map[string]int) 180 for i, r := range rs { 181 k := fmt.Sprintf("%s[%s]", r.Type, r.Name) 182 ks = append(ks, k) 183 mapping[k] = i 184 } 185 sort.Strings(ks) 186 for _, k := range ks { 187 order = append(order, mapping[k]) 188 } 189 190 for _, i := range order { 191 r := rs[i] 192 result += fmt.Sprintf( 193 "%s[%s] (x%s)\n", 194 r.Type, 195 r.Name, 196 r.RawCount.Value()) 197 198 ks := make([]string, 0, len(r.RawConfig.Raw)) 199 for k, _ := range r.RawConfig.Raw { 200 ks = append(ks, k) 201 } 202 sort.Strings(ks) 203 204 for _, k := range ks { 205 result += fmt.Sprintf(" %s\n", k) 206 } 207 208 if len(r.Provisioners) > 0 { 209 result += fmt.Sprintf(" provisioners\n") 210 for _, p := range r.Provisioners { 211 result += fmt.Sprintf(" %s\n", p.Type) 212 213 ks := make([]string, 0, len(p.RawConfig.Raw)) 214 for k, _ := range p.RawConfig.Raw { 215 ks = append(ks, k) 216 } 217 sort.Strings(ks) 218 219 for _, k := range ks { 220 result += fmt.Sprintf(" %s\n", k) 221 } 222 } 223 } 224 225 if len(r.DependsOn) > 0 { 226 result += fmt.Sprintf(" dependsOn\n") 227 for _, d := range r.DependsOn { 228 result += fmt.Sprintf(" %s\n", d) 229 } 230 } 231 232 if len(r.RawConfig.Variables) > 0 { 233 result += fmt.Sprintf(" vars\n") 234 235 ks := make([]string, 0, len(r.RawConfig.Variables)) 236 for k, _ := range r.RawConfig.Variables { 237 ks = append(ks, k) 238 } 239 sort.Strings(ks) 240 241 for _, k := range ks { 242 rawV := r.RawConfig.Variables[k] 243 kind := "unknown" 244 str := rawV.FullKey() 245 246 switch rawV.(type) { 247 case *ResourceVariable: 248 kind = "resource" 249 case *UserVariable: 250 kind = "user" 251 } 252 253 result += fmt.Sprintf(" %s: %s\n", kind, str) 254 } 255 } 256 } 257 258 return strings.TrimSpace(result) 259 } 260 261 // This helper turns a variables field into a deterministic 262 // string value for comparison in tests. 263 func variablesStr(vs []*Variable) string { 264 result := "" 265 ks := make([]string, 0, len(vs)) 266 m := make(map[string]*Variable) 267 for _, v := range vs { 268 ks = append(ks, v.Name) 269 m[v.Name] = v 270 } 271 sort.Strings(ks) 272 273 for _, k := range ks { 274 v := m[k] 275 276 required := "" 277 if v.Required() { 278 required = " (required)" 279 } 280 281 if v.Default == nil || v.Default == "" { 282 v.Default = "<>" 283 } 284 if v.Description == "" { 285 v.Description = "<>" 286 } 287 288 result += fmt.Sprintf( 289 "%s%s\n %v\n %s\n", 290 k, 291 required, 292 v.Default, 293 v.Description) 294 } 295 296 return strings.TrimSpace(result) 297 }