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"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"coopcloud.tech/abra/config"
|
"coopcloud.tech/abra/config"
|
||||||
"coopcloud.tech/abra/web"
|
"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.
|
// RecipeCatalogueURL is the only current recipe catalogue available.
|
||||||
@ -67,62 +64,6 @@ type Recipe struct {
|
|||||||
Website string `json:"website"`
|
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.
|
// LatestVersion returns the latest version of a recipe.
|
||||||
func (r Recipe) LatestVersion() string {
|
func (r Recipe) LatestVersion() string {
|
||||||
var latestVersion string
|
var latestVersion string
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/config"
|
"coopcloud.tech/abra/config"
|
||||||
|
"coopcloud.tech/abra/recipe"
|
||||||
"coopcloud.tech/abra/secret"
|
"coopcloud.tech/abra/secret"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -87,15 +88,15 @@ func getRecipe(recipeName string) (catalogue.Recipe, error) {
|
|||||||
return catalogue.Recipe{}, err
|
return catalogue.Recipe{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
recipe, ok := catl[recipeName]
|
rec, ok := catl[recipeName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return catalogue.Recipe{}, fmt.Errorf("recipe '%s' does not exist?", recipeName)
|
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 catalogue.Recipe{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return recipe, nil
|
return rec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensureDomainFlag checks if the domain flag was used. if not, asks the user for it/
|
// 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)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
recipe, err := getRecipe(recipeName)
|
rec, err := getRecipe(recipeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
latestVersion := recipe.LatestVersion()
|
latestVersion := rec.LatestVersion()
|
||||||
if err := recipe.EnsureVersion(latestVersion); err != nil {
|
if err := recipe.EnsureVersion(latestVersion); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,6 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Flags
|
|
||||||
|
|
||||||
// AppName stores the variable from AppNameFlag
|
|
||||||
|
|
||||||
// Secrets stores the variable from SecretsFlag
|
// Secrets stores the variable from SecretsFlag
|
||||||
var Secrets bool
|
var Secrets bool
|
||||||
|
|
||||||
@ -43,8 +39,10 @@ var ContextFlag = &cli.StringFlag{
|
|||||||
Destination: &Context,
|
Destination: &Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force force functionality without asking.
|
||||||
var Force bool
|
var Force bool
|
||||||
|
|
||||||
|
// ForceFlag turns on/off force functionality.
|
||||||
var ForceFlag = &cli.BoolFlag{
|
var ForceFlag = &cli.BoolFlag{
|
||||||
Name: "force",
|
Name: "force",
|
||||||
Value: false,
|
Value: false,
|
||||||
|
@ -7,10 +7,10 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"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{}) {
|
func ShowSubcommandHelpAndError(c *cli.Context, err interface{}) {
|
||||||
if err2 := cli.ShowSubcommandHelp(c); err2 != nil {
|
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(err2)
|
||||||
}
|
}
|
||||||
logrus.Error(err)
|
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"},
|
Aliases: []string{"v"},
|
||||||
ArgsUsage: "<recipe>",
|
ArgsUsage: "<recipe>",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipe := c.Args().First()
|
recipe := internal.ValidateRecipeArg(c)
|
||||||
if recipe == "" {
|
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
|
||||||
}
|
|
||||||
|
|
||||||
catalogue, err := catalogue.ReadRecipeCatalogue()
|
catalogue, err := catalogue.ReadRecipeCatalogue()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -173,10 +170,7 @@ This is step 1 of upgrading a recipe. Step 2 is running "abra recipe sync
|
|||||||
`,
|
`,
|
||||||
ArgsUsage: "<recipe>",
|
ArgsUsage: "<recipe>",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipe := c.Args().First()
|
recipe := internal.ValidateRecipeArg(c)
|
||||||
if recipe == "" {
|
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
|
||||||
}
|
|
||||||
|
|
||||||
appFiles, err := config.LoadAppFiles("")
|
appFiles, err := config.LoadAppFiles("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -304,10 +298,7 @@ the versioning metadata of up-and-running containers are.
|
|||||||
`,
|
`,
|
||||||
ArgsUsage: "<recipe>",
|
ArgsUsage: "<recipe>",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipe := c.Args().First()
|
recipe := internal.ValidateRecipeArg(c)
|
||||||
if recipe == "" {
|
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
|
||||||
}
|
|
||||||
|
|
||||||
appFiles, err := config.LoadAppFiles("")
|
appFiles, err := config.LoadAppFiles("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -363,10 +354,7 @@ var recipeLintCommand = &cli.Command{
|
|||||||
Aliases: []string{"l"},
|
Aliases: []string{"l"},
|
||||||
ArgsUsage: "<recipe>",
|
ArgsUsage: "<recipe>",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipe := c.Args().First()
|
recipe := internal.ValidateRecipeArg(c)
|
||||||
if recipe == "" {
|
|
||||||
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pattern := fmt.Sprintf("%s/%s/compose**yml", config.APPS_DIR, recipe)
|
pattern := fmt.Sprintf("%s/%s/compose**yml", config.APPS_DIR, recipe)
|
||||||
composeFiles, err := filepath.Glob(pattern)
|
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…
x
Reference in New Issue
Block a user