Skip to content

Commit

Permalink
feat: add stack.id (#441)
Browse files Browse the repository at this point in the history
  • Loading branch information
katcipis committed Jul 1, 2022
1 parent f92a01a commit 16684cf
Show file tree
Hide file tree
Showing 12 changed files with 852 additions and 521 deletions.
40 changes: 35 additions & 5 deletions generate/genfile/genfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func TestLoadGenerateFiles(t *testing.T) {
},
},
{
name: "all metadata available",
name: "all metadata available by default",
stack: "/stack",
configs: []hclconfig{
{
Expand All @@ -146,6 +146,7 @@ stack_path_abs=${terramate.stack.path.absolute}
stack_path_rel=${terramate.stack.path.relative}
stack_path_to_root=${terramate.stack.path.to_root}
stack_path_basename=${terramate.stack.path.basename}
stack_id=${tm_try(terramate.stack.id, "no-id")}
stack_name=${terramate.stack.name}
stack_description=${terramate.stack.description}
EOT`,
Expand All @@ -163,8 +164,37 @@ stack_path_abs=/stack
stack_path_rel=stack
stack_path_to_root=..
stack_path_basename=stack
stack_id=no-id
stack_name=stack
stack_description=
`,
},
},
},
},
{
name: "stack.id metadata available",
stack: "/stack:id=stack-id",
configs: []hclconfig{
{
path: "/stack/test.tm",
add: generateFile(
labels("test"),
expr("content", `<<EOT
stack_id=${terramate.stack.id}
EOT`,
)),
},
},
want: []result{
{
name: "test",
condition: true,
file: genFile{
origin: "/stack/test.tm",
body: `
stack_id=stack-id
`,
},
},
Expand Down Expand Up @@ -812,8 +842,8 @@ stack_description=
for _, tcase := range tcases {
t.Run(tcase.name, func(t *testing.T) {
s := sandbox.New(t)
stackEntry := s.CreateStack(tcase.stack)
stack := stackEntry.Load()
s.BuildTree([]string{"s:" + tcase.stack})
stack := s.LoadStacks()[0]

for _, cfg := range tcase.configs {
test.AppendFile(t, s.RootDir(), cfg.path, cfg.add.String())
Expand All @@ -825,10 +855,10 @@ stack_description=

if len(got) != len(tcase.want) {
for i, file := range got {
t.Logf("got[%d] = %v", i, file)
t.Logf("got[%d] = %+v", i, file)
}
for i, file := range tcase.want {
t.Logf("want[%d] = %v", i, file)
t.Logf("want[%d] = %+v", i, file)
}
t.Fatalf("length of got and want mismatch: got %d but want %d",
len(got), len(tcase.want))
Expand Down
35 changes: 32 additions & 3 deletions generate/genhcl/genhcl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ func TestLoadGeneratedHCL(t *testing.T) {
},
},
{
name: "all metadata available",
name: "all metadata available by default",
stack: "/stacks/stack",
configs: []hclconfig{
{
Expand All @@ -860,6 +860,7 @@ func TestLoadGeneratedHCL(t *testing.T) {
labels("root"),
content(
expr("stack_description", "terramate.stack.description"),
expr("stack_id", `tm_try(terramate.stack.id, "no-id")`),
expr("stack_name", "terramate.stack.name"),
expr("stack_path_abs", "terramate.stack.path.absolute"),
expr("stack_path_basename", "terramate.stack.path.basename"),
Expand All @@ -877,6 +878,7 @@ func TestLoadGeneratedHCL(t *testing.T) {
condition: true,
body: hcldoc(
str("stack_description", ""),
str("stack_id", "no-id"),
str("stack_name", "stack"),
str("stack_path_abs", "/stacks/stack"),
str("stack_path_basename", "stack"),
Expand All @@ -887,6 +889,33 @@ func TestLoadGeneratedHCL(t *testing.T) {
},
},
},
{
name: "stack.id metadata available",
stack: "/stacks/stack:id=stack-id",
configs: []hclconfig{
{
path: "/",
add: generateHCL(
labels("root"),
content(
expr("stack_id", "terramate.stack.id"),
),
),
},
},
want: []result{
{
name: "root",
hcl: genHCL{
origin: defaultCfg("/"),
condition: true,
body: hcldoc(
str("stack_id", "stack-id"),
),
},
},
},
},
{
name: "generate HCL on project root dir",
stack: "/stacks/stack",
Expand Down Expand Up @@ -1460,8 +1489,8 @@ func TestLoadGeneratedHCL(t *testing.T) {
for _, tcase := range tcases {
t.Run(tcase.name, func(t *testing.T) {
s := sandbox.New(t)
stackEntry := s.CreateStack(tcase.stack)
stack := stackEntry.Load()
s.BuildTree([]string{"s:" + tcase.stack})
stack := s.LoadStacks()[0]

for _, cfg := range tcase.configs {
filename := cfg.filename
Expand Down
47 changes: 47 additions & 0 deletions hcl/hcl.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package hcl
import (
"os"
"path/filepath"
"regexp"
"sort"
"strings"

Expand Down Expand Up @@ -79,8 +80,16 @@ type Terramate struct {
Config *RootConfig
}

// StackID represents the stack ID. Its zero value represents an undefined ID.
type StackID struct {
id *string
}

// Stack is the parsed "stack" HCL block.
type Stack struct {
// ID of the stack. If the ID is nil it indicates this stack has no ID.
ID StackID

// Name of the stack
Name string

Expand Down Expand Up @@ -153,6 +162,27 @@ type TerramateParser struct {
parsed bool
}

var stackIDRegex = regexp.MustCompile("^[a-zA-Z0-9_-]{1,64}$")

// NewStackID creates a new StackID with the given string as its id.
// It guarantees that the id passed is a valid StackID value,
// an error is returned otherwise.
func NewStackID(id string) (StackID, error) {
if !stackIDRegex.MatchString(id) {
return StackID{}, errors.E("Stack ID %q doesn't match %q", id, stackIDRegex)
}
return StackID{id: &id}, nil
}

// Value returns the ID string value and true if this StackID is defined,
// it returns "" and false otherwise.
func (s StackID) Value() (string, bool) {
if s.id == nil {
return "", false
}
return *s.id, true
}

// parsedFile tells the origin and kind of the parsedFile.
// The kind can be either internal or external, meaning the file was parsed
// by this parser or by another parser instance, respectively.
Expand Down Expand Up @@ -888,6 +918,23 @@ func parseStack(stack *Stack, stackblock *ast.Block) error {
Msg("Setting attribute on configuration.")

switch attr.Name {
case "id":
if attrVal.Type() != cty.String {
errs.Append(errors.E(attr.NameRange,
"field stack.\"id\" must be a \"string\" but is %q",
attrVal.Type().FriendlyName()),
)
continue
}
id, err := NewStackID(attrVal.AsString())
if err != nil {
errs.Append(errors.E(attr.NameRange, err))
continue
}
logger.Trace().
Str("id", attrVal.AsString()).
Msg("found valid stack ID definition")
stack.ID = id
case "name":
if attrVal.Type() != cty.String {
errs.Append(errors.E(attr.NameRange,
Expand Down

0 comments on commit 16684cf

Please sign in to comment.