From 950f85e2b4597fd943dfab7e69b4660af6f5ae18 Mon Sep 17 00:00:00 2001 From: p4u1 Date: Sun, 7 Jul 2024 12:35:09 +0200 Subject: [PATCH] refactor(recipe): introduce new recipe struct and move some methods --- cli/app/backup.go | 36 +++++---- cli/app/check.go | 10 +-- cli/app/cmd.go | 19 ++--- cli/app/deploy.go | 15 ++-- cli/app/logs.go | 3 +- cli/app/new.go | 11 +-- cli/app/ps.go | 3 +- cli/app/restore.go | 9 ++- cli/app/rollback.go | 13 ++-- cli/app/secret.go | 27 ++++--- cli/app/upgrade.go | 11 +-- cli/recipe/fetch.go | 6 +- cli/recipe/lint.go | 9 ++- cli/recipe/upgrade.go | 9 ++- cli/updater/updater.go | 14 ++-- pkg/recipe/recipe.go | 169 ++++++++++++++++++++++------------------- 16 files changed, 197 insertions(+), 167 deletions(-) diff --git a/cli/app/backup.go b/cli/app/backup.go index c7067941..75d9eb6b 100644 --- a/cli/app/backup.go +++ b/cli/app/backup.go @@ -47,22 +47,23 @@ var appBackupListCommand = cli.Command{ Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if err := recipe.EnsureExists(app.Recipe); err != nil { + r := recipe.Get2(app.Recipe) + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -109,23 +110,24 @@ var appBackupDownloadCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -179,23 +181,24 @@ var appBackupCreateCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -237,23 +240,24 @@ var appBackupSnapshotsCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } diff --git a/cli/app/check.go b/cli/app/check.go index 53f68901..002a2978 100644 --- a/cli/app/check.go +++ b/cli/app/check.go @@ -7,7 +7,6 @@ import ( "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" - recipePkg "coopcloud.tech/abra/pkg/recipe" "github.com/urfave/cli" ) @@ -37,23 +36,24 @@ ${FOO:} syntax). "check" does not confirm or deny this for you.`, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipePkg.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipePkg.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipePkg.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } diff --git a/cli/app/cmd.go b/cli/app/cmd.go index c8215d28..a92dc946 100644 --- a/cli/app/cmd.go +++ b/cli/app/cmd.go @@ -17,7 +17,6 @@ import ( "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" - recipePkg "coopcloud.tech/abra/pkg/recipe" "github.com/urfave/cli" ) @@ -60,23 +59,24 @@ Example: }, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Name) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipePkg.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipePkg.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipePkg.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -228,23 +228,24 @@ var appCmdListCommand = cli.Command{ Before: internal.SubCommandBefore, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Name) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipePkg.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipePkg.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipePkg.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } diff --git a/cli/app/deploy.go b/cli/app/deploy.go index e7c3d5fd..27716276 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -52,28 +52,29 @@ recipes. Action: func(c *cli.Context) error { app := internal.ValidateApp(c) stackName := app.StackName() + r2 := recipe.Get2(app.Recipe) specificVersion := c.Args().Get(1) if specificVersion != "" && internal.Chaos { log.Fatal("cannot use and --chaos together") } - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r2.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r2.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r2.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r2.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -107,7 +108,7 @@ recipes. if specificVersion != "" { version = specificVersion log.Debugf("choosing %s as version to deploy", version) - if err := recipe.EnsureVersion(app.Recipe, version); err != nil { + if err := r2.EnsureVersion(version); err != nil { log.Fatal(err) } } @@ -157,7 +158,7 @@ recipes. if len(versions) > 0 && !internal.Chaos { version = versions[len(versions)-1] log.Debugf("choosing %s as version to deploy", version) - if err := recipe.EnsureVersion(app.Recipe, version); err != nil { + if err := r2.EnsureVersion(version); err != nil { log.Fatal(err) } } else { @@ -173,7 +174,7 @@ recipes. if internal.Chaos { log.Warnf("chaos mode engaged") var err error - version, err = recipe.ChaosVersion(app.Recipe) + version, err = r2.ChaosVersion() if err != nil { log.Fatal(err) } diff --git a/cli/app/logs.go b/cli/app/logs.go index c98d62b5..346e4ed3 100644 --- a/cli/app/logs.go +++ b/cli/app/logs.go @@ -38,8 +38,9 @@ var appLogsCommand = cli.Command{ Action: func(c *cli.Context) error { app := internal.ValidateApp(c) stackName := app.StackName() + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } diff --git a/cli/app/new.go b/cli/app/new.go index 5011af63..63aff1de 100644 --- a/cli/app/new.go +++ b/cli/app/new.go @@ -67,13 +67,14 @@ var appNewCommand = cli.Command{ }, Action: func(c *cli.Context) error { recipe := internal.ValidateRecipe(c) + r := recipePkg.Get2(recipe.Name) if !internal.Chaos { - if err := recipePkg.EnsureIsClean(recipe.Name); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } @@ -93,16 +94,16 @@ var appNewCommand = cli.Command{ version = tag } - if err := recipePkg.EnsureVersion(recipe.Name, version); err != nil { + if err := r.EnsureVersion(version); err != nil { log.Fatal(err) } } else { - if err := recipePkg.EnsureLatest(recipe.Name); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } } else { - if err := recipePkg.EnsureVersion(recipe.Name, c.Args().Get(1)); err != nil { + if err := r.EnsureVersion(c.Args().Get(1)); err != nil { log.Fatal(err) } } diff --git a/cli/app/ps.go b/cli/app/ps.go index 162c6f1c..0db7a7dc 100644 --- a/cli/app/ps.go +++ b/cli/app/ps.go @@ -35,6 +35,7 @@ var appPsCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) cl, err := client.New(app.Server) if err != nil { @@ -53,7 +54,7 @@ var appPsCommand = cli.Command{ statuses, err := appPkg.GetAppStatuses([]appPkg.App{app}, true) if statusMeta, ok := statuses[app.StackName()]; ok { if _, exists := statusMeta["chaos"]; !exists { - if err := recipe.EnsureVersion(app.Recipe, deployedVersion); err != nil { + if err := r.EnsureVersion(deployedVersion); err != nil { log.Fatal(err) } } diff --git a/cli/app/restore.go b/cli/app/restore.go index f95b497d..b6605d29 100644 --- a/cli/app/restore.go +++ b/cli/app/restore.go @@ -32,23 +32,24 @@ var appRestoreCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 6dbf449c..82eae9cc 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -52,28 +52,29 @@ recipes. Action: func(c *cli.Context) error { app := internal.ValidateApp(c) stackName := app.StackName() + r2 := recipe.Get2(app.Recipe) specificVersion := c.Args().Get(1) if specificVersion != "" && internal.Chaos { log.Fatal("cannot use and --chaos together") } - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r2.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r2.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r2.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r2.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -185,7 +186,7 @@ recipes. } if !internal.Chaos { - if err := recipe.EnsureVersion(app.Recipe, chosenDowngrade); err != nil { + if err := r2.EnsureVersion(chosenDowngrade); err != nil { log.Fatal(err) } } @@ -193,7 +194,7 @@ recipes. if internal.Chaos { log.Warn("chaos mode engaged") var err error - chosenDowngrade, err = recipe.ChaosVersion(app.Recipe) + chosenDowngrade, err = r2.ChaosVersion() if err != nil { log.Fatal(err) } diff --git a/cli/app/secret.go b/cli/app/secret.go index 672496f1..0f995fd0 100644 --- a/cli/app/secret.go +++ b/cli/app/secret.go @@ -56,23 +56,24 @@ var appSecretGenerateCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -263,23 +264,24 @@ Example: `, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -371,23 +373,24 @@ var appSecretLsCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + r := recipe.Get2(app.Recipe) - if err := recipe.EnsureExists(app.Recipe); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 4f54a481..f4d2bf85 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -58,6 +58,7 @@ recipes. Action: func(c *cli.Context) error { app := internal.ValidateApp(c) stackName := app.StackName() + r := recipe.Get2(app.Name) specificVersion := c.Args().Get(1) if specificVersion != "" && internal.Chaos { @@ -65,17 +66,17 @@ recipes. } if !internal.Chaos { - if err := recipe.EnsureIsClean(app.Recipe); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipe.EnsureUpToDate(app.Recipe); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipe.EnsureLatest(app.Recipe); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } @@ -219,7 +220,7 @@ recipes. } if !internal.Chaos { - if err := recipePkg.EnsureVersion(app.Recipe, chosenUpgrade); err != nil { + if err := r.EnsureVersion(chosenUpgrade); err != nil { log.Fatal(err) } } @@ -227,7 +228,7 @@ recipes. if internal.Chaos { log.Warn("chaos mode engaged") var err error - chosenUpgrade, err = recipePkg.ChaosVersion(app.Recipe) + chosenUpgrade, err = r.ChaosVersion() if err != nil { log.Fatal(err) } diff --git a/cli/recipe/fetch.go b/cli/recipe/fetch.go index 4bb0cb28..877700c7 100644 --- a/cli/recipe/fetch.go +++ b/cli/recipe/fetch.go @@ -24,9 +24,10 @@ var recipeFetchCommand = cli.Command{ BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { recipeName := c.Args().First() + r := recipe.Get2(recipeName) if recipeName != "" { internal.ValidateRecipe(c) - if err := recipe.Ensure(recipeName); err != nil { + if err := r.Ensure(); err != nil { log.Fatal(err) } return nil @@ -39,7 +40,8 @@ var recipeFetchCommand = cli.Command{ catlBar := formatter.CreateProgressbar(len(catalogue), "fetching latest recipes...") for recipeName := range catalogue { - if err := recipe.Ensure(recipeName); err != nil { + r := recipe.Get2(recipeName) + if err := r.Ensure(); err != nil { log.Error(err) } catlBar.Add(1) diff --git a/cli/recipe/lint.go b/cli/recipe/lint.go index 41a78db5..ecddc12b 100644 --- a/cli/recipe/lint.go +++ b/cli/recipe/lint.go @@ -28,23 +28,24 @@ var recipeLintCommand = cli.Command{ BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { recipe := internal.ValidateRecipe(c) + r := recipePkg.Get2(recipe.Name) - if err := recipePkg.EnsureExists(recipe.Name); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } if !internal.Chaos { - if err := recipePkg.EnsureIsClean(recipe.Name); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } if !internal.Offline { - if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } } - if err := recipePkg.EnsureLatest(recipe.Name); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } } diff --git a/cli/recipe/upgrade.go b/cli/recipe/upgrade.go index f6011b62..f51d5a96 100644 --- a/cli/recipe/upgrade.go +++ b/cli/recipe/upgrade.go @@ -72,20 +72,21 @@ You may invoke this command in "wizard" mode and be prompted for input: BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { recipe := internal.ValidateRecipe(c) + r := recipePkg.Get2(recipe.Name) - if err := recipePkg.EnsureIsClean(recipe.Name); err != nil { + if err := r.EnsureIsClean(); err != nil { log.Fatal(err) } - if err := recipePkg.EnsureExists(recipe.Name); err != nil { + if err := r.EnsureExists(); err != nil { log.Fatal(err) } - if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil { + if err := r.EnsureUpToDate(); err != nil { log.Fatal(err) } - if err := recipePkg.EnsureLatest(recipe.Name); err != nil { + if err := r.EnsureLatest(); err != nil { log.Fatal(err) } diff --git a/cli/updater/updater.go b/cli/updater/updater.go index 7fb7a2bd..49d0e854 100644 --- a/cli/updater/updater.go +++ b/cli/updater/updater.go @@ -318,20 +318,20 @@ func getAvailableUpgrades(cl *dockerclient.Client, stackName string, recipeName // processRecipeRepoVersion clones, pulls, checks out the version and lints the // recipe repository. -func processRecipeRepoVersion(recipeName, version string) error { - if err := recipe.EnsureExists(recipeName); err != nil { +func processRecipeRepoVersion(r recipe.Recipe2, version string) error { + if err := r.EnsureExists(); err != nil { return err } - if err := recipe.EnsureUpToDate(recipeName); err != nil { + if err := r.EnsureUpToDate(); err != nil { return err } - if err := recipe.EnsureVersion(recipeName, version); err != nil { + if err := r.EnsureVersion(version); err != nil { return err } - if r, err := recipe.Get(recipeName, internal.Offline); err != nil { + if r, err := recipe.Get(r.Name, internal.Offline); err != nil { return err } else if err := lint.LintForErrors(r); err != nil { return err @@ -445,7 +445,9 @@ func upgrade(cl *dockerclient.Client, stackName, recipeName, Env: env, } - if err = processRecipeRepoVersion(recipeName, upgradeVersion); err != nil { + r := recipe.Get2(recipeName) + + if err = processRecipeRepoVersion(r, upgradeVersion); err != nil { return err } diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index a112a256..bc343984 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -213,21 +213,22 @@ func (r Recipe) Tags() ([]string, error) { // Get retrieves a recipe. func Get(recipeName string, offline bool) (Recipe, error) { - if err := EnsureExists(recipeName); err != nil { + r := Get2(recipeName) + if err := r.EnsureExists(); err != nil { return Recipe{}, err } - pattern := fmt.Sprintf("%s/%s/compose**yml", config.RECIPES_DIR, recipeName) + pattern := fmt.Sprintf("%s/%s/compose**yml", config.RECIPES_DIR, r.Name) composeFiles, err := filepath.Glob(pattern) if err != nil { return Recipe{}, err } if len(composeFiles) == 0 { - return Recipe{}, fmt.Errorf("%s is missing a compose.yml or compose.*.yml file?", recipeName) + return Recipe{}, fmt.Errorf("%s is missing a compose.yml or compose.*.yml file?", r.Name) } - envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample") + envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") sampleEnv, err := envfile.ReadEnv(envSamplePath) if err != nil { return Recipe{}, err @@ -239,7 +240,7 @@ func Get(recipeName string, offline bool) (Recipe, error) { return Recipe{}, err } - meta, err := GetRecipeMeta(recipeName, offline) + meta, err := GetRecipeMeta(r.Name, offline) if err != nil { switch err.(type) { case RecipeMissingFromCatalogue: @@ -265,27 +266,35 @@ func (r Recipe) SampleEnv() (map[string]string, error) { return sampleEnv, nil } +func Get2(name string) Recipe2 { + return Recipe2{Name: name} +} + +type Recipe2 struct { + Name string +} + // Ensure makes sure the recipe exists, is up to date and has the latest version checked out. -func Ensure(recipeName string) error { - if err := EnsureExists(recipeName); err != nil { +func (r Recipe2) Ensure() error { + if err := r.EnsureExists(); err != nil { return err } - if err := EnsureUpToDate(recipeName); err != nil { + if err := r.EnsureUpToDate(); err != nil { return err } - if err := EnsureLatest(recipeName); err != nil { + if err := r.EnsureLatest(); err != nil { return err } return nil } -// EnsureExists ensures that a recipe is locally cloned -func EnsureExists(recipeName string) error { - recipeDir := path.Join(config.RECIPES_DIR, recipeName) +// EnsureExists ensures that the recipe is locally cloned +func (r Recipe2) EnsureExists() error { + recipeDir := path.Join(config.RECIPES_DIR, r.Name) if _, err := os.Stat(recipeDir); os.IsNotExist(err) { log.Debugf("%s does not exist, attemmpting to clone", recipeDir) - url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipeName) + url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, r.Name) if err := gitPkg.Clone(recipeDir, url); err != nil { return err } @@ -299,8 +308,8 @@ func EnsureExists(recipeName string) error { } // EnsureVersion checks whether a specific version exists for a recipe. -func EnsureVersion(recipeName, version string) error { - recipeDir := path.Join(config.RECIPES_DIR, recipeName) +func (r Recipe2) EnsureVersion(version string) error { + recipeDir := path.Join(config.RECIPES_DIR, r.Name) if err := gitPkg.EnsureGitRepo(recipeDir); err != nil { return err @@ -330,11 +339,11 @@ func EnsureVersion(recipeName, version string) error { joinedTags := strings.Join(parsedTags, ", ") if joinedTags != "" { - log.Debugf("read %s as tags for recipe %s", joinedTags, recipeName) + log.Debugf("read %s as tags for recipe %s", joinedTags, r.Name) } if tagRef.String() == "" { - return fmt.Errorf("the local copy of %s doesn't seem to have version %s available?", recipeName, version) + return fmt.Errorf("the local copy of %s doesn't seem to have version %s available?", r.Name, version) } worktree, err := repo.Worktree() @@ -351,14 +360,14 @@ func EnsureVersion(recipeName, version string) error { return err } - log.Debugf("successfully checked %s out to %s in %s", recipeName, tagRef.Short(), recipeDir) + log.Debugf("successfully checked %s out to %s in %s", r.Name, tagRef.Short(), recipeDir) return nil } // EnsureIsClean makes sure that the recipe repository has no unstaged changes. -func EnsureIsClean(recipeName string) error { - recipeDir := path.Join(config.RECIPES_DIR, recipeName) +func (r Recipe2) EnsureIsClean() error { + recipeDir := path.Join(config.RECIPES_DIR, r.Name) isClean, err := gitPkg.IsClean(recipeDir) if err != nil { @@ -367,15 +376,15 @@ func EnsureIsClean(recipeName string) error { if !isClean { msg := "%s (%s) has locally unstaged changes? please commit/remove your changes before proceeding" - return fmt.Errorf(msg, recipeName, recipeDir) + return fmt.Errorf(msg, r.Name, recipeDir) } return nil } -// EnsureLatest makes sure the latest commit is checked out for a local recipe repository -func EnsureLatest(recipeName string) error { - recipeDir := path.Join(config.RECIPES_DIR, recipeName) +// EnsureLatest makes sure the latest commit is checked out for the local recipe repository +func (r Recipe2) EnsureLatest() error { + recipeDir := path.Join(config.RECIPES_DIR, r.Name) if err := gitPkg.EnsureGitRepo(recipeDir); err != nil { return err @@ -410,18 +419,71 @@ func EnsureLatest(recipeName string) error { return nil } +// EnsureUpToDate ensures that the local repo is synced to the remote +func (r Recipe2) EnsureUpToDate() error { + recipeDir := path.Join(config.RECIPES_DIR, r.Name) + + repo, err := git.PlainOpen(recipeDir) + if err != nil { + return fmt.Errorf("unable to open %s: %s", recipeDir, err) + } + + remotes, err := repo.Remotes() + if err != nil { + return fmt.Errorf("unable to read remotes in %s: %s", recipeDir, err) + } + + if len(remotes) == 0 { + log.Debugf("cannot ensure %s is up-to-date, no git remotes configured", r.Name) + return nil + } + + worktree, err := repo.Worktree() + if err != nil { + return fmt.Errorf("unable to open git work tree in %s: %s", recipeDir, err) + } + + branch, err := gitPkg.CheckoutDefaultBranch(repo, recipeDir) + if err != nil { + return fmt.Errorf("unable to check out default branch in %s: %s", recipeDir, err) + } + + fetchOpts := &git.FetchOptions{Tags: git.AllTags} + if err := repo.Fetch(fetchOpts); err != nil { + if !strings.Contains(err.Error(), "already up-to-date") { + return fmt.Errorf("unable to fetch tags in %s: %s", recipeDir, err) + } + } + + opts := &git.PullOptions{ + Force: true, + ReferenceName: branch, + SingleBranch: true, + } + + if err := worktree.Pull(opts); err != nil { + if !strings.Contains(err.Error(), "already up-to-date") { + return fmt.Errorf("unable to git pull in %s: %s", recipeDir, err) + } + } + + log.Debugf("fetched latest git changes for %s", r.Name) + + return nil +} + // ChaosVersion constructs a chaos mode recipe version. -func ChaosVersion(recipeName string) (string, error) { +func (r Recipe2) ChaosVersion() (string, error) { var version string - head, err := gitPkg.GetRecipeHead(recipeName) + head, err := gitPkg.GetRecipeHead(r.Name) if err != nil { return version, err } version = formatter.SmallSHA(head.String()) - recipeDir := path.Join(config.RECIPES_DIR, recipeName) + recipeDir := path.Join(config.RECIPES_DIR, r.Name) isClean, err := gitPkg.IsClean(recipeDir) if err != nil { return version, err @@ -597,59 +659,6 @@ func GetStringInBetween(recipeName, str, start, end string) (result string, err return str[s : s+e], nil } -// EnsureUpToDate ensures that the local repo is synced to the remote -func EnsureUpToDate(recipeName string) error { - recipeDir := path.Join(config.RECIPES_DIR, recipeName) - - repo, err := git.PlainOpen(recipeDir) - if err != nil { - return fmt.Errorf("unable to open %s: %s", recipeDir, err) - } - - remotes, err := repo.Remotes() - if err != nil { - return fmt.Errorf("unable to read remotes in %s: %s", recipeDir, err) - } - - if len(remotes) == 0 { - log.Debugf("cannot ensure %s is up-to-date, no git remotes configured", recipeName) - return nil - } - - worktree, err := repo.Worktree() - if err != nil { - return fmt.Errorf("unable to open git work tree in %s: %s", recipeDir, err) - } - - branch, err := gitPkg.CheckoutDefaultBranch(repo, recipeDir) - if err != nil { - return fmt.Errorf("unable to check out default branch in %s: %s", recipeDir, err) - } - - fetchOpts := &git.FetchOptions{Tags: git.AllTags} - if err := repo.Fetch(fetchOpts); err != nil { - if !strings.Contains(err.Error(), "already up-to-date") { - return fmt.Errorf("unable to fetch tags in %s: %s", recipeDir, err) - } - } - - opts := &git.PullOptions{ - Force: true, - ReferenceName: branch, - SingleBranch: true, - } - - if err := worktree.Pull(opts); err != nil { - if !strings.Contains(err.Error(), "already up-to-date") { - return fmt.Errorf("unable to git pull in %s: %s", recipeDir, err) - } - } - - log.Debugf("fetched latest git changes for %s", recipeName) - - return nil -} - // ReadRecipeCatalogue reads the recipe catalogue. func ReadRecipeCatalogue(offline bool) (RecipeCatalogue, error) { recipes := make(RecipeCatalogue)