config: add Append function
This commit is contained in:
parent
c6f049ffc6
commit
69b7bc5047
|
@ -0,0 +1,58 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
// Append appends one configuration to another.
|
||||||
|
//
|
||||||
|
// Append assumes that both configurations will not have
|
||||||
|
// conflicting variables, resources, etc. If they do, the
|
||||||
|
// problems will be caught in the validation phase.
|
||||||
|
//
|
||||||
|
// It is possible that c1, c2 on their own are not valid. For
|
||||||
|
// example, a resource in c2 may reference a variable in c1. But
|
||||||
|
// together, they would be valid.
|
||||||
|
func Append(c1, c2 *Config) (*Config, error) {
|
||||||
|
c := new(Config)
|
||||||
|
|
||||||
|
// Append unknown keys, but keep them unique since it is a set
|
||||||
|
unknowns := make(map[string]struct{})
|
||||||
|
for _, k := range c1.unknownKeys {
|
||||||
|
unknowns[k] = struct{}{}
|
||||||
|
}
|
||||||
|
for _, k := range c2.unknownKeys {
|
||||||
|
unknowns[k] = struct{}{}
|
||||||
|
}
|
||||||
|
for k, _ := range unknowns {
|
||||||
|
c.unknownKeys = append(c.unknownKeys, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c1.Outputs) > 0 || len(c2.Outputs) > 0 {
|
||||||
|
c.Outputs = make(
|
||||||
|
[]*Output, 0, len(c1.Outputs)+len(c2.Outputs))
|
||||||
|
c.Outputs = append(c.Outputs, c1.Outputs...)
|
||||||
|
c.Outputs = append(c.Outputs, c2.Outputs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c1.ProviderConfigs) > 0 || len(c2.ProviderConfigs) > 0 {
|
||||||
|
c.ProviderConfigs = make(
|
||||||
|
[]*ProviderConfig,
|
||||||
|
0, len(c1.ProviderConfigs)+len(c2.ProviderConfigs))
|
||||||
|
c.ProviderConfigs = append(c.ProviderConfigs, c1.ProviderConfigs...)
|
||||||
|
c.ProviderConfigs = append(c.ProviderConfigs, c2.ProviderConfigs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c1.Resources) > 0 || len(c2.Resources) > 0 {
|
||||||
|
c.Resources = make(
|
||||||
|
[]*Resource,
|
||||||
|
0, len(c1.Resources)+len(c2.Resources))
|
||||||
|
c.Resources = append(c.Resources, c1.Resources...)
|
||||||
|
c.Resources = append(c.Resources, c2.Resources...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c1.Variables) > 0 || len(c2.Variables) > 0 {
|
||||||
|
c.Variables = make(
|
||||||
|
[]*Variable, 0, len(c1.Variables)+len(c2.Variables))
|
||||||
|
c.Variables = append(c.Variables, c1.Variables...)
|
||||||
|
c.Variables = append(c.Variables, c2.Variables...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAppend(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
c1, c2, result *Config
|
||||||
|
err bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
&Config{
|
||||||
|
Outputs: []*Output{
|
||||||
|
&Output{Name: "foo"},
|
||||||
|
},
|
||||||
|
ProviderConfigs: []*ProviderConfig{
|
||||||
|
&ProviderConfig{Name: "foo"},
|
||||||
|
},
|
||||||
|
Resources: []*Resource{
|
||||||
|
&Resource{Name: "foo"},
|
||||||
|
},
|
||||||
|
Variables: []*Variable{
|
||||||
|
&Variable{Name: "foo"},
|
||||||
|
},
|
||||||
|
|
||||||
|
unknownKeys: []string{"foo"},
|
||||||
|
},
|
||||||
|
|
||||||
|
&Config{
|
||||||
|
Outputs: []*Output{
|
||||||
|
&Output{Name: "bar"},
|
||||||
|
},
|
||||||
|
ProviderConfigs: []*ProviderConfig{
|
||||||
|
&ProviderConfig{Name: "bar"},
|
||||||
|
},
|
||||||
|
Resources: []*Resource{
|
||||||
|
&Resource{Name: "bar"},
|
||||||
|
},
|
||||||
|
Variables: []*Variable{
|
||||||
|
&Variable{Name: "bar"},
|
||||||
|
},
|
||||||
|
|
||||||
|
unknownKeys: []string{"bar"},
|
||||||
|
},
|
||||||
|
|
||||||
|
&Config{
|
||||||
|
Outputs: []*Output{
|
||||||
|
&Output{Name: "foo"},
|
||||||
|
&Output{Name: "bar"},
|
||||||
|
},
|
||||||
|
ProviderConfigs: []*ProviderConfig{
|
||||||
|
&ProviderConfig{Name: "foo"},
|
||||||
|
&ProviderConfig{Name: "bar"},
|
||||||
|
},
|
||||||
|
Resources: []*Resource{
|
||||||
|
&Resource{Name: "foo"},
|
||||||
|
&Resource{Name: "bar"},
|
||||||
|
},
|
||||||
|
Variables: []*Variable{
|
||||||
|
&Variable{Name: "foo"},
|
||||||
|
&Variable{Name: "bar"},
|
||||||
|
},
|
||||||
|
|
||||||
|
unknownKeys: []string{"foo", "bar"},
|
||||||
|
},
|
||||||
|
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
actual, err := Append(tc.c1, tc.c2)
|
||||||
|
if (err != nil) != tc.err {
|
||||||
|
t.Fatalf("%d: error fail", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(actual, tc.result) {
|
||||||
|
t.Fatalf("%d: bad:\n\n%#v", i, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue