diff --git a/cmd/terramate/cli/cli.go b/cmd/terramate/cli/cli.go index 6af263b7f..15cc032ca 100644 --- a/cmd/terramate/cli/cli.go +++ b/cmd/terramate/cli/cli.go @@ -45,7 +45,6 @@ import ( const ( ErrOutdatedLocalRev errutil.Error = "outdated local revision" - ErrNoDefaultRemoteConfig errutil.Error = "repository must have a configured origin/main" ErrInit errutil.Error = "failed to initialize all stacks" ErrOutdatedGenCodeDetected errutil.Error = "outdated generated code detected" ) @@ -148,12 +147,7 @@ type cli struct { prj project } -func newCLI( - args []string, - stdin io.Reader, - stdout io.Writer, - stderr io.Writer, -) *cli { +func newCLI(args []string, stdin io.Reader, stdout, stderr io.Writer) *cli { if len(args) == 0 { // WHY: avoid default kong error, print help args = []string{"--help"} @@ -307,11 +301,10 @@ func (c *cli) run() { Logger() if c.parsedArgs.Changed { - logger.Trace(). - Msg("`Changed` flag was set.") + logger.Trace().Msg("`Changed` flag was set.") + + logger.Trace().Msg("Create new git wrapper.") - logger.Trace(). - Msg("Create new git wrapper.") git, err := newGit(c.root(), true) if err != nil { log.Fatal(). @@ -319,8 +312,8 @@ func (c *cli) run() { Msg("creating git wrapper.") } - logger.Trace(). - Msg("Check git default remote.") + logger.Trace().Msg("Check git default remote.") + if err := c.checkDefaultRemote(git); err != nil { log.Fatal(). Err(err). @@ -866,6 +859,10 @@ func (c *cli) runOnStacks() { func (c *cli) wd() string { return c.prj.wd } func (c *cli) root() string { return c.prj.root } +func (c *cli) gitcfg() *hcl.GitConfig { + return c.prj.rootcfg.Terramate.RootConfig.Git +} + func (c *cli) log(format string, args ...interface{}) { fmt.Fprintln(c.stdout, fmt.Sprintf(format, args...)) } @@ -880,8 +877,8 @@ func (c *cli) checkDefaultRemote(g *git.Git) error { Str("stack", c.wd()). Logger() - logger.Trace(). - Msg("Get list of configured git remotes.") + logger.Trace().Msg("Get list of configured git remotes.") + remotes, err := g.Remotes() if err != nil { return fmt.Errorf("checking if remote %q exists: %v", defaultRemote, err) @@ -889,36 +886,33 @@ func (c *cli) checkDefaultRemote(g *git.Git) error { var defRemote *git.Remote + gitOpt := c.gitcfg() + logger.Trace(). Msg("Find default git remote.") for _, remote := range remotes { - if remote.Name == defaultRemote { + if remote.Name == gitOpt.DefaultRemote { defRemote = &remote break } } if defRemote == nil { - return fmt.Errorf( - "%w:no default remote %q", - ErrNoDefaultRemoteConfig, - defaultRemote, + return fmt.Errorf("repository must have a configured %q remote", + gitOpt.DefaultRemote, ) } - logger.Trace(). - Msg("Find default git branch.") + logger.Trace().Msg("Find default git branch.") for _, branch := range defRemote.Branches { - if branch == defaultBranch { + if branch == gitOpt.DefaultBranch { return nil } } - return fmt.Errorf( - "%w:%q has no default branch %q,branches:%v", - ErrNoDefaultRemoteConfig, - defaultRemote, - defaultBranch, + return fmt.Errorf("remote %q has no default branch %q,branches:%v", + gitOpt.DefaultRemote, + gitOpt.DefaultBranch, defRemote.Branches, ) } @@ -929,8 +923,8 @@ func (c *cli) checkLocalDefaultIsUpdated(g *git.Git) error { Str("workingDir", c.wd()). Logger() - logger.Trace(). - Msg("Get current git branch.") + logger.Trace().Msg("Get current git branch.") + branch, err := g.CurrentBranch() if err != nil { // ON CI envs we don't have a clean way to get the branch name @@ -948,23 +942,26 @@ func (c *cli) checkLocalDefaultIsUpdated(g *git.Git) error { return nil } - if branch != defaultBranch { + gitcfg := c.gitcfg() + if branch != gitcfg.DefaultBranch { return nil } c.logerr("current branch %q is the default branch, checking if it is updated.", branch) - c.logerr("retrieving info from remote branch: %s/%s ...", defaultRemote, defaultBranch) + c.logerr("retrieving info from remote branch: %s/%s ...", + gitcfg.DefaultRemote, gitcfg.DefaultBranch) - logger.Trace(). - Msg("Fetch remote reference.") - remoteRef, err := g.FetchRemoteRev(defaultRemote, defaultBranch) + logger.Trace().Msg("Fetch remote reference.") + + remoteRef, err := g.FetchRemoteRev(gitcfg.DefaultRemote, gitcfg.DefaultBranch) if err != nil { return fmt.Errorf("checking if local branch %q is updated: %v", branch, err) } - c.logerr("retrieved info from remote branch: %s/%s.", defaultRemote, defaultBranch) - logger.Trace(). - Msg("Get local commit ID.") + c.logerr("retrieved info from remote branch: %s/%s.", gitcfg.DefaultRemote, gitcfg.DefaultBranch) + + logger.Trace().Msg("Get local commit ID.") + localCommitID, err := g.RevParse(branch) if err != nil { return fmt.Errorf("checking if local branch %q is updated: %v", branch, err) @@ -976,8 +973,8 @@ func (c *cli) checkLocalDefaultIsUpdated(g *git.Git) error { return fmt.Errorf( "%w: remote %s/%s=%q != local %s=%q", ErrOutdatedLocalRev, - defaultRemote, - defaultBranch, + gitcfg.DefaultRemote, + gitcfg.DefaultBranch, remoteRef.ShortCommitID(), branch, localRef.ShortCommitID(), @@ -1083,8 +1080,8 @@ func lookupProject(wd string) (prj project, found bool, err error) { Str("workingDir", wd). Logger() - logger.Trace(). - Msg("Create new git wrapper.") + logger.Trace().Msg("Create new git wrapper.") + gw, err := newGit(wd, false) if err == nil { logger.Trace(). diff --git a/cmd/terramate/e2etests/general_test.go b/cmd/terramate/e2etests/general_test.go index 57abb67f3..b116bea76 100644 --- a/cmd/terramate/e2etests/general_test.go +++ b/cmd/terramate/e2etests/general_test.go @@ -309,13 +309,13 @@ func TestFailsOnChangeDetectionIfCurrentBranchIsMainAndItIsOutdated(t *testing.T func TestFailsOnChangeDetectionIfRepoDoesntHaveOriginMain(t *testing.T) { rootdir := t.TempDir() - assertFails := func() { + assertFails := func(stderrRegex string) { t.Helper() ts := newCLI(t, rootdir) wantRes := runExpected{ Status: 1, - StderrRegex: cli.ErrNoDefaultRemoteConfig.Error(), + StderrRegex: stderrRegex, } assertRunResult(t, ts.run("stacks", "list", "--changed"), wantRes) @@ -332,7 +332,7 @@ func TestFailsOnChangeDetectionIfRepoDoesntHaveOriginMain(t *testing.T) { git := sandbox.NewGit(t, rootdir) git.InitLocalRepo() - assertFails() + assertFails("repository must have a configured") // the main branch only exists after first commit. path := test.WriteFile(t, git.BaseDir(), "README.md", "# generated by terramate") @@ -340,11 +340,11 @@ func TestFailsOnChangeDetectionIfRepoDoesntHaveOriginMain(t *testing.T) { git.Commit("first commit") git.SetupRemote("notorigin", "main", "main") - assertFails() + assertFails("repository must have a configured") git.CheckoutNew("not-main") git.SetupRemote("origin", "not-main", "main") - assertFails() + assertFails("has no default branch ") } func TestNoArgsProvidesBasicHelp(t *testing.T) { @@ -353,6 +353,35 @@ func TestNoArgsProvidesBasicHelp(t *testing.T) { assertRunResult(t, cli.run(), runExpected{Stdout: help.Stdout}) } +func TestFailsIfDefaultRemoteDoesntHaveDefaultBranch(t *testing.T) { + s := sandbox.NewWithGitConfig(t, sandbox.GitConfig{ + LocalBranchName: "main", + DefaultRemoteName: "origin", + DefaultRemoteBranchName: "default", + }) + + cli := newCLI(t, s.RootDir()) + assertRunResult(t, + cli.run("stacks", "list", "--changed"), + runExpected{ + Status: 1, + StderrRegex: "has no default branch ", + }, + ) + + test.WriteFile(t, s.RootDir(), "terramate.tm.hcl", ` +terramate { + config { + git { + default_branch = "default" + } + } +} +`) + + assertRun(t, cli.run("stacks", "list", "--changed")) +} + func TestLoadGitRootConfig(t *testing.T) { s := sandbox.NewWithGitConfig(t, sandbox.GitConfig{ DefaultRemoteName: "mineiros", diff --git a/config/config.go b/config/config.go index fa36e35c3..b80dcf65c 100644 --- a/config/config.go +++ b/config/config.go @@ -15,9 +15,6 @@ package config import ( - "os" - "path/filepath" - "github.com/mineiros-io/terramate/hcl" "github.com/rs/zerolog/log" ) @@ -31,24 +28,11 @@ const ( ) func TryLoadRootConfig(dir string) (cfg hcl.Config, found bool, err error) { - path := filepath.Join(dir, DefaultFilename) logger := log.With(). Str("action", "TryLoadRootConfig()"). Str("path", dir). - Str("configFile", path). Logger() - logger.Trace(). - Msg("Check if file exists.") - _, err = os.Stat(path) - if err != nil { - if os.IsNotExist(err) { - return hcl.Config{}, false, nil - } - - return hcl.Config{}, false, err - } - logger.Trace().Msg("Parse Terramate config.") cfg, err = hcl.ParseDir(dir)