diff --git a/cli/app/cp.go b/cli/app/cp.go index f1c50d2a..e5d2035c 100644 --- a/cli/app/cp.go +++ b/cli/app/cp.go @@ -50,6 +50,10 @@ And if you want to copy that file back to your current working directory locally Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { + log.Fatal(err) + } + src := c.Args().Get(1) dst := c.Args().Get(2) if src == "" { diff --git a/cli/app/deploy.go b/cli/app/deploy.go index aa4f3367..9a9524f1 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -52,6 +52,9 @@ EXAMPLE: stackName := app.StackName() specificVersion := c.Args().Get(1) + if specificVersion == "" { + specificVersion = app.Recipe.Version + } if specificVersion != "" && internal.Chaos { log.Fatal("cannot use and --chaos together") } diff --git a/cli/app/restart.go b/cli/app/restart.go index 1acf7ca2..bba2983f 100644 --- a/cli/app/restart.go +++ b/cli/app/restart.go @@ -39,6 +39,9 @@ EXAMPLE: BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + if err := app.Recipe.Ensure(false, false); err != nil { + log.Fatal(err) + } serviceName := c.Args().Get(1) if serviceName == "" && !internal.AllServices { diff --git a/cli/app/restore.go b/cli/app/restore.go index b31cc097..8ce54fb8 100644 --- a/cli/app/restore.go +++ b/cli/app/restore.go @@ -31,7 +31,6 @@ var appRestoreCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { log.Fatal(err) } diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 366d3127..8ec65d06 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -86,6 +86,9 @@ EXAMPLE: } specificVersion := c.Args().Get(1) + if specificVersion == "" { + specificVersion = app.Recipe.Version + } if specificVersion != "" { parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) if err != nil { diff --git a/cli/app/secret.go b/cli/app/secret.go index 28554979..a8fe9486 100644 --- a/cli/app/secret.go +++ b/cli/app/secret.go @@ -55,7 +55,6 @@ var appSecretGenerateCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { log.Fatal(err) } @@ -246,27 +245,10 @@ Example: `, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - - if err := app.Recipe.EnsureExists(); err != nil { + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { log.Fatal(err) } - if !internal.Chaos { - if err := app.Recipe.EnsureIsClean(); err != nil { - log.Fatal(err) - } - - if !internal.Offline { - if err := app.Recipe.EnsureUpToDate(); err != nil { - log.Fatal(err) - } - } - - if err := app.Recipe.EnsureLatest(); err != nil { - log.Fatal(err) - } - } - composeFiles, err := app.Recipe.GetComposeFiles(app.Env) if err != nil { log.Fatal(err) @@ -354,27 +336,10 @@ var appSecretLsCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - - if err := app.Recipe.EnsureExists(); err != nil { + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { log.Fatal(err) } - if !internal.Chaos { - if err := app.Recipe.EnsureIsClean(); err != nil { - log.Fatal(err) - } - - if !internal.Offline { - if err := app.Recipe.EnsureUpToDate(); err != nil { - log.Fatal(err) - } - } - - if err := app.Recipe.EnsureLatest(); err != nil { - log.Fatal(err) - } - } - cl, err := client.New(app.Server) if err != nil { log.Fatal(err) diff --git a/cli/app/services.go b/cli/app/services.go index 1986f6e7..97dfda61 100644 --- a/cli/app/services.go +++ b/cli/app/services.go @@ -28,6 +28,9 @@ var appServicesCommand = cli.Command{ BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { + log.Fatal(err) + } cl, err := client.New(app.Server) if err != nil { diff --git a/cli/app/undeploy.go b/cli/app/undeploy.go index 342532a3..5e63d62c 100644 --- a/cli/app/undeploy.go +++ b/cli/app/undeploy.go @@ -81,6 +81,9 @@ any previously attached volumes as eligible for pruning once undeployed. Passing "-p/--prune" does not remove those volumes.`, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { + log.Fatal(err) + } stackName := app.StackName() cl, err := client.New(app.Server) diff --git a/pkg/recipe/git.go b/pkg/recipe/git.go index 775c7491..4978856d 100644 --- a/pkg/recipe/git.go +++ b/pkg/recipe/git.go @@ -21,15 +21,23 @@ func (r Recipe) Ensure(chaos bool, offline bool) error { return err } - if !chaos { - if err := r.EnsureIsClean(); err != nil { + if chaos { + return nil + } + + if err := r.EnsureIsClean(); err != nil { + return err + } + if !offline { + if err := r.EnsureUpToDate(); err != nil { + log.Fatal(err) + } + } + if r.Version != "" { + if _, err := r.EnsureVersion(r.Version); err != nil { return err } - if !offline { - if err := r.EnsureUpToDate(); err != nil { - log.Fatal(err) - } - } + } else { if err := r.EnsureLatest(); err != nil { return err } diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index a68a9c53..df8134f3 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -124,6 +124,13 @@ type Features struct { } func Get(name string) Recipe { + version := "" + if strings.Contains(name, ":") { + split := strings.Split(name, ":") + name = split[0] + version = split[1] + } + gitURL := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, name) sshURL := fmt.Sprintf(config.SSH_URL_TEMPLATE, name) if strings.Contains(name, "/") { @@ -142,10 +149,11 @@ func Get(name string) Recipe { dir := path.Join(config.RECIPES_DIR, escapeRecipeName(name)) return Recipe{ - Name: name, - Dir: dir, - GitURL: gitURL, - SSHURL: sshURL, + Name: name, + Version: version, + Dir: dir, + GitURL: gitURL, + SSHURL: sshURL, ComposePath: path.Join(dir, "compose.yml"), ReadmePath: path.Join(dir, "README.md"), @@ -155,10 +163,11 @@ func Get(name string) Recipe { } type Recipe struct { - Name string - Dir string - GitURL string - SSHURL string + Name string + Version string + Dir string + GitURL string + SSHURL string ComposePath string ReadmePath string diff --git a/pkg/recipe/recipe_test.go b/pkg/recipe/recipe_test.go index 7837cde3..053361df 100644 --- a/pkg/recipe/recipe_test.go +++ b/pkg/recipe/recipe_test.go @@ -29,6 +29,20 @@ func TestGet(t *testing.T) { AbraShPath: path.Join(cfg.GetAbraDir(), "recipes/foo/abra.sh"), }, }, + { + name: "foo:1.2.3", + recipe: Recipe{ + Name: "foo", + Version: "1.2.3", + Dir: path.Join(cfg.GetAbraDir(), "/recipes/foo"), + GitURL: "https://git.coopcloud.tech/coop-cloud/foo.git", + SSHURL: "ssh://git@git.coopcloud.tech:2222/coop-cloud/foo.git", + ComposePath: path.Join(cfg.GetAbraDir(), "recipes/foo/compose.yml"), + ReadmePath: path.Join(cfg.GetAbraDir(), "recipes/foo/README.md"), + SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/foo/.env.sample"), + AbraShPath: path.Join(cfg.GetAbraDir(), "recipes/foo/abra.sh"), + }, + }, { name: "mygit.org/myorg/cool-recipe", recipe: Recipe{ @@ -42,6 +56,20 @@ func TestGet(t *testing.T) { AbraShPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/abra.sh"), }, }, + { + name: "mygit.org/myorg/cool-recipe:1.2.4", + recipe: Recipe{ + Name: "mygit.org/myorg/cool-recipe", + Version: "1.2.4", + Dir: path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"), + GitURL: "https://mygit.org/myorg/cool-recipe.git", + SSHURL: "ssh://git@mygit.org/myorg/cool-recipe.git", + ComposePath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/compose.yml"), + ReadmePath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/README.md"), + SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/.env.sample"), + AbraShPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/abra.sh"), + }, + }, } for _, tc := range testcases {