1
1
mirror of https://github.com/mcuadros/ascode synced 2024-11-23 01:11:59 +01:00

nested: nested blocks and tests

Signed-off-by: Máximo Cuadros <mcuadros@gmail.com>
This commit is contained in:
Máximo Cuadros 2019-07-02 00:13:58 +02:00
parent 07d0555a7e
commit 7d56f1762c
4 changed files with 161 additions and 26 deletions

60
main_test.go Normal file

@ -0,0 +1,60 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"testing"
"go.starlark.net/resolve"
"go.starlark.net/starlark"
"go.starlark.net/starlarktest"
)
func init() {
// The tests make extensive use of these not-yet-standard features.
resolve.AllowLambda = true
resolve.AllowNestedDef = true
resolve.AllowFloat = true
resolve.AllowSet = true
}
func TestProvider(t *testing.T) {
test(t, "testdata/provider.star")
}
func TestNestedBlock(t *testing.T) {
test(t, "testdata/nested.star")
}
func test(t *testing.T, filename string) {
log.SetOutput(ioutil.Discard)
thread := &starlark.Thread{Load: load}
starlarktest.SetReporter(thread, t)
provider := starlark.NewBuiltin("provider", func(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
name := args.Index(0).(starlark.String)
version := args.Index(1).(starlark.String)
return NewProviderInstance(&PluginManager{".providers"}, string(name), string(version))
})
predeclared := starlark.StringDict{
"provider": provider,
}
if _, err := starlark.ExecFile(thread, filename, nil, predeclared); err != nil {
if err, ok := err.(*starlark.EvalError); ok {
t.Fatal(err.Backtrace())
}
t.Fatal(err)
}
}
// load implements the 'load' operation as used in the evaluator tests.
func load(thread *starlark.Thread, module string) (starlark.StringDict, error) {
if module == "assert.star" {
return starlarktest.LoadAssertModule()
}
return nil, fmt.Errorf("load not implemented")
}

64
nested.go Normal file

@ -0,0 +1,64 @@
package main
import (
"fmt"
"github.com/hashicorp/terraform/configs/configschema"
"go.starlark.net/starlark"
)
type NestedBlock struct {
typ string
block *configschema.Block
*PointerList
}
func NewNestedBlock(typ string, block *configschema.Block, refs *PointerList) *NestedBlock {
return &NestedBlock{typ: typ, block: block, PointerList: refs}
}
// String honors the starlark.Value interface.
func (r *NestedBlock) String() string {
return fmt.Sprintf("%s", r.typ)
}
// Type honors the starlark.Value interface.
func (r *NestedBlock) Type() string {
return fmt.Sprintf("%s_collection", r.typ)
}
// Truth honors the starlark.Value interface.
func (r *NestedBlock) Truth() starlark.Bool {
return true // even when empty
}
// Freeze honors the starlark.Value interface.
func (r *NestedBlock) Freeze() {}
// Hash honors the starlark.Value interface.
func (r *NestedBlock) Hash() (uint32, error) { return 42, nil }
// Name honors the starlark.Callable interface.
func (b *NestedBlock) Name() string {
return b.typ
}
// CallInternal honors the starlark.Callable interface.
func (b *NestedBlock) CallInternal(thread *starlark.Thread, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var name starlark.String
if len(args) != 0 {
name = args.Index(0).(starlark.String)
}
resource, err := MakeResourceInstance(string(name), b.typ, b.block, kwargs)
if err != nil {
return nil, err
}
if err := b.PointerList.Append(resource); err != nil {
return nil, err
}
return resource, nil
}

@ -4,7 +4,7 @@ import (
"fmt"
"strings"
"github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/plugin/discovery"
"github.com/hashicorp/terraform/plugin"
"github.com/hashicorp/terraform/providers"
@ -14,14 +14,14 @@ import (
type ProviderInstance struct {
name string
provider *plugin.GRPCProvider
meta discovery.PluginMeta
dataSources *MapSchemaIntance
resources *MapSchemaIntance
}
func NewProviderInstance(pm *PluginManager, name string) (*ProviderInstance, error) {
cli := pm.Get(name, "")
func NewProviderInstance(pm *PluginManager, name, version string) (*ProviderInstance, error) {
cli, meta := pm.Get(name, version)
rpc, err := cli.Client()
if err != nil {
return nil, err
@ -39,33 +39,12 @@ func NewProviderInstance(pm *PluginManager, name string) (*ProviderInstance, err
return &ProviderInstance{
name: name,
provider: provider,
meta: meta,
dataSources: NewMapSchemaInstance(name, response.DataSources),
resources: NewMapSchemaInstance(name, response.ResourceTypes),
}, nil
}
func computeNestedBlocks(s map[string]providers.Schema) map[string]*configschema.NestedBlock {
blks := make(map[string]*configschema.NestedBlock)
for k, block := range s {
for n, nested := range block.Block.BlockTypes {
key := k + "_" + n
doComputeNestedBlocks(key, nested, blks)
}
}
return blks
}
func doComputeNestedBlocks(name string, b *configschema.NestedBlock, list map[string]*configschema.NestedBlock) {
list[name] = b
for k, block := range b.BlockTypes {
key := name + "_" + k
list[key] = block
doComputeNestedBlocks(key, block, list)
}
}
func (t *ProviderInstance) String() string {
return fmt.Sprintf("provider(%q)", t.name)
}
@ -80,6 +59,8 @@ func (t *ProviderInstance) Hash() (uint32, error) { return 1, nil }
func (t *ProviderInstance) Name() string { return t.name }
func (s *ProviderInstance) Attr(name string) (starlark.Value, error) {
switch name {
case "version":
return starlark.String(s.meta.Version), nil
case "data":
return s.dataSources, nil
case "resource":

30
testdata/nested.star vendored Normal file

@ -0,0 +1,30 @@
load("assert.star", "assert")
p = provider("aws", "2.13.0")
d = p.data.ami("foo")
assert.eq(type(d.filter), "filter_collection")
bar = d.filter(name="bar", values=["qux"])
assert.eq(type(bar), "filter")
assert.eq(bar.name, "bar")
assert.eq(bar.values, ["qux"])
assert.eq(len(d.filter), 1)
assert.eq(d.filter[0], bar)
qux = d.filter()
qux.name = "qux"
qux.values = ["bar"]
assert.eq(qux.name, "qux")
assert.eq(qux.values, ["bar"])
assert.eq(len(d.filter), 2)
assert.eq(d.filter[1], qux)
d.filter[1].values = ["baz"]
assert.eq(qux.values, ["baz"])
assert.ne(d.filter[0], d.filter[1])