Skip to content

Commit

Permalink
fix: fail if root config is not at project root (#459)
Browse files Browse the repository at this point in the history
Co-authored-by: Tiago Cesar Katcipis <tiagokatcipis@gmail.com>
  • Loading branch information
i4ki and katcipis authored Jul 9, 2022
1 parent cdb07a2 commit 4388834
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 38 deletions.
41 changes: 18 additions & 23 deletions cmd/terramate/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,11 @@ func lookupProject(wd string) (prj project, found bool, err error) {

logger.Trace().Msg("Create new git wrapper.")

rootcfg, rootpath, rootfound, err := config.TryLoadRootConfig(wd)
if err != nil {
return project{}, false, err
}

gw, err := newGit(wd, false)
if err == nil {
logger.Trace().Msg("Get root of git repo.")
Expand Down Expand Up @@ -1169,6 +1174,13 @@ func lookupProject(wd string) (prj project, found bool, err error) {

root := filepath.Dir(gitabs)

if rootfound && strings.HasPrefix(rootpath, root) && rootpath != root {
return project{}, false, errors.E(
"terramate root config found at %q but it must be at the root dir %q",
rootpath, root,
)
}

logger.Trace().Msg("Load root config.")

cfg, err := hcl.ParseDir(root, root)
Expand All @@ -1185,31 +1197,14 @@ func lookupProject(wd string) (prj project, found bool, err error) {
}
}

dir := wd

for {
logger.Trace().Msg("Load root config.")

cfg, ok, err := config.TryLoadRootConfig(dir)
if err != nil {
return project{}, false, err
}

if ok {
prj.root = dir
prj.rootcfg = cfg

return prj, true, nil
}

if dir == "/" {
break
}

dir = filepath.Dir(dir)
if !rootfound {
return project{}, false, nil
}

return project{}, false, nil
prj.root = rootpath
prj.rootcfg = rootcfg
return prj, true, nil

}

func configureLogging(logLevel string, logFmt string, output io.Writer) {
Expand Down
17 changes: 17 additions & 0 deletions cmd/terramate/e2etests/general_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package e2etest

import (
"fmt"
"path/filepath"
"strings"
"testing"

Expand Down Expand Up @@ -466,6 +467,22 @@ func TestCommandsNotRequiringGitSafeguards(t *testing.T) {
}
}

func TestE2ETerramateFailIfRootConfigIsNotAtProjectRoot(t *testing.T) {
s := sandbox.New(t)
s.BuildTree([]string{
"s:stacks/stack",
})

stacksDir := filepath.Join(s.RootDir(), "stacks")
test.WriteRootConfig(t, stacksDir)

cli := newCLI(t, stacksDir)
assertRunResult(t, cli.listStacks(), runExpected{
Status: 1,
StderrRegex: "terramate root config found at",
})
}

func setupLocalMainBranchBehindOriginMain(git *sandbox.Git, changeFiles func()) {
// dance below makes local main branch behind origin/main by 1 commit.
// - a "temp" branch is created to record current commit.
Expand Down
46 changes: 31 additions & 15 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package config

import (
"path/filepath"

"github.com/mineiros-io/terramate/hcl"
"github.com/rs/zerolog/log"
)
Expand All @@ -24,23 +26,37 @@ const (
DefaultFilename = "terramate.tm.hcl"
)

// TryLoadRootConfig loads Terramate root config. If no configuration is found
// it returns false, nil.
func TryLoadRootConfig(dir string) (cfg hcl.Config, found bool, err error) {
logger := log.With().
Str("action", "TryLoadRootConfig()").
Str("path", dir).
Logger()
// TryLoadRootConfig try to load the Terramate root config. It looks for the
// the config in fromdir and all parent directories until / is reached.
// If the configuration is found, it returns configpath != "" and found as true.
func TryLoadRootConfig(fromdir string) (cfg hcl.Config, configpath string, found bool, err error) {
for {
logger := log.With().
Str("action", "TryLoadRootConfig()").
Str("path", fromdir).
Logger()

logger.Trace().Msg("Parse Terramate config.")
logger.Trace().Msg("Parse Terramate config.")

cfg, err = hcl.ParseDir(dir, dir)
if err != nil {
return hcl.Config{}, false, err
}
cfg, err = hcl.ParseDir(fromdir, fromdir)
if err != nil {
return hcl.Config{}, "", false, err
}

if cfg.Terramate != nil && cfg.Terramate.Config != nil {
return cfg, fromdir, true, nil
}

if cfg.Terramate != nil && cfg.Terramate.Config != nil {
return cfg, true, nil
parent, ok := parentDir(fromdir)
if !ok {
break
}
fromdir = parent
}
return hcl.Config{}, false, nil
return hcl.Config{}, "", false, nil
}

func parentDir(dir string) (string, bool) {
parent := filepath.Dir(dir)
return parent, parent != dir
}

0 comments on commit 4388834

Please sign in to comment.