refactor: recipe validation
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
317be4cc01
commit
c99f0fc908
@ -9,14 +9,11 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"coopcloud.tech/abra/config"
|
||||
"coopcloud.tech/abra/web"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
)
|
||||
|
||||
// RecipeCatalogueURL is the only current recipe catalogue available.
|
||||
@ -67,62 +64,6 @@ type Recipe struct {
|
||||
Website string `json:"website"`
|
||||
}
|
||||
|
||||
// EnsureExists checks whether a recipe has been cloned locally or not.
|
||||
func (r Recipe) EnsureExists() error {
|
||||
recipeDir := path.Join(config.ABRA_DIR, "apps", strings.ToLower(r.Name))
|
||||
|
||||
if _, err := os.Stat(recipeDir); os.IsNotExist(err) {
|
||||
url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, r.Name)
|
||||
_, err := git.PlainClone(recipeDir, false, &git.CloneOptions{URL: url, Tags: git.AllTags})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureVersion checks whether a specific version exists for a recipe.
|
||||
func (r Recipe) EnsureVersion(version string) error {
|
||||
recipeDir := path.Join(config.ABRA_DIR, "apps", strings.ToLower(r.Name))
|
||||
|
||||
repo, err := git.PlainOpen(recipeDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tags, err := repo.Tags()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tagRef plumbing.ReferenceName
|
||||
if err := tags.ForEach(func(ref *plumbing.Reference) (err error) {
|
||||
if ref.Name().Short() == version {
|
||||
tagRef = ref.Name()
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tagRef.String() == "" {
|
||||
return fmt.Errorf("%s is not available?", version)
|
||||
}
|
||||
|
||||
worktree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts := &git.CheckoutOptions{Branch: tagRef, Keep: true}
|
||||
if err := worktree.Checkout(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LatestVersion returns the latest version of a recipe.
|
||||
func (r Recipe) LatestVersion() string {
|
||||
var latestVersion string
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/config"
|
||||
"coopcloud.tech/abra/recipe"
|
||||
"coopcloud.tech/abra/secret"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -87,15 +88,15 @@ func getRecipe(recipeName string) (catalogue.Recipe, error) {
|
||||
return catalogue.Recipe{}, err
|
||||
}
|
||||
|
||||
recipe, ok := catl[recipeName]
|
||||
rec, ok := catl[recipeName]
|
||||
if !ok {
|
||||
return catalogue.Recipe{}, fmt.Errorf("recipe '%s' does not exist?", recipeName)
|
||||
}
|
||||
if err := recipe.EnsureExists(); err != nil {
|
||||
if err := recipe.EnsureExists(rec.Name); err != nil {
|
||||
return catalogue.Recipe{}, err
|
||||
}
|
||||
|
||||
return recipe, nil
|
||||
return rec, nil
|
||||
}
|
||||
|
||||
// ensureDomainFlag checks if the domain flag was used. if not, asks the user for it/
|
||||
@ -180,12 +181,12 @@ func action(c *cli.Context) error {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
recipe, err := getRecipe(recipeName)
|
||||
rec, err := getRecipe(recipeName)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
latestVersion := recipe.LatestVersion()
|
||||
latestVersion := rec.LatestVersion()
|
||||
if err := recipe.EnsureVersion(latestVersion); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
@ -4,10 +4,6 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Flags
|
||||
|
||||
// AppName stores the variable from AppNameFlag
|
||||
|
||||
// Secrets stores the variable from SecretsFlag
|
||||
var Secrets bool
|
||||
|
||||
@ -43,8 +39,10 @@ var ContextFlag = &cli.StringFlag{
|
||||
Destination: &Context,
|
||||
}
|
||||
|
||||
// Force force functionality without asking.
|
||||
var Force bool
|
||||
|
||||
// ForceFlag turns on/off force functionality.
|
||||
var ForceFlag = &cli.BoolFlag{
|
||||
Name: "force",
|
||||
Value: false,
|
||||
|
@ -7,10 +7,10 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// ShowSubcommandHelpAndError exits the program on error, logs the error to the terminal, and shows the help command.
|
||||
// ShowSubcommandHelpAndError exits the program on error, logs the error to the
|
||||
// terminal, and shows the help command.
|
||||
func ShowSubcommandHelpAndError(c *cli.Context, err interface{}) {
|
||||
if err2 := cli.ShowSubcommandHelp(c); err2 != nil {
|
||||
// go-critic wants me to check this error but if this throws an error while we throw an error that would be annoying
|
||||
logrus.Error(err2)
|
||||
}
|
||||
logrus.Error(err)
|
||||
|
24
cli/internal/validate.go
Normal file
24
cli/internal/validate.go
Normal file
@ -0,0 +1,24 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"coopcloud.tech/abra/recipe"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// ValidateRecipeArg ensures the recipe arg is valid.
|
||||
func ValidateRecipeArg(c *cli.Context) string {
|
||||
recipeName := c.Args().First()
|
||||
|
||||
if recipeName == "" {
|
||||
ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
||||
}
|
||||
|
||||
if err := recipe.EnsureExists(recipeName); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
return recipeName
|
||||
}
|
@ -56,10 +56,7 @@ var recipeVersionCommand = &cli.Command{
|
||||
Aliases: []string{"v"},
|
||||
ArgsUsage: "<recipe>",
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := c.Args().First()
|
||||
if recipe == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
||||
}
|
||||
recipe := internal.ValidateRecipeArg(c)
|
||||
|
||||
catalogue, err := catalogue.ReadRecipeCatalogue()
|
||||
if err != nil {
|
||||
@ -173,10 +170,7 @@ This is step 1 of upgrading a recipe. Step 2 is running "abra recipe sync
|
||||
`,
|
||||
ArgsUsage: "<recipe>",
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := c.Args().First()
|
||||
if recipe == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
||||
}
|
||||
recipe := internal.ValidateRecipeArg(c)
|
||||
|
||||
appFiles, err := config.LoadAppFiles("")
|
||||
if err != nil {
|
||||
@ -304,10 +298,7 @@ the versioning metadata of up-and-running containers are.
|
||||
`,
|
||||
ArgsUsage: "<recipe>",
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := c.Args().First()
|
||||
if recipe == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
||||
}
|
||||
recipe := internal.ValidateRecipeArg(c)
|
||||
|
||||
appFiles, err := config.LoadAppFiles("")
|
||||
if err != nil {
|
||||
@ -363,10 +354,7 @@ var recipeLintCommand = &cli.Command{
|
||||
Aliases: []string{"l"},
|
||||
ArgsUsage: "<recipe>",
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := c.Args().First()
|
||||
if recipe == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
||||
}
|
||||
recipe := internal.ValidateRecipeArg(c)
|
||||
|
||||
pattern := fmt.Sprintf("%s/%s/compose**yml", config.APPS_DIR, recipe)
|
||||
composeFiles, err := filepath.Glob(pattern)
|
||||
|
68
recipe/recipe.go
Normal file
68
recipe/recipe.go
Normal file
@ -0,0 +1,68 @@
|
||||
package recipe
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"coopcloud.tech/abra/config"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
)
|
||||
|
||||
// EnsureExists checks whether a recipe has been cloned locally or not.
|
||||
func EnsureExists(recipe string) error {
|
||||
recipeDir := path.Join(config.ABRA_DIR, "apps", strings.ToLower(recipe))
|
||||
|
||||
if _, err := os.Stat(recipeDir); os.IsNotExist(err) {
|
||||
url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipe)
|
||||
_, err := git.PlainClone(recipeDir, false, &git.CloneOptions{URL: url, Tags: git.AllTags})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureVersion checks whether a specific version exists for a recipe.
|
||||
func EnsureVersion(version string) error {
|
||||
recipeDir := path.Join(config.ABRA_DIR, "apps", strings.ToLower(version))
|
||||
|
||||
repo, err := git.PlainOpen(recipeDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tags, err := repo.Tags()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tagRef plumbing.ReferenceName
|
||||
if err := tags.ForEach(func(ref *plumbing.Reference) (err error) {
|
||||
if ref.Name().Short() == version {
|
||||
tagRef = ref.Name()
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tagRef.String() == "" {
|
||||
return fmt.Errorf("%s is not available?", version)
|
||||
}
|
||||
|
||||
worktree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts := &git.CheckoutOptions{Branch: tagRef, Keep: true}
|
||||
if err := worktree.Checkout(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user