diff --git a/cli/internal/validate.go b/cli/internal/validate.go index b95d1da9..6d257723 100644 --- a/cli/internal/validate.go +++ b/cli/internal/validate.go @@ -25,7 +25,7 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe { ShowSubcommandHelpAndError(c, errors.New("no recipe provided")) } - recipe, err := recipe.Get(recipeName) + chosenRecipe, err := recipe.Get(recipeName) if err != nil { if c.Command.Name == "generate" { if strings.Contains(err.Error(), "missing a compose") { @@ -37,9 +37,13 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe { } } - logrus.Debugf("validated '%s' as recipe argument", recipeName) + if err := recipe.EnsureUpToDate(recipeName); err != nil { + logrus.Fatal(err) + } - return recipe + logrus.Debugf("validated %s as recipe argument", recipeName) + + return chosenRecipe } // ValidateRecipeWithPrompt ensures a recipe argument is present before @@ -93,14 +97,18 @@ func ValidateRecipeWithPrompt(c *cli.Context) recipe.Recipe { ShowSubcommandHelpAndError(c, errors.New("no recipe provided")) } - recipe, err := recipe.Get(recipeName) + chosenRecipe, err := recipe.Get(recipeName) if err != nil { logrus.Fatal(err) } + if err := recipe.EnsureUpToDate(chosenRecipe.Name); err != nil { + logrus.Fatal(err) + } + logrus.Debugf("validated %s as recipe argument", recipeName) - return recipe + return chosenRecipe } // ValidateApp ensures the app name arg is valid. @@ -125,6 +133,10 @@ func ValidateApp(c *cli.Context) config.App { logrus.Fatal(err) } + if err := recipe.EnsureUpToDate(app.Type); err != nil { + logrus.Fatal(err) + } + if err := ssh.EnsureHostKey(app.Server); err != nil { logrus.Fatal(err) } diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index a5463ce7..257931b8 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -184,7 +184,7 @@ func EnsureVersion(recipeName, version string) error { return nil } -// EnsureLatest makes sure the latest commit is checkout on for a local recipe repository. +// EnsureLatest makes sure the latest commit is checked out for a local recipe repository func EnsureLatest(recipeName string) error { recipeDir := path.Join(config.ABRA_DIR, "apps", recipeName) @@ -285,3 +285,37 @@ func GetVersionLabelLocal(recipe Recipe) (string, error) { return label, nil } + +// EnsureUpToDate ensures that the local repo is synced to the remote +func EnsureUpToDate(recipeName string) error { + recipeDir := path.Join(config.ABRA_DIR, "apps", recipeName) + + repo, err := git.PlainOpen(recipeDir) + if err != nil { + return err + } + + worktree, err := repo.Worktree() + if err != nil { + return err + } + + branch, err := gitPkg.GetCurrentBranch(repo) + if err != nil { + return err + } + + opts := &git.PullOptions{ + ReferenceName: plumbing.ReferenceName(branch), + } + + if err := worktree.Pull(opts); err != nil { + if !strings.Contains(err.Error(), "already up-to-date") { + return err + } + } + + logrus.Debugf("fetched latest git changes for %s", recipeName) + + return nil +}