diff --git a/.drone.yml b/.drone.yml index 601a89f8..17c563ad 100644 --- a/.drone.yml +++ b/.drone.yml @@ -33,7 +33,7 @@ steps: event: tag - name: release - image: goreleaser/goreleaser:v1.19.2 + image: goreleaser/goreleaser:v1.18.2 environment: GITEA_TOKEN: from_secret: goreleaser_gitea_token diff --git a/cli/app/deploy.go b/cli/app/deploy.go index da50050f..44bbfd0c 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -93,6 +93,7 @@ recipes. } } + isLatestHash := false version := deployedVersion if version == "unknown" && !internal.Chaos { catl, err := recipe.ReadRecipeCatalogue(conf) @@ -114,6 +115,7 @@ recipes. if err != nil { logrus.Fatal(err) } + isLatestHash = true version = formatter.SmallSHA(head.String()) logrus.Warn("no versions detected, using latest commit") if err := recipe.EnsureLatest(app.Recipe, conf); err != nil { @@ -129,7 +131,7 @@ recipes. } } - if version != "unknown" && !internal.Chaos { + if version != "unknown" && !internal.Chaos && !isLatestHash { if err := recipe.EnsureVersion(app.Recipe, version); err != nil { logrus.Fatal(err) } diff --git a/cli/app/logs.go b/cli/app/logs.go index 008be8f7..b1cd992c 100644 --- a/cli/app/logs.go +++ b/cli/app/logs.go @@ -84,7 +84,11 @@ var appLogsCommand = cli.Command{ Before: internal.SubCommandBefore, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { - conf := runtime.New(runtime.WithOffline(internal.Offline)) + conf := runtime.New( + runtime.WithOffline(internal.Offline), + runtime.WithEnsureRecipeExists(false), + ) + app := internal.ValidateApp(c, conf) cl, err := client.New(app.Server) diff --git a/cli/app/new.go b/cli/app/new.go index 40927d1f..ac8e194c 100644 --- a/cli/app/new.go +++ b/cli/app/new.go @@ -58,7 +58,11 @@ var appNewCommand = cli.Command{ Before: internal.SubCommandBefore, ArgsUsage: "[]", Action: func(c *cli.Context) error { - conf := runtime.New(runtime.WithOffline(internal.Offline)) + conf := runtime.New( + runtime.WithOffline(internal.Offline), + runtime.WithEnsureRecipeUpToDate(false), + ) + recipe := internal.ValidateRecipeWithPrompt(c, conf) if err := recipePkg.EnsureUpToDate(recipe.Name, conf); err != nil { diff --git a/cli/recipe/release.go b/cli/recipe/release.go index 01c109f1..82d490f4 100644 --- a/cli/recipe/release.go +++ b/cli/recipe/release.go @@ -60,7 +60,11 @@ your SSH keys configured on your account. Before: internal.SubCommandBefore, BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { - conf := runtime.New(runtime.WithOffline(internal.Offline)) + conf := runtime.New( + runtime.WithOffline(internal.Offline), + runtime.WithEnsureRecipeUpToDate(false), + ) + recipe := internal.ValidateRecipeWithPrompt(c, conf) imagesTmp, err := getImageVersions(recipe) diff --git a/cli/recipe/sync.go b/cli/recipe/sync.go index b6576237..39f4189d 100644 --- a/cli/recipe/sync.go +++ b/cli/recipe/sync.go @@ -43,7 +43,11 @@ auto-generate it for you. The configuration will be updated on the local file system. `, Action: func(c *cli.Context) error { - conf := runtime.New(runtime.WithOffline(internal.Offline)) + conf := runtime.New( + runtime.WithOffline(internal.Offline), + runtime.WithEnsureRecipeUpToDate(false), + ) + recipe := internal.ValidateRecipeWithPrompt(c, conf) mainApp, err := internal.GetMainAppImage(recipe) diff --git a/cli/recipe/version.go b/cli/recipe/version.go index b42afb94..4852a93f 100644 --- a/cli/recipe/version.go +++ b/cli/recipe/version.go @@ -22,7 +22,11 @@ var recipeVersionCommand = cli.Command{ Before: internal.SubCommandBefore, BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { - conf := runtime.New(runtime.WithOffline(internal.Offline)) + conf := runtime.New( + runtime.WithOffline(internal.Offline), + runtime.WithEnsureRecipeUpToDate(false), + ) + recipe := internal.ValidateRecipe(c, conf) catalogue, err := recipePkg.ReadRecipeCatalogue(conf) diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index 64ce637b..69c646af 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -236,9 +236,10 @@ func Get(recipeName string, conf *runtime.Config) (Recipe, error) { meta, err := GetRecipeMeta(recipeName, conf) if err != nil { - if strings.Contains(err.Error(), "does not exist") { + switch err.(type) { + case RecipeMissingFromCatalogue: meta = RecipeMeta{} - } else { + default: return Recipe{}, err } } @@ -252,6 +253,11 @@ func Get(recipeName string, conf *runtime.Config) (Recipe, error) { // EnsureExists ensures that a recipe is locally cloned func EnsureExists(recipeName string, conf *runtime.Config) error { + if !conf.RecipeExists { + logrus.Debug("skipping ensuring recipe locally exists") + return nil + } + recipeDir := path.Join(config.RECIPES_DIR, recipeName) if _, err := os.Stat(recipeDir); os.IsNotExist(err) { @@ -339,6 +345,11 @@ func EnsureVersion(recipeName, version string) error { // EnsureLatest makes sure the latest commit is checked out for a local recipe repository func EnsureLatest(recipeName string, conf *runtime.Config) error { + if !conf.RecipeLatest { + logrus.Debug("skipping ensuring recipe is synced with remote") + return nil + } + recipeDir := path.Join(config.RECIPES_DIR, recipeName) isClean, err := gitPkg.IsClean(recipeDir) @@ -368,7 +379,12 @@ func EnsureLatest(recipeName string, conf *runtime.Config) error { meta, err := GetRecipeMeta(recipeName, conf) if err != nil { - return err + switch err.(type) { + case RecipeMissingFromCatalogue: + meta = RecipeMeta{} + default: + return err + } } var branch plumbing.ReferenceName @@ -584,6 +600,11 @@ func GetStringInBetween(recipeName, str, start, end string) (result string, err // EnsureUpToDate ensures that the local repo is synced to the remote func EnsureUpToDate(recipeName string, conf *runtime.Config) error { + if !conf.RecipeLatest { + logrus.Debug("skipping ensuring recipe is synced with remote") + return nil + } + recipeDir := path.Join(config.RECIPES_DIR, recipeName) isClean, err := gitPkg.IsClean(recipeDir) @@ -719,6 +740,14 @@ func VersionsOfService(recipe, serviceName string, conf *runtime.Config) ([]stri return versions, nil } +// RecipeMissingFromCatalogue signifies a recipe is not present in the catalogue. +type RecipeMissingFromCatalogue struct{ err string } + +// Error outputs the error message. +func (r RecipeMissingFromCatalogue) Error() string { + return r.err +} + // GetRecipeMeta retrieves the recipe metadata from the recipe catalogue. func GetRecipeMeta(recipeName string, conf *runtime.Config) (RecipeMeta, error) { catl, err := ReadRecipeCatalogue(conf) @@ -728,7 +757,9 @@ func GetRecipeMeta(recipeName string, conf *runtime.Config) (RecipeMeta, error) recipeMeta, ok := catl[recipeName] if !ok { - return RecipeMeta{}, fmt.Errorf("recipe %s does not exist?", recipeName) + return RecipeMeta{}, RecipeMissingFromCatalogue{ + err: fmt.Sprintf("recipe %s does not exist?", recipeName), + } } if err := EnsureExists(recipeName, conf); err != nil { diff --git a/pkg/runtime/config.go b/pkg/runtime/config.go index d4518203..cd0fa2a9 100644 --- a/pkg/runtime/config.go +++ b/pkg/runtime/config.go @@ -2,14 +2,23 @@ package runtime import "github.com/sirupsen/logrus" +// Config is a runtime behaviour modifier. type Config struct { - Offline bool + Offline bool // Whether or not Abra should prefer local / offline access + RecipeExists bool // Whether or not Abra should ensure the recipe is locally cloned + RecipeLatest bool // Whether or not Abra should ensure the recipe has the latest commit } +// Option is a runtime configuration option. type Option func(c *Config) +// New creates a new runtime configuration. func New(opts ...Option) *Config { - conf := &Config{Offline: false} + conf := &Config{ + Offline: false, + RecipeExists: true, + RecipeLatest: true, + } for _, optFunc := range opts { optFunc(conf) @@ -18,6 +27,8 @@ func New(opts ...Option) *Config { return conf } +// WithOffline ensures Abra attempts to prefer local file system and offline +// access. func WithOffline(offline bool) Option { return func(c *Config) { if offline { @@ -26,3 +37,23 @@ func WithOffline(offline bool) Option { c.Offline = offline } } + +// WithEnsureRecipeExists ensures recipe exists locally. +func WithEnsureRecipeExists(exists bool) Option { + return func(c *Config) { + if exists { + logrus.Debugf("runtime config: ensuring recipe exists") + } + c.RecipeExists = exists + } +} + +// WithEnsureRecipeUpToDate ensures recipe is synced with the remote. +func WithEnsureRecipeUpToDate(upToDate bool) Option { + return func(c *Config) { + if upToDate { + logrus.Debugf("runtime config: ensuring recipe is synced with remote") + } + c.RecipeLatest = upToDate + } +} diff --git a/renovate.json b/renovate.json index c6b1b7ba..bd95ddef 100644 --- a/renovate.json +++ b/renovate.json @@ -8,6 +8,7 @@ "gomodTidy" ], "ignoreDeps": [ - "github.com/urfave/cli" + "github.com/urfave/cli", + "goreleaser/goreleaser" ] } diff --git a/tests/integration/.envrc.sample b/tests/manual/.envrc.sample similarity index 100% rename from tests/integration/.envrc.sample rename to tests/manual/.envrc.sample diff --git a/tests/integration/.gitignore b/tests/manual/.gitignore similarity index 100% rename from tests/integration/.gitignore rename to tests/manual/.gitignore diff --git a/tests/integration/README.md b/tests/manual/README.md similarity index 100% rename from tests/integration/README.md rename to tests/manual/README.md diff --git a/tests/integration/app.sh b/tests/manual/app.sh similarity index 100% rename from tests/integration/app.sh rename to tests/manual/app.sh diff --git a/tests/integration/autocomplete.sh b/tests/manual/autocomplete.sh similarity index 100% rename from tests/integration/autocomplete.sh rename to tests/manual/autocomplete.sh diff --git a/tests/integration/catalogue.sh b/tests/manual/catalogue.sh similarity index 100% rename from tests/integration/catalogue.sh rename to tests/manual/catalogue.sh diff --git a/tests/integration/cmd.sh b/tests/manual/cmd.sh similarity index 100% rename from tests/integration/cmd.sh rename to tests/manual/cmd.sh diff --git a/tests/integration/common.sh b/tests/manual/common.sh similarity index 100% rename from tests/integration/common.sh rename to tests/manual/common.sh diff --git a/tests/integration/install.sh b/tests/manual/install.sh similarity index 100% rename from tests/integration/install.sh rename to tests/manual/install.sh diff --git a/tests/integration/recipe.sh b/tests/manual/recipe.sh similarity index 100% rename from tests/integration/recipe.sh rename to tests/manual/recipe.sh diff --git a/tests/integration/records.sh b/tests/manual/records.sh similarity index 100% rename from tests/integration/records.sh rename to tests/manual/records.sh diff --git a/tests/integration/server.sh b/tests/manual/server.sh similarity index 100% rename from tests/integration/server.sh rename to tests/manual/server.sh diff --git a/tests/integration/test_all.sh b/tests/manual/test_all.sh similarity index 100% rename from tests/integration/test_all.sh rename to tests/manual/test_all.sh diff --git a/tests/integration/testfunctions.sh b/tests/manual/testfunctions.sh similarity index 100% rename from tests/integration/testfunctions.sh rename to tests/manual/testfunctions.sh