config: Variables is now a slice

This commit is contained in:
Mitchell Hashimoto 2014-07-18 17:48:30 -07:00
parent a583b800a4
commit e4bcd3c448
4 changed files with 39 additions and 26 deletions

View File

@ -15,7 +15,7 @@ import (
type Config struct { type Config struct {
ProviderConfigs map[string]*ProviderConfig ProviderConfigs map[string]*ProviderConfig
Resources []*Resource Resources []*Resource
Variables map[string]*Variable Variables []*Variable
Outputs map[string]*Output Outputs map[string]*Output
// The fields below can be filled in by loaders for validation // The fields below can be filled in by loaders for validation
@ -51,6 +51,7 @@ type Provisioner struct {
// Variable is a variable defined within the configuration. // Variable is a variable defined within the configuration.
type Variable struct { type Variable struct {
Name string
Default string Default string
Description string Description string
defaultSet bool defaultSet bool
@ -124,6 +125,10 @@ func (c *Config) Validate() error {
} }
vars := c.allVariables() vars := c.allVariables()
varMap := make(map[string]*Variable)
for _, v := range c.Variables {
varMap[v.Name] = v
}
// Check for references to user variables that do not actually // Check for references to user variables that do not actually
// exist and record those errors. // exist and record those errors.
@ -134,7 +139,7 @@ func (c *Config) Validate() error {
continue continue
} }
if _, ok := c.Variables[uv.Name]; !ok { if _, ok := varMap[uv.Name]; !ok {
errs = append(errs, fmt.Errorf( errs = append(errs, fmt.Errorf(
"%s: unknown variable referenced: %s", "%s: unknown variable referenced: %s",
source, source,

View File

@ -45,8 +45,10 @@ func (t *libuclConfigurable) Config() (*Config, error) {
// Start building up the actual configuration. We start with // Start building up the actual configuration. We start with
// variables. // variables.
// TODO(mitchellh): Make function like loadVariablesLibucl so that
// duplicates aren't overriden
config := new(Config) config := new(Config)
config.Variables = make(map[string]*Variable) config.Variables = make([]*Variable, 0, len(rawConfig.Variable))
for k, v := range rawConfig.Variable { for k, v := range rawConfig.Variable {
defaultSet := false defaultSet := false
for _, f := range v.Fields { for _, f := range v.Fields {
@ -56,11 +58,12 @@ func (t *libuclConfigurable) Config() (*Config, error) {
} }
} }
config.Variables[k] = &Variable{ config.Variables = append(config.Variables, &Variable{
Name: k,
Default: v.Default, Default: v.Default,
Description: v.Description, Description: v.Description,
defaultSet: defaultSet, defaultSet: defaultSet,
} })
} }
// Build the provider configs // Build the provider configs

View File

@ -116,16 +116,6 @@ func TestLoad_variables(t *testing.T) {
if actual != strings.TrimSpace(variablesVariablesStr) { if actual != strings.TrimSpace(variablesVariablesStr) {
t.Fatalf("bad:\n%s", actual) t.Fatalf("bad:\n%s", actual)
} }
if !c.Variables["foo"].Required() {
t.Fatal("foo should be required")
}
if c.Variables["bar"].Required() {
t.Fatal("bar should not be required")
}
if c.Variables["baz"].Required() {
t.Fatal("baz should not be required")
}
} }
func TestLoadDir_basic(t *testing.T) { func TestLoadDir_basic(t *testing.T) {
@ -384,16 +374,18 @@ func resourcesStr(rs []*Resource) string {
// This helper turns a variables field into a deterministic // This helper turns a variables field into a deterministic
// string value for comparison in tests. // string value for comparison in tests.
func variablesStr(vs map[string]*Variable) string { func variablesStr(vs []*Variable) string {
result := "" result := ""
ks := make([]string, 0, len(vs)) ks := make([]string, 0, len(vs))
for k, _ := range vs { m := make(map[string]*Variable)
ks = append(ks, k) for _, v := range vs {
ks = append(ks, v.Name)
m[v.Name] = v
} }
sort.Strings(ks) sort.Strings(ks)
for _, k := range ks { for _, k := range ks {
v := vs[k] v := m[k]
if v.Default == "" { if v.Default == "" {
v.Default = "<>" v.Default = "<>"
@ -402,9 +394,15 @@ func variablesStr(vs map[string]*Variable) string {
v.Description = "<>" v.Description = "<>"
} }
required := ""
if v.Required() {
required = " (required)"
}
result += fmt.Sprintf( result += fmt.Sprintf(
"%s\n %s\n %s\n", "%s%s\n %s\n %s\n",
k, k,
required,
v.Default, v.Default,
v.Description) v.Description)
} }
@ -497,7 +495,7 @@ aws_security_group[web] (x1)
` `
const importVariablesStr = ` const importVariablesStr = `
bar bar (required)
<> <>
<> <>
foo foo
@ -538,7 +536,7 @@ bar
baz baz
foo foo
<> <>
foo foo (required)
<> <>
<> <>
` `

View File

@ -26,9 +26,13 @@ func Merge(c1, c2 *Config) (*Config, error) {
// Merge variables: Variable merging is quite simple. Set fields in // Merge variables: Variable merging is quite simple. Set fields in
// later set variables override those earlier. // later set variables override those earlier.
c.Variables = c1.Variables c.Variables = make([]*Variable, 0, len(c1.Variables)+len(c2.Variables))
for k, v2 := range c2.Variables { varMap := make(map[string]*Variable)
v1, ok := c.Variables[k] for _, v := range c1.Variables {
varMap[v.Name] = v
}
for _, v2 := range c2.Variables {
v1, ok := varMap[v2.Name]
if ok { if ok {
if v2.Default == "" { if v2.Default == "" {
v2.Default = v1.Default v2.Default = v1.Default
@ -38,7 +42,10 @@ func Merge(c1, c2 *Config) (*Config, error) {
} }
} }
c.Variables[k] = v2 varMap[v2.Name] = v2
}
for _, v := range varMap {
c.Variables = append(c.Variables, v)
} }
// Merge outputs: If they collide, just take the latest one for now. In // Merge outputs: If they collide, just take the latest one for now. In