Skip to content

Commit

Permalink
feat: move stack metadata related to terramate.stack (#380)
Browse files Browse the repository at this point in the history
  • Loading branch information
katcipis committed Jun 7, 2022
1 parent 15b5b00 commit 2358a7b
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 78 deletions.
6 changes: 3 additions & 3 deletions cmd/terramate/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -816,9 +816,9 @@ func (c *cli) printMetadata() {
Msg("Print metadata for individual stack.")

c.log("\nstack %q:", stackMeta.Path())
c.log("\tterramate.name=%q", stackMeta.Name())
c.log("\tterramate.path=%q", stackMeta.Path())
c.log("\tterramate.description=%q", stackMeta.Desc())
c.log("\tterramate.stack.name=%q", stackMeta.Name())
c.log("\tterramate.stack.description=%q", stackMeta.Desc())
c.log("\tterramate.stack.path.absolute=%q", stackMeta.Path())
}
}

Expand Down
48 changes: 24 additions & 24 deletions cmd/terramate/e2etests/exp_metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ func TestCliMetadata(t *testing.T) {
Stdout: `Available metadata:
stack "/stack":
terramate.name="stack"
terramate.path="/stack"
terramate.description=""
terramate.stack.name="stack"
terramate.stack.description=""
terramate.stack.path.absolute="/stack"
`,
},
},
Expand All @@ -60,24 +60,24 @@ stack "/stack":
Stdout: `Available metadata:
stack "/somedir/stack3":
terramate.name="stack3"
terramate.path="/somedir/stack3"
terramate.description=""
terramate.stack.name="stack3"
terramate.stack.description=""
terramate.stack.path.absolute="/somedir/stack3"
stack "/somedir/stack4":
terramate.name="stack4"
terramate.path="/somedir/stack4"
terramate.description=""
terramate.stack.name="stack4"
terramate.stack.description=""
terramate.stack.path.absolute="/somedir/stack4"
stack "/stack1":
terramate.name="stack1"
terramate.path="/stack1"
terramate.description=""
terramate.stack.name="stack1"
terramate.stack.description=""
terramate.stack.path.absolute="/stack1"
stack "/stack2":
terramate.name="stack2"
terramate.path="/stack2"
terramate.description=""
terramate.stack.name="stack2"
terramate.stack.description=""
terramate.stack.path.absolute="/stack2"
`,
},
},
Expand All @@ -94,9 +94,9 @@ stack "/stack2":
Stdout: `Available metadata:
stack "/stack1":
terramate.name="stack1"
terramate.path="/stack1"
terramate.description=""
terramate.stack.name="stack1"
terramate.stack.description=""
terramate.stack.path.absolute="/stack1"
`,
},
},
Expand All @@ -113,14 +113,14 @@ stack "/stack1":
Stdout: `Available metadata:
stack "/somedir/stack3":
terramate.name="stack3"
terramate.path="/somedir/stack3"
terramate.description=""
terramate.stack.name="stack3"
terramate.stack.description=""
terramate.stack.path.absolute="/somedir/stack3"
stack "/somedir/stack4":
terramate.name="stack4"
terramate.path="/somedir/stack4"
terramate.description=""
terramate.stack.name="stack4"
terramate.stack.description=""
terramate.stack.path.absolute="/somedir/stack4"
`,
},
},
Expand Down
33 changes: 25 additions & 8 deletions docs/sharing-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ globals {
}
```

Globals can reference [metadata](metadata.md):
Globals can reference [metadata](#metadata):

```hcl
globals {
Expand Down Expand Up @@ -243,7 +243,7 @@ accessed through the variable namespace **terramate**.
This can be referenced from any Terramate code to reference
information like the path of the stack or its name.

## terramate.path (string)
## terramate.stack.path.absolute (string)

The absolute path of the stack relative to the project
root directory, not the host root directory. So it is absolute
Expand All @@ -258,10 +258,10 @@ Given this project layout:
└── stack-b
```

* terramate.path for **stack-a** = /stacks/stack-a
* terramate.path for **stack-b** = /stacks/stack-b
* **stack-a** = /stacks/stack-a
* **stack-b** = /stacks/stack-b

## terramate.name (string)
## terramate.stack.name (string)

The name of the stack.

Expand All @@ -274,16 +274,33 @@ Given this stack layout (from the root of the project):
└── stack-b
```

* terramate.name for **stack-a** = stack-a
* terramate.name for **stack-b** = stack-b
* **stack-a** = stack-a
* **stack-b** = stack-b

Please consider [stack configuration](stack.md) to see how
you can change the default stack name.

## terramate.description (string)
## terramate.stack.description (string)

The description of the stack, if it has any.
The default value is an empty string.

Please consider [stack configuration](stack.md) to see how
you can change the default stack description.

## Deprecated

Here is a list of older metadata that still can be used but are in the
process of deprecation.

### terramate.path (string)

Superseded by terramate.stack.path.absolute.

### terramate.name (string)

Superseded by terramate.stack.name.

### terramate.description (string)

Superseded by terramate.stack.description.
27 changes: 25 additions & 2 deletions generate/genfile/genfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,29 @@ func TestLoadGenerateFiles(t *testing.T) {
},
},
},
{
name: "all metadata available",
stack: "/stack",
configs: []hclconfig{
{
path: "/stack/test.tm",
add: generateFile(
labels("test"),
str("content", "${terramate.stack.path.absolute}-${terramate.stack.name}-${terramate.stack.description}"),
),
},
},
want: []result{
{
name: "test",
condition: true,
file: genFile{
origin: "/stack/test.tm",
body: "/stack-stack-",
},
},
},
},
{
name: "using globals and metadata with interpolation",
stack: "/stack",
Expand All @@ -146,7 +169,7 @@ func TestLoadGenerateFiles(t *testing.T) {
path: "/stack/test.tm",
add: generateFile(
labels("test"),
str("content", "${global.data}-${terramate.path}"),
str("content", "${global.data}-${terramate.stack.path.absolute}"),
),
},
},
Expand Down Expand Up @@ -384,7 +407,7 @@ func TestLoadGenerateFiles(t *testing.T) {
path: "/stack/yaml.tm",
add: generateFile(
labels("test.yml"),
expr("content", "tm_yamlencode({field = terramate.path})"),
expr("content", "tm_yamlencode({field = terramate.stack.path.absolute})"),
),
},
},
Expand Down
35 changes: 33 additions & 2 deletions generate/genhcl/genhcl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,37 @@ func TestLoadGeneratedHCL(t *testing.T) {
},
},
},
{
name: "all metadata available",
stack: "/stacks/stack",
configs: []hclconfig{
{
path: "/",
add: generateHCL(
labels("root"),
content(
expr("stack_path_absolute", "terramate.stack.path.absolute"),
expr("stack_name", "terramate.stack.name"),
expr("stack_description", "terramate.stack.description"),
),
),
},
},
want: []result{
{
name: "root",
hcl: genHCL{
origin: defaultCfg("/"),
condition: true,
body: hcldoc(
str("stack_description", ""),
str("stack_name", "stack"),
str("stack_path_absolute", "/stacks/stack"),
),
},
},
},
},
{
name: "generate HCL on project root dir",
stack: "/stacks/stack",
Expand All @@ -860,7 +891,7 @@ func TestLoadGeneratedHCL(t *testing.T) {
labels("root"),
content(
block("root",
expr("test", "terramate.path"),
expr("test", "terramate.stack.path.absolute"),
),
),
),
Expand Down Expand Up @@ -2443,7 +2474,7 @@ func TestPartialEval(t *testing.T) {
{
name: "terramate.path interpolation",
config: hcldoc(
str("string", `${terramate.path} test`),
str("string", `${terramate.stack.path.absolute} test`),
),
want: hcldoc(
str("string", `/stack test`),
Expand Down
43 changes: 22 additions & 21 deletions hcl/eval/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ func (c *Context) SetNamespace(name string, vals map[string]cty.Value) error {
Str("action", "SetNamespace()").
Logger()

logger.Trace().
Msg("Convert from map to object.")
obj, err := fromMapToObject(vals)
logger.Trace().Msg("Convert from map to object")

obj, err := FromMapToObject(vals)
if err != nil {
return fmt.Errorf("setting namespace %q:%v", name, err)
}
Expand Down Expand Up @@ -106,39 +106,40 @@ func (c *Context) PartialEval(expr hclsyntax.Expression) (hclwrite.Tokens, error
return engine.Eval()
}

func toWriteTokens(in hclsyntax.Tokens) hclwrite.Tokens {
tokens := make([]*hclwrite.Token, len(in))
for i, st := range in {
tokens[i] = &hclwrite.Token{
Type: st.Type,
Bytes: st.Bytes,
}
}
return tokens
}

func fromMapToObject(m map[string]cty.Value) (cty.Value, error) {
// FromMapToObject converts a map of cty.Value to an object.
func FromMapToObject(values map[string]cty.Value) (cty.Value, error) {
logger := log.With().
Str("action", "fromMapToObject()").
Logger()

logger.Trace().
Msg("Range over map.")
logger.Trace().Msg("Range over map")

ctyTypes := map[string]cty.Type{}
for key, value := range m {
for key, value := range values {
ctyTypes[key] = value.Type()
}

logger.Trace().
Msg("Convert type and value to object.")
logger.Trace().Msg("Convert type and value to object")

ctyObject := cty.Object(ctyTypes)
ctyVal, err := gocty.ToCtyValue(m, ctyObject)
ctyVal, err := gocty.ToCtyValue(values, ctyObject)
if err != nil {
return cty.Value{}, err
}
return ctyVal, nil
}

func toWriteTokens(in hclsyntax.Tokens) hclwrite.Tokens {
tokens := make([]*hclwrite.Token, len(in))
for i, st := range in {
tokens[i] = &hclwrite.Token{
Type: st.Type,
Bytes: st.Bytes,
}
}
return tokens
}

func newTmFunctions(tffuncs map[string]function.Function) map[string]function.Function {
tmfuncs := map[string]function.Function{}
for name, function := range tffuncs {
Expand Down
29 changes: 25 additions & 4 deletions stack/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ func (e *EvalCtx) SetGlobals(g Globals) error {

// SetMetadata sets the given metadata on the stack evaluation context.
func (e *EvalCtx) SetMetadata(sm Metadata) error {
return e.evalctx.SetNamespace("terramate", metaToCtyMap(sm))
namespaceValues, err := metaToCtyMap(sm)
if err != nil {
return errors.E(err, "setting metadata on eval ctx")
}
return e.evalctx.SetNamespace("terramate", namespaceValues)
}

// Eval will evaluate an expression given its context.
Expand All @@ -78,10 +82,27 @@ func (e *EvalCtx) HasNamespace(name string) bool {
return e.evalctx.HasNamespace(name)
}

func metaToCtyMap(m Metadata) map[string]cty.Value {
return map[string]cty.Value{
func metaToCtyMap(m Metadata) (map[string]cty.Value, error) {
path, err := eval.FromMapToObject(map[string]cty.Value{
"absolute": cty.StringVal(m.Path()),
})
if err != nil {
return nil, errors.E(err, "creating stack.path obj")
}

stack, err := eval.FromMapToObject(map[string]cty.Value{
"name": cty.StringVal(m.Name()),
"path": cty.StringVal(m.Path()),
"description": cty.StringVal(m.Desc()),
"path": path,
})
if err != nil {
return nil, errors.E(err, "creating stack obj")
}

return map[string]cty.Value{
"name": cty.StringVal(m.Name()), // DEPRECATED
"path": cty.StringVal(m.Path()), // DEPRECATED
"description": cty.StringVal(m.Desc()), // DEPRECATED
"stack": stack,
}, nil
}

0 comments on commit 2358a7b

Please sign in to comment.