github.com/grange74/terraform@v0.7.0-rc3.0.20160722171430-8c8803864753/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 := r.Id()
   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 (x%s)\n",
   194  			r.Id(),
   195  			r.RawCount.Value())
   196  
   197  		ks := make([]string, 0, len(r.RawConfig.Raw))
   198  		for k, _ := range r.RawConfig.Raw {
   199  			ks = append(ks, k)
   200  		}
   201  		sort.Strings(ks)
   202  
   203  		for _, k := range ks {
   204  			result += fmt.Sprintf("  %s\n", k)
   205  		}
   206  
   207  		if len(r.Provisioners) > 0 {
   208  			result += fmt.Sprintf("  provisioners\n")
   209  			for _, p := range r.Provisioners {
   210  				result += fmt.Sprintf("    %s\n", p.Type)
   211  
   212  				ks := make([]string, 0, len(p.RawConfig.Raw))
   213  				for k, _ := range p.RawConfig.Raw {
   214  					ks = append(ks, k)
   215  				}
   216  				sort.Strings(ks)
   217  
   218  				for _, k := range ks {
   219  					result += fmt.Sprintf("      %s\n", k)
   220  				}
   221  			}
   222  		}
   223  
   224  		if len(r.DependsOn) > 0 {
   225  			result += fmt.Sprintf("  dependsOn\n")
   226  			for _, d := range r.DependsOn {
   227  				result += fmt.Sprintf("    %s\n", d)
   228  			}
   229  		}
   230  
   231  		if len(r.RawConfig.Variables) > 0 {
   232  			result += fmt.Sprintf("  vars\n")
   233  
   234  			ks := make([]string, 0, len(r.RawConfig.Variables))
   235  			for k, _ := range r.RawConfig.Variables {
   236  				ks = append(ks, k)
   237  			}
   238  			sort.Strings(ks)
   239  
   240  			for _, k := range ks {
   241  				rawV := r.RawConfig.Variables[k]
   242  				kind := "unknown"
   243  				str := rawV.FullKey()
   244  
   245  				switch rawV.(type) {
   246  				case *ResourceVariable:
   247  					kind = "resource"
   248  				case *UserVariable:
   249  					kind = "user"
   250  				}
   251  
   252  				result += fmt.Sprintf("    %s: %s\n", kind, str)
   253  			}
   254  		}
   255  	}
   256  
   257  	return strings.TrimSpace(result)
   258  }
   259  
   260  // This helper turns a variables field into a deterministic
   261  // string value for comparison in tests.
   262  func variablesStr(vs []*Variable) string {
   263  	result := ""
   264  	ks := make([]string, 0, len(vs))
   265  	m := make(map[string]*Variable)
   266  	for _, v := range vs {
   267  		ks = append(ks, v.Name)
   268  		m[v.Name] = v
   269  	}
   270  	sort.Strings(ks)
   271  
   272  	for _, k := range ks {
   273  		v := m[k]
   274  
   275  		required := ""
   276  		if v.Required() {
   277  			required = " (required)"
   278  		}
   279  
   280  		declaredType := ""
   281  		if v.DeclaredType != "" {
   282  			declaredType = fmt.Sprintf(" (%s)", v.DeclaredType)
   283  		}
   284  
   285  		if v.Default == nil || v.Default == "" {
   286  			v.Default = "<>"
   287  		}
   288  		if v.Description == "" {
   289  			v.Description = "<>"
   290  		}
   291  
   292  		result += fmt.Sprintf(
   293  			"%s%s%s\n  %v\n  %s\n",
   294  			k,
   295  			required,
   296  			declaredType,
   297  			v.Default,
   298  			v.Description)
   299  	}
   300  
   301  	return strings.TrimSpace(result)
   302  }