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  }