forked from toolshed/abra
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			private-re
			...
			refactor-r
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 89e1046882 | |||
| cbab9b5907 | |||
| b688ddc4b1 | 
@ -47,22 +47,26 @@ var appBackupListCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -110,22 +114,26 @@ var appBackupDownloadCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -180,22 +188,27 @@ var appBackupCreateCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -238,22 +251,27 @@ var appBackupSnapshotsCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,6 @@ import (
 | 
				
			|||||||
	"coopcloud.tech/abra/pkg/config"
 | 
						"coopcloud.tech/abra/pkg/config"
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/formatter"
 | 
						"coopcloud.tech/abra/pkg/formatter"
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/recipe"
 | 
						"coopcloud.tech/abra/pkg/recipe"
 | 
				
			||||||
	recipePkg "coopcloud.tech/abra/pkg/recipe"
 | 
					 | 
				
			||||||
	"github.com/sirupsen/logrus"
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -38,22 +37,26 @@ ${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipePkg.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipePkg.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipePkg.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,6 @@ import (
 | 
				
			|||||||
	"coopcloud.tech/abra/pkg/client"
 | 
						"coopcloud.tech/abra/pkg/client"
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/config"
 | 
						"coopcloud.tech/abra/pkg/config"
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/recipe"
 | 
						"coopcloud.tech/abra/pkg/recipe"
 | 
				
			||||||
	recipePkg "coopcloud.tech/abra/pkg/recipe"
 | 
					 | 
				
			||||||
	"github.com/sirupsen/logrus"
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -60,22 +59,27 @@ Example:
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipePkg.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipePkg.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipePkg.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -228,22 +232,27 @@ var appCmdListCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipePkg.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipePkg.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipePkg.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -56,28 +56,32 @@ recipes.
 | 
				
			|||||||
			logrus.Fatal("cannot use <version> and --chaos together")
 | 
								logrus.Fatal("cannot use <version> and --chaos together")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		r, err := recipe.Get(app.Recipe, internal.Offline)
 | 
							if err := r.LoadConfig(); err != nil {
 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -105,7 +109,7 @@ recipes.
 | 
				
			|||||||
		if specificVersion != "" {
 | 
							if specificVersion != "" {
 | 
				
			||||||
			version = specificVersion
 | 
								version = specificVersion
 | 
				
			||||||
			logrus.Debugf("choosing %s as version to deploy", version)
 | 
								logrus.Debugf("choosing %s as version to deploy", version)
 | 
				
			||||||
			if err := recipe.EnsureVersion(app.Recipe, version); err != nil {
 | 
								if err := r.EnsureVersion(version); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -141,7 +145,7 @@ recipes.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			if len(versions) == 0 && !internal.Chaos {
 | 
								if len(versions) == 0 && !internal.Chaos {
 | 
				
			||||||
				logrus.Warn("no published versions in catalogue, trying local recipe repository")
 | 
									logrus.Warn("no published versions in catalogue, trying local recipe repository")
 | 
				
			||||||
				recipeVersions, err := recipe.GetRecipeVersions(app.Recipe, internal.Offline)
 | 
									recipeVersions, err := r.GetVersions(internal.Offline)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					logrus.Warn(err)
 | 
										logrus.Warn(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -155,11 +159,11 @@ recipes.
 | 
				
			|||||||
			if len(versions) > 0 && !internal.Chaos {
 | 
								if len(versions) > 0 && !internal.Chaos {
 | 
				
			||||||
				version = versions[len(versions)-1]
 | 
									version = versions[len(versions)-1]
 | 
				
			||||||
				logrus.Debugf("choosing %s as version to deploy", version)
 | 
									logrus.Debugf("choosing %s as version to deploy", version)
 | 
				
			||||||
				if err := recipe.EnsureVersion(app.Recipe, version); err != nil {
 | 
									if err := r.EnsureVersion(version); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				head, err := git.GetRecipeHead(app.Recipe)
 | 
									head, err := git.GetHead(app.Recipe)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -171,7 +175,7 @@ recipes.
 | 
				
			|||||||
		if internal.Chaos {
 | 
							if internal.Chaos {
 | 
				
			||||||
			logrus.Warnf("chaos mode engaged")
 | 
								logrus.Warnf("chaos mode engaged")
 | 
				
			||||||
			var err error
 | 
								var err error
 | 
				
			||||||
			version, err = recipe.ChaosVersion(app.Recipe)
 | 
								version, err = r.ChaosVersion()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -88,12 +88,15 @@ the logs.
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App) error {
 | 
					func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App) error {
 | 
				
			||||||
	recipe, err := recipe.Get(app.Recipe, internal.Offline)
 | 
						r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logrus.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := r.LoadConfig(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, service := range recipe.Config.Services {
 | 
						for _, service := range r.Config.Services {
 | 
				
			||||||
		filters := filters.NewArgs()
 | 
							filters := filters.NewArgs()
 | 
				
			||||||
		filters.Add("name", fmt.Sprintf("^%s_%s", app.StackName(), service.Name))
 | 
							filters.Add("name", fmt.Sprintf("^%s_%s", app.StackName(), service.Name))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,12 @@ var appLogsCommand = cli.Command{
 | 
				
			|||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
		stackName := app.StackName()
 | 
							stackName := app.StackName()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,6 @@ import (
 | 
				
			|||||||
	"coopcloud.tech/abra/pkg/config"
 | 
						"coopcloud.tech/abra/pkg/config"
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/formatter"
 | 
						"coopcloud.tech/abra/pkg/formatter"
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/jsontable"
 | 
						"coopcloud.tech/abra/pkg/jsontable"
 | 
				
			||||||
	recipePkg "coopcloud.tech/abra/pkg/recipe"
 | 
					 | 
				
			||||||
	"coopcloud.tech/abra/pkg/secret"
 | 
						"coopcloud.tech/abra/pkg/secret"
 | 
				
			||||||
	"github.com/AlecAivazis/survey/v2"
 | 
						"github.com/AlecAivazis/survey/v2"
 | 
				
			||||||
	dockerClient "github.com/docker/docker/client"
 | 
						dockerClient "github.com/docker/docker/client"
 | 
				
			||||||
@ -65,21 +64,21 @@ var appNewCommand = cli.Command{
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		recipe := internal.ValidateRecipe(c)
 | 
							r := internal.ValidateRecipe(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipePkg.EnsureIsClean(recipe.Name); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if c.Args().Get(1) == "" {
 | 
								if c.Args().Get(1) == "" {
 | 
				
			||||||
				var version string
 | 
									var version string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				recipeVersions, err := recipePkg.GetRecipeVersions(recipe.Name, internal.Offline)
 | 
									recipeVersions, err := r.GetVersions(internal.Offline)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -92,16 +91,16 @@ var appNewCommand = cli.Command{
 | 
				
			|||||||
						version = tag
 | 
											version = tag
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if err := recipePkg.EnsureVersion(recipe.Name, version); err != nil {
 | 
										if err := r.EnsureVersion(version); err != nil {
 | 
				
			||||||
						logrus.Fatal(err)
 | 
											logrus.Fatal(err)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					if err := recipePkg.EnsureLatest(recipe.Name); err != nil {
 | 
										if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
						logrus.Fatal(err)
 | 
											logrus.Fatal(err)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if err := recipePkg.EnsureVersion(recipe.Name, c.Args().Get(1)); err != nil {
 | 
									if err := r.EnsureVersion(c.Args().Get(1)); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -111,7 +110,7 @@ var appNewCommand = cli.Command{
 | 
				
			|||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := ensureDomainFlag(recipe, internal.NewAppServer); err != nil {
 | 
							if err := ensureDomainFlag(r.Name, internal.NewAppServer); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -119,7 +118,7 @@ var appNewCommand = cli.Command{
 | 
				
			|||||||
		logrus.Debugf("%s sanitised as %s for new app", internal.Domain, sanitisedAppName)
 | 
							logrus.Debugf("%s sanitised as %s for new app", internal.Domain, sanitisedAppName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := config.TemplateAppEnvSample(
 | 
							if err := config.TemplateAppEnvSample(
 | 
				
			||||||
			recipe.Name,
 | 
								r.Name,
 | 
				
			||||||
			internal.Domain,
 | 
								internal.Domain,
 | 
				
			||||||
			internal.NewAppServer,
 | 
								internal.NewAppServer,
 | 
				
			||||||
			internal.Domain,
 | 
								internal.Domain,
 | 
				
			||||||
@ -130,23 +129,23 @@ var appNewCommand = cli.Command{
 | 
				
			|||||||
		var secrets AppSecrets
 | 
							var secrets AppSecrets
 | 
				
			||||||
		var secretTable *jsontable.JSONTable
 | 
							var secretTable *jsontable.JSONTable
 | 
				
			||||||
		if internal.Secrets {
 | 
							if internal.Secrets {
 | 
				
			||||||
			sampleEnv, err := recipe.SampleEnv()
 | 
								sampleEnv, err := r.SampleEnv()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			composeFiles, err := config.GetComposeFiles(recipe.Name, sampleEnv)
 | 
								composeFiles, err := config.GetComposeFiles(r.NameEscaped, sampleEnv)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			envSamplePath := path.Join(config.RECIPES_DIR, recipe.Name, ".env.sample")
 | 
								envSamplePath := path.Join(r.Dir, ".env.sample")
 | 
				
			||||||
			secretsConfig, err := secret.ReadSecretsConfig(envSamplePath, composeFiles, config.StackName(internal.Domain))
 | 
								secretsConfig, err := secret.ReadSecretsConfig(envSamplePath, composeFiles, config.StackName(internal.Domain))
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := promptForSecrets(recipe.Name, secretsConfig); err != nil {
 | 
								if err := promptForSecrets(r.Name, secretsConfig); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -173,9 +172,9 @@ var appNewCommand = cli.Command{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		tableCol := []string{"server", "recipe", "domain"}
 | 
							tableCol := []string{"server", "recipe", "domain"}
 | 
				
			||||||
		table := formatter.CreateTable(tableCol)
 | 
							table := formatter.CreateTable(tableCol)
 | 
				
			||||||
		table.Append([]string{internal.NewAppServer, recipe.Name, internal.Domain})
 | 
							table.Append([]string{internal.NewAppServer, r.Name, internal.Domain})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fmt.Println(fmt.Sprintf("A new %s app has been created! Here is an overview:", recipe.Name))
 | 
							fmt.Println(fmt.Sprintf("A new %s app has been created! Here is an overview:", r.Name))
 | 
				
			||||||
		fmt.Println("")
 | 
							fmt.Println("")
 | 
				
			||||||
		table.Render()
 | 
							table.Render()
 | 
				
			||||||
		fmt.Println("")
 | 
							fmt.Println("")
 | 
				
			||||||
@ -231,11 +230,11 @@ func createSecrets(cl *dockerClient.Client, secretsConfig map[string]secret.Secr
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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/
 | 
				
			||||||
func ensureDomainFlag(recipe recipePkg.Recipe, server string) error {
 | 
					func ensureDomainFlag(recipeName string, server string) error {
 | 
				
			||||||
	if internal.Domain == "" && !internal.NoInput {
 | 
						if internal.Domain == "" && !internal.NoInput {
 | 
				
			||||||
		prompt := &survey.Input{
 | 
							prompt := &survey.Input{
 | 
				
			||||||
			Message: "Specify app domain",
 | 
								Message: "Specify app domain",
 | 
				
			||||||
			Default: fmt.Sprintf("%s.%s", recipe.Name, server),
 | 
								Default: fmt.Sprintf("%s.%s", recipeName, server),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := survey.AskOne(prompt, &internal.Domain); err != nil {
 | 
							if err := survey.AskOne(prompt, &internal.Domain); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,11 @@ var appPsCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cl, err := client.New(app.Server)
 | 
							cl, err := client.New(app.Server)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
@ -56,7 +61,7 @@ var appPsCommand = cli.Command{
 | 
				
			|||||||
		statuses, err := config.GetAppStatuses([]config.App{app}, true)
 | 
							statuses, err := config.GetAppStatuses([]config.App{app}, true)
 | 
				
			||||||
		if statusMeta, ok := statuses[app.StackName()]; ok {
 | 
							if statusMeta, ok := statuses[app.StackName()]; ok {
 | 
				
			||||||
			if _, exists := statusMeta["chaos"]; !exists {
 | 
								if _, exists := statusMeta["chaos"]; !exists {
 | 
				
			||||||
				if err := recipe.EnsureVersion(app.Recipe, deployedVersion); err != nil {
 | 
									if err := r.EnsureVersion(deployedVersion); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,22 +33,27 @@ var appRestoreCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -51,33 +51,37 @@ recipes.
 | 
				
			|||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
		stackName := app.StackName()
 | 
							stackName := app.StackName()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		specificVersion := c.Args().Get(1)
 | 
							specificVersion := c.Args().Get(1)
 | 
				
			||||||
		if specificVersion != "" && internal.Chaos {
 | 
							if specificVersion != "" && internal.Chaos {
 | 
				
			||||||
			logrus.Fatal("cannot use <version> and --chaos together")
 | 
								logrus.Fatal("cannot use <version> and --chaos together")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		r, err := recipe.Get(app.Recipe, internal.Offline)
 | 
							if err := r.LoadConfig(); err != nil {
 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -113,7 +117,7 @@ recipes.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if len(versions) == 0 && !internal.Chaos {
 | 
							if len(versions) == 0 && !internal.Chaos {
 | 
				
			||||||
			logrus.Warn("no published versions in catalogue, trying local recipe repository")
 | 
								logrus.Warn("no published versions in catalogue, trying local recipe repository")
 | 
				
			||||||
			recipeVersions, err := recipe.GetRecipeVersions(app.Recipe, internal.Offline)
 | 
								recipeVersions, err := r.GetVersions(internal.Offline)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Warn(err)
 | 
									logrus.Warn(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -183,7 +187,7 @@ recipes.
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureVersion(app.Recipe, chosenDowngrade); err != nil {
 | 
								if err := r.EnsureVersion(chosenDowngrade); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -191,13 +195,13 @@ recipes.
 | 
				
			|||||||
		if internal.Chaos {
 | 
							if internal.Chaos {
 | 
				
			||||||
			logrus.Warn("chaos mode engaged")
 | 
								logrus.Warn("chaos mode engaged")
 | 
				
			||||||
			var err error
 | 
								var err error
 | 
				
			||||||
			chosenDowngrade, err = recipe.ChaosVersion(app.Recipe)
 | 
								chosenDowngrade, err = r.ChaosVersion()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		abraShPath := fmt.Sprintf("%s/%s/%s", config.RECIPES_DIR, app.Recipe, "abra.sh")
 | 
							abraShPath := fmt.Sprintf("%s/%s/%s", r.Dir, "abra.sh")
 | 
				
			||||||
		abraShEnv, err := config.ReadAbraShEnvVars(abraShPath)
 | 
							abraShEnv, err := config.ReadAbraShEnvVars(abraShPath)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
				
			|||||||
@ -57,22 +57,27 @@ var appSecretGenerateCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -264,22 +269,27 @@ Example:
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -372,22 +382,27 @@ var appSecretLsCommand = cli.Command{
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipe.EnsureExists(app.Recipe); err != nil {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -62,28 +62,32 @@ recipes.
 | 
				
			|||||||
			logrus.Fatal("cannot use <version> and --chaos together")
 | 
								logrus.Fatal("cannot use <version> and --chaos together")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
 | 
					 | 
				
			||||||
				logrus.Fatal(err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if !internal.Offline {
 | 
					 | 
				
			||||||
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
 | 
					 | 
				
			||||||
					logrus.Fatal(err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if err := recipe.EnsureLatest(app.Recipe); err != nil {
 | 
					 | 
				
			||||||
				logrus.Fatal(err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		recipe, err := recipePkg.Get(app.Recipe, internal.Offline)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := lint.LintForErrors(recipe); err != nil {
 | 
							if !internal.Chaos {
 | 
				
			||||||
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
 | 
									logrus.Fatal(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if !internal.Offline {
 | 
				
			||||||
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
 | 
										logrus.Fatal(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
 | 
									logrus.Fatal(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := r.LoadConfig(); err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := lint.LintForErrors(r); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -115,7 +119,7 @@ recipes.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if len(versions) == 0 && !internal.Chaos {
 | 
							if len(versions) == 0 && !internal.Chaos {
 | 
				
			||||||
			logrus.Warn("no published versions in catalogue, trying local recipe repository")
 | 
								logrus.Warn("no published versions in catalogue, trying local recipe repository")
 | 
				
			||||||
			recipeVersions, err := recipePkg.GetRecipeVersions(app.Recipe, internal.Offline)
 | 
								recipeVersions, err := r.GetVersions(internal.Offline)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Warn(err)
 | 
									logrus.Warn(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -217,7 +221,7 @@ recipes.
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipePkg.EnsureVersion(app.Recipe, chosenUpgrade); err != nil {
 | 
								if err := r.EnsureVersion(chosenUpgrade); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -225,13 +229,13 @@ recipes.
 | 
				
			|||||||
		if internal.Chaos {
 | 
							if internal.Chaos {
 | 
				
			||||||
			logrus.Warn("chaos mode engaged")
 | 
								logrus.Warn("chaos mode engaged")
 | 
				
			||||||
			var err error
 | 
								var err error
 | 
				
			||||||
			chosenUpgrade, err = recipePkg.ChaosVersion(app.Recipe)
 | 
								chosenUpgrade, err = r.ChaosVersion()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		abraShPath := fmt.Sprintf("%s/%s/%s", config.RECIPES_DIR, app.Recipe, "abra.sh")
 | 
							abraShPath := fmt.Sprintf("%s/%s/%s", r.Dir, "abra.sh")
 | 
				
			||||||
		abraShEnv, err := config.ReadAbraShEnvVars(abraShPath)
 | 
							abraShEnv, err := config.ReadAbraShEnvVars(abraShPath)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
				
			|||||||
@ -58,6 +58,11 @@ var appVersionCommand = cli.Command{
 | 
				
			|||||||
		app := internal.ValidateApp(c)
 | 
							app := internal.ValidateApp(c)
 | 
				
			||||||
		stackName := app.StackName()
 | 
							stackName := app.StackName()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r, err := recipe.Get(app.Recipe)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cl, err := client.New(app.Server)
 | 
							cl, err := client.New(app.Server)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
@ -78,7 +83,7 @@ var appVersionCommand = cli.Command{
 | 
				
			|||||||
			logrus.Fatalf("failed to determine version of deployed %s", app.Name)
 | 
								logrus.Fatalf("failed to determine version of deployed %s", app.Name)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		recipeMeta, err := recipe.GetRecipeMeta(app.Recipe, internal.Offline)
 | 
							recipeMeta, err := r.GetRecipeMeta(internal.Offline)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"coopcloud.tech/abra/cli/internal"
 | 
						"coopcloud.tech/abra/cli/internal"
 | 
				
			||||||
@ -57,9 +58,10 @@ keys configured on your account.
 | 
				
			|||||||
	BashComplete: autocomplete.RecipeNameComplete,
 | 
						BashComplete: autocomplete.RecipeNameComplete,
 | 
				
			||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		recipeName := c.Args().First()
 | 
							recipeName := c.Args().First()
 | 
				
			||||||
 | 
							r := recipe.Recipe{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if recipeName != "" {
 | 
							if recipeName != "" {
 | 
				
			||||||
			internal.ValidateRecipe(c)
 | 
								r = internal.ValidateRecipe(c)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
@ -98,12 +100,12 @@ keys configured on your account.
 | 
				
			|||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			versions, err := recipe.GetRecipeVersions(recipeMeta.Name, internal.Offline)
 | 
								versions, err := r.GetVersions(internal.Offline)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Warn(err)
 | 
									logrus.Warn(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			features, category, err := recipe.GetRecipeFeaturesAndCategory(recipeMeta.Name)
 | 
								features, category, err := r.GetRecipeFeaturesAndCategory()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logrus.Warn(err)
 | 
									logrus.Warn(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -130,7 +132,7 @@ keys configured on your account.
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if recipeName == "" {
 | 
							if recipeName == "" {
 | 
				
			||||||
			if err := ioutil.WriteFile(config.RECIPES_JSON, recipesJSON, 0764); err != nil {
 | 
								if err := os.WriteFile(config.RECIPES_JSON, recipesJSON, 0764); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
 | 
				
			|||||||
@ -57,7 +57,10 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe {
 | 
				
			|||||||
		ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
 | 
							ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chosenRecipe, err := recipe.Get(recipeName, Offline)
 | 
						r, err := recipe.Get(recipeName)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logrus.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if c.Command.Name == "generate" {
 | 
							if c.Command.Name == "generate" {
 | 
				
			||||||
			if strings.Contains(err.Error(), "missing a compose") {
 | 
								if strings.Contains(err.Error(), "missing a compose") {
 | 
				
			||||||
@ -74,7 +77,7 @@ func ValidateRecipe(c *cli.Context) recipe.Recipe {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	logrus.Debugf("validated %s as recipe argument", recipeName)
 | 
						logrus.Debugf("validated %s as recipe argument", recipeName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return chosenRecipe
 | 
						return r
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ValidateApp ensures the app name arg is valid.
 | 
					// ValidateApp ensures the app name arg is valid.
 | 
				
			||||||
 | 
				
			|||||||
@ -24,9 +24,14 @@ var recipeFetchCommand = cli.Command{
 | 
				
			|||||||
	BashComplete: autocomplete.RecipeNameComplete,
 | 
						BashComplete: autocomplete.RecipeNameComplete,
 | 
				
			||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		recipeName := c.Args().First()
 | 
							recipeName := c.Args().First()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if recipeName != "" {
 | 
							if recipeName != "" {
 | 
				
			||||||
			internal.ValidateRecipe(c)
 | 
								internal.ValidateRecipe(c)
 | 
				
			||||||
			if err := recipe.Ensure(recipeName); err != nil {
 | 
								r, err := recipe.Get(recipeName)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									logrus.Fatal(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := r.Ensure(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
@ -39,7 +44,11 @@ var recipeFetchCommand = cli.Command{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		catlBar := formatter.CreateProgressbar(len(catalogue), "fetching latest recipes...")
 | 
							catlBar := formatter.CreateProgressbar(len(catalogue), "fetching latest recipes...")
 | 
				
			||||||
		for recipeName := range catalogue {
 | 
							for recipeName := range catalogue {
 | 
				
			||||||
			if err := recipe.Ensure(recipeName); err != nil {
 | 
								r, err := recipe.Get(recipeName)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									logrus.Fatal(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := r.Ensure(); err != nil {
 | 
				
			||||||
				logrus.Error(err)
 | 
									logrus.Error(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			catlBar.Add(1)
 | 
								catlBar.Add(1)
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,6 @@ import (
 | 
				
			|||||||
	"coopcloud.tech/abra/pkg/autocomplete"
 | 
						"coopcloud.tech/abra/pkg/autocomplete"
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/formatter"
 | 
						"coopcloud.tech/abra/pkg/formatter"
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/lint"
 | 
						"coopcloud.tech/abra/pkg/lint"
 | 
				
			||||||
	recipePkg "coopcloud.tech/abra/pkg/recipe"
 | 
					 | 
				
			||||||
	"github.com/sirupsen/logrus"
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -27,24 +26,27 @@ var recipeLintCommand = cli.Command{
 | 
				
			|||||||
	Before:       internal.SubCommandBefore,
 | 
						Before:       internal.SubCommandBefore,
 | 
				
			||||||
	BashComplete: autocomplete.RecipeNameComplete,
 | 
						BashComplete: autocomplete.RecipeNameComplete,
 | 
				
			||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		recipe := internal.ValidateRecipe(c)
 | 
							r := internal.ValidateRecipe(c)
 | 
				
			||||||
 | 
							if err := r.LoadConfig(); err != nil {
 | 
				
			||||||
 | 
								logrus.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipePkg.EnsureExists(recipe.Name); err != nil {
 | 
							if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !internal.Chaos {
 | 
							if !internal.Chaos {
 | 
				
			||||||
			if err := recipePkg.EnsureIsClean(recipe.Name); err != nil {
 | 
								if err := r.EnsureIsClean(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if !internal.Offline {
 | 
								if !internal.Offline {
 | 
				
			||||||
				if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
 | 
									if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
					logrus.Fatal(err)
 | 
										logrus.Fatal(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := recipePkg.EnsureLatest(recipe.Name); err != nil {
 | 
								if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -62,7 +64,7 @@ var recipeLintCommand = cli.Command{
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				skipped := false
 | 
									skipped := false
 | 
				
			||||||
				if rule.Skip(recipe) {
 | 
									if rule.Skip(r) {
 | 
				
			||||||
					skipped = true
 | 
										skipped = true
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -73,7 +75,7 @@ var recipeLintCommand = cli.Command{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				satisfied := false
 | 
									satisfied := false
 | 
				
			||||||
				if !skipped {
 | 
									if !skipped {
 | 
				
			||||||
					ok, err := rule.Function(recipe)
 | 
										ok, err := rule.Function(r)
 | 
				
			||||||
					if err != nil {
 | 
										if err != nil {
 | 
				
			||||||
						logrus.Warn(err)
 | 
											logrus.Warn(err)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
				
			|||||||
@ -108,14 +108,14 @@ your SSH keys configured on your account.
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		isClean, err := gitPkg.IsClean(recipe.Dir())
 | 
							isClean, err := gitPkg.IsClean(recipe.Dir)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !isClean {
 | 
							if !isClean {
 | 
				
			||||||
			logrus.Infof("%s currently has these unstaged changes 👇", recipe.Name)
 | 
								logrus.Infof("%s currently has these unstaged changes 👇", recipe.Name)
 | 
				
			||||||
			if err := gitPkg.DiffUnstaged(recipe.Dir()); err != nil {
 | 
								if err := gitPkg.DiffUnstaged(recipe.Dir); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -184,7 +184,7 @@ func getImageVersions(recipe recipe.Recipe) (map[string]string, error) {
 | 
				
			|||||||
func createReleaseFromTag(recipe recipe.Recipe, tagString, mainAppVersion string) error {
 | 
					func createReleaseFromTag(recipe recipe.Recipe, tagString, mainAppVersion string) error {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	directory := path.Join(config.RECIPES_DIR, recipe.Name)
 | 
						directory := path.Join(recipe.Dir)
 | 
				
			||||||
	repo, err := git.PlainOpen(directory)
 | 
						repo, err := git.PlainOpen(directory)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@ -246,8 +246,7 @@ func getTagCreateOptions(tag string) (git.CreateTagOptions, error) {
 | 
				
			|||||||
// addReleaseNotes checks if the release/next release note exists and moves the
 | 
					// addReleaseNotes checks if the release/next release note exists and moves the
 | 
				
			||||||
// file to release/<tag>.
 | 
					// file to release/<tag>.
 | 
				
			||||||
func addReleaseNotes(recipe recipe.Recipe, tag string) error {
 | 
					func addReleaseNotes(recipe recipe.Recipe, tag string) error {
 | 
				
			||||||
	repoPath := path.Join(config.RECIPES_DIR, recipe.Name)
 | 
						tagReleaseNotePath := path.Join(recipe.Dir, "release", tag)
 | 
				
			||||||
	tagReleaseNotePath := path.Join(repoPath, "release", tag)
 | 
					 | 
				
			||||||
	if _, err := os.Stat(tagReleaseNotePath); err == nil {
 | 
						if _, err := os.Stat(tagReleaseNotePath); err == nil {
 | 
				
			||||||
		// Release note for current tag already exist exists.
 | 
							// Release note for current tag already exist exists.
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
@ -255,7 +254,7 @@ func addReleaseNotes(recipe recipe.Recipe, tag string) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nextReleaseNotePath := path.Join(repoPath, "release", "next")
 | 
						nextReleaseNotePath := path.Join(recipe.Dir, "release", "next")
 | 
				
			||||||
	if _, err := os.Stat(nextReleaseNotePath); err == nil {
 | 
						if _, err := os.Stat(nextReleaseNotePath); err == nil {
 | 
				
			||||||
		// release/next note exists. Move it to release/<tag>
 | 
							// release/next note exists. Move it to release/<tag>
 | 
				
			||||||
		if internal.Dry {
 | 
							if internal.Dry {
 | 
				
			||||||
@ -278,11 +277,11 @@ func addReleaseNotes(recipe recipe.Recipe, tag string) error {
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		err = gitPkg.Add(repoPath, path.Join("release", "next"), internal.Dry)
 | 
							err = gitPkg.Add(recipe.Dir, path.Join("release", "next"), internal.Dry)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		err = gitPkg.Add(repoPath, path.Join("release", tag), internal.Dry)
 | 
							err = gitPkg.Add(recipe.Dir, path.Join("release", tag), internal.Dry)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -311,7 +310,7 @@ func addReleaseNotes(recipe recipe.Recipe, tag string) error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = gitPkg.Add(repoPath, path.Join("release", tag), internal.Dry)
 | 
						err = gitPkg.Add(recipe.Dir, path.Join("release", tag), internal.Dry)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -325,14 +324,14 @@ func commitRelease(recipe recipe.Recipe, tag string) error {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	isClean, err := gitPkg.IsClean(recipe.Dir())
 | 
						isClean, err := gitPkg.IsClean(recipe.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if isClean {
 | 
						if isClean {
 | 
				
			||||||
		if !internal.Dry {
 | 
							if !internal.Dry {
 | 
				
			||||||
			return fmt.Errorf("no changes discovered in %s, nothing to publish?", recipe.Dir())
 | 
								return fmt.Errorf("no changes discovered in %s, nothing to publish?", recipe.Dir)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -402,8 +401,7 @@ func pushRelease(recipe recipe.Recipe, tagString string) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func createReleaseFromPreviousTag(tagString, mainAppVersion string, recipe recipe.Recipe, tags []string) error {
 | 
					func createReleaseFromPreviousTag(tagString, mainAppVersion string, recipe recipe.Recipe, tags []string) error {
 | 
				
			||||||
	directory := path.Join(config.RECIPES_DIR, recipe.Name)
 | 
						repo, err := git.PlainOpen(recipe.Dir)
 | 
				
			||||||
	repo, err := git.PlainOpen(directory)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -199,13 +199,13 @@ likely to change.
 | 
				
			|||||||
			logrus.Infof("dry run: not syncing label %s for recipe %s", nextTag, recipe.Name)
 | 
								logrus.Infof("dry run: not syncing label %s for recipe %s", nextTag, recipe.Name)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		isClean, err := gitPkg.IsClean(recipe.Dir())
 | 
							isClean, err := gitPkg.IsClean(recipe.Dir)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if !isClean {
 | 
							if !isClean {
 | 
				
			||||||
			logrus.Infof("%s currently has these unstaged changes 👇", recipe.Name)
 | 
								logrus.Infof("%s currently has these unstaged changes 👇", recipe.Name)
 | 
				
			||||||
			if err := gitPkg.DiffUnstaged(recipe.Dir()); err != nil {
 | 
								if err := gitPkg.DiffUnstaged(recipe.Dir); err != nil {
 | 
				
			||||||
				logrus.Fatal(err)
 | 
									logrus.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -73,19 +73,19 @@ You may invoke this command in "wizard" mode and be prompted for input:
 | 
				
			|||||||
	Action: func(c *cli.Context) error {
 | 
						Action: func(c *cli.Context) error {
 | 
				
			||||||
		recipe := internal.ValidateRecipe(c)
 | 
							recipe := internal.ValidateRecipe(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipePkg.EnsureIsClean(recipe.Name); err != nil {
 | 
							if err := recipe.EnsureIsClean(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipePkg.EnsureExists(recipe.Name); err != nil {
 | 
							if err := recipe.EnsureExists(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
 | 
							if err := recipe.EnsureUpToDate(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := recipePkg.EnsureLatest(recipe.Name); err != nil {
 | 
							if err := recipe.EnsureLatest(); err != nil {
 | 
				
			||||||
			logrus.Fatal(err)
 | 
								logrus.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -316,22 +316,23 @@ func getAvailableUpgrades(cl *dockerclient.Client, stackName string, recipeName
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// processRecipeRepoVersion clones, pulls, checks out the version and lints the
 | 
					// processRecipeRepoVersion clones, pulls, checks out the version and lints the
 | 
				
			||||||
// recipe repository.
 | 
					// recipe repository.
 | 
				
			||||||
func processRecipeRepoVersion(recipeName, version string) error {
 | 
					func processRecipeRepoVersion(recipe recipe.Recipe, version string) error {
 | 
				
			||||||
	if err := recipe.EnsureExists(recipeName); err != nil {
 | 
						if err := recipe.EnsureExists(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := recipe.EnsureUpToDate(recipeName); err != nil {
 | 
						if err := recipe.EnsureUpToDate(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := recipe.EnsureVersion(recipeName, version); err != nil {
 | 
						if err := recipe.EnsureVersion(version); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if r, err := recipe.Get(recipeName, internal.Offline); err != nil {
 | 
						if err := recipe.LoadConfig(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	} else if err := lint.LintForErrors(r); err != nil {
 | 
						}
 | 
				
			||||||
 | 
						if err := lint.LintForErrors(recipe); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -442,7 +443,12 @@ func upgrade(cl *dockerclient.Client, stackName, recipeName,
 | 
				
			|||||||
		Env:    env,
 | 
							Env:    env,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = processRecipeRepoVersion(recipeName, upgradeVersion); err != nil {
 | 
						recipe, err := recipe.Get(recipeName)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err = processRecipeRepoVersion(recipe, upgradeVersion); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,7 @@ func TestGetApp(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetComposeFiles(t *testing.T) {
 | 
					func TestGetComposeFiles(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	r, err := recipe.Get("abra-test-recipe", offline)
 | 
						r, err := recipe.Get2("abra-test-recipe", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -92,7 +92,7 @@ func TestGetComposeFiles(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetComposeFilesError(t *testing.T) {
 | 
					func TestGetComposeFilesError(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	r, err := recipe.Get("abra-test-recipe", offline)
 | 
						r, err := recipe.Get2("abra-test-recipe", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -94,7 +94,7 @@ func TestReadEnv(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestReadAbraShEnvVars(t *testing.T) {
 | 
					func TestReadAbraShEnvVars(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	r, err := recipe.Get("abra-test-recipe", offline)
 | 
						r, err := recipe.Get2("abra-test-recipe", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -124,7 +124,7 @@ func TestReadAbraShEnvVars(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestReadAbraShCmdNames(t *testing.T) {
 | 
					func TestReadAbraShCmdNames(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	r, err := recipe.Get("abra-test-recipe", offline)
 | 
						r, err := recipe.Get2("abra-test-recipe", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -149,7 +149,7 @@ func TestReadAbraShCmdNames(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestCheckEnv(t *testing.T) {
 | 
					func TestCheckEnv(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	r, err := recipe.Get("abra-test-recipe", offline)
 | 
						r, err := recipe.Get2("abra-test-recipe", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -183,7 +183,7 @@ func TestCheckEnv(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestCheckEnvError(t *testing.T) {
 | 
					func TestCheckEnvError(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	r, err := recipe.Get("abra-test-recipe", offline)
 | 
						r, err := recipe.Get2("abra-test-recipe", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -219,7 +219,7 @@ func TestCheckEnvError(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestEnvVarCommentsRemoved(t *testing.T) {
 | 
					func TestEnvVarCommentsRemoved(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	r, err := recipe.Get("abra-test-recipe", offline)
 | 
						r, err := recipe.Get2("abra-test-recipe", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -251,7 +251,7 @@ func TestEnvVarCommentsRemoved(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestEnvVarModifiersIncluded(t *testing.T) {
 | 
					func TestEnvVarModifiersIncluded(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	r, err := recipe.Get("abra-test-recipe", offline)
 | 
						r, err := recipe.Get2("abra-test-recipe", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,11 +4,9 @@ import (
 | 
				
			|||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/user"
 | 
						"os/user"
 | 
				
			||||||
	"path"
 | 
					 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"coopcloud.tech/abra/pkg/config"
 | 
					 | 
				
			||||||
	"github.com/go-git/go-git/v5"
 | 
						"github.com/go-git/go-git/v5"
 | 
				
			||||||
	gitConfigPkg "github.com/go-git/go-git/v5/config"
 | 
						gitConfigPkg "github.com/go-git/go-git/v5/config"
 | 
				
			||||||
	"github.com/go-git/go-git/v5/plumbing"
 | 
						"github.com/go-git/go-git/v5/plumbing"
 | 
				
			||||||
@ -16,11 +14,9 @@ import (
 | 
				
			|||||||
	"github.com/sirupsen/logrus"
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetRecipeHead retrieves latest HEAD metadata.
 | 
					// GetHead retrieves latest HEAD metadata.
 | 
				
			||||||
func GetRecipeHead(recipeName string) (*plumbing.Reference, error) {
 | 
					func GetHead(dir string) (*plumbing.Reference, error) {
 | 
				
			||||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
						repo, err := git.PlainOpen(dir)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	repo, err := git.PlainOpen(recipeDir)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -210,7 +210,7 @@ func LintComposeVersion(recipe recipe.Recipe) (bool, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LintEnvConfigPresent(recipe recipe.Recipe) (bool, error) {
 | 
					func LintEnvConfigPresent(recipe recipe.Recipe) (bool, error) {
 | 
				
			||||||
	envSample := fmt.Sprintf("%s/%s/.env.sample", config.RECIPES_DIR, recipe.Name)
 | 
						envSample := fmt.Sprintf("%s/%s/.env.sample", recipe.Dir)
 | 
				
			||||||
	if _, err := os.Stat(envSample); !os.IsNotExist(err) {
 | 
						if _, err := os.Stat(envSample); !os.IsNotExist(err) {
 | 
				
			||||||
		return true, nil
 | 
							return true, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -233,7 +233,7 @@ func LintAppService(recipe recipe.Recipe) (bool, error) {
 | 
				
			|||||||
// the recipe. This typically means that no domain is required to deploy and
 | 
					// the recipe. This typically means that no domain is required to deploy and
 | 
				
			||||||
// therefore no matching traefik deploy label will be present.
 | 
					// therefore no matching traefik deploy label will be present.
 | 
				
			||||||
func LintTraefikEnabledSkipCondition(recipe recipe.Recipe) (bool, error) {
 | 
					func LintTraefikEnabledSkipCondition(recipe recipe.Recipe) (bool, error) {
 | 
				
			||||||
	envSamplePath := path.Join(config.RECIPES_DIR, recipe.Name, ".env.sample")
 | 
						envSamplePath := path.Join(recipe.Dir, ".env.sample")
 | 
				
			||||||
	sampleEnv, err := config.ReadEnv(envSamplePath)
 | 
						sampleEnv, err := config.ReadEnv(envSamplePath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return false, fmt.Errorf("Unable to discover .env.sample for %s", recipe.Name)
 | 
							return false, fmt.Errorf("Unable to discover .env.sample for %s", recipe.Name)
 | 
				
			||||||
@ -358,7 +358,7 @@ func LintHasPublishedVersion(recipe recipe.Recipe) (bool, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LintMetadataFilledIn(r recipe.Recipe) (bool, error) {
 | 
					func LintMetadataFilledIn(r recipe.Recipe) (bool, error) {
 | 
				
			||||||
	features, category, err := recipe.GetRecipeFeaturesAndCategory(r.Name)
 | 
						features, category, err := r.GetRecipeFeaturesAndCategory()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return false, err
 | 
							return false, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ package recipe
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io/ioutil"
 | 
						"net/url"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
@ -130,17 +130,10 @@ type Features struct {
 | 
				
			|||||||
	SSO         string `json:"sso"`
 | 
						SSO         string `json:"sso"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Recipe represents a recipe.
 | 
					 | 
				
			||||||
type Recipe struct {
 | 
					 | 
				
			||||||
	Name   string
 | 
					 | 
				
			||||||
	Config *composetypes.Config
 | 
					 | 
				
			||||||
	Meta   RecipeMeta
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Push pushes the latest changes to a SSH URL remote. You need to have your
 | 
					// Push pushes the latest changes to a SSH URL remote. You need to have your
 | 
				
			||||||
// local SSH configuration for git.coopcloud.tech working for this to work
 | 
					// local SSH configuration for git.coopcloud.tech working for this to work
 | 
				
			||||||
func (r Recipe) Push(dryRun bool) error {
 | 
					func (r Recipe) Push(dryRun bool) error {
 | 
				
			||||||
	repo, err := git.PlainOpen(r.Dir())
 | 
						repo, err := git.PlainOpen(r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -149,21 +142,16 @@ func (r Recipe) Push(dryRun bool) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := gitPkg.Push(r.Dir(), "origin-ssh", true, dryRun); err != nil {
 | 
						if err := gitPkg.Push(r.Dir, "origin-ssh", true, dryRun); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Dir retrieves the recipe repository path
 | 
					 | 
				
			||||||
func (r Recipe) Dir() string {
 | 
					 | 
				
			||||||
	return path.Join(config.RECIPES_DIR, r.Name)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UpdateLabel updates a recipe label
 | 
					// UpdateLabel updates a recipe label
 | 
				
			||||||
func (r Recipe) UpdateLabel(pattern, serviceName, label string) error {
 | 
					func (r Recipe) UpdateLabel(pattern, serviceName, label string) error {
 | 
				
			||||||
	fullPattern := fmt.Sprintf("%s/%s/%s", config.RECIPES_DIR, r.Name, pattern)
 | 
						fullPattern := fmt.Sprintf("%s/%s", r.Dir, pattern)
 | 
				
			||||||
	if err := compose.UpdateLabel(fullPattern, serviceName, label, r.Name); err != nil {
 | 
						if err := compose.UpdateLabel(fullPattern, serviceName, label, r.Name); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -172,7 +160,7 @@ func (r Recipe) UpdateLabel(pattern, serviceName, label string) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// UpdateTag updates a recipe tag
 | 
					// UpdateTag updates a recipe tag
 | 
				
			||||||
func (r Recipe) UpdateTag(image, tag string) (bool, error) {
 | 
					func (r Recipe) UpdateTag(image, tag string) (bool, error) {
 | 
				
			||||||
	pattern := fmt.Sprintf("%s/%s/compose**yml", config.RECIPES_DIR, r.Name)
 | 
						pattern := fmt.Sprintf("%s/compose**yml", r.Dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	image = formatter.StripTagMeta(image)
 | 
						image = formatter.StripTagMeta(image)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -188,7 +176,7 @@ func (r Recipe) UpdateTag(image, tag string) (bool, error) {
 | 
				
			|||||||
func (r Recipe) Tags() ([]string, error) {
 | 
					func (r Recipe) Tags() ([]string, error) {
 | 
				
			||||||
	var tags []string
 | 
						var tags []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo, err := git.PlainOpen(r.Dir())
 | 
						repo, err := git.PlainOpen(r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return tags, err
 | 
							return tags, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -210,49 +198,51 @@ func (r Recipe) Tags() ([]string, error) {
 | 
				
			|||||||
	return tags, nil
 | 
						return tags, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Get retrieves a recipe.
 | 
					// // Get2 retrieves a recipe.
 | 
				
			||||||
func Get(recipeName string, offline bool) (Recipe, error) {
 | 
					// func (r Recipe) Load(offline bool) (Recipe2, error) {
 | 
				
			||||||
	if err := EnsureExists(recipeName); err != nil {
 | 
					//
 | 
				
			||||||
		return Recipe{}, err
 | 
					// 	meta, err := r.GetRecipeMeta(offline)
 | 
				
			||||||
 | 
					// 	if err != nil {
 | 
				
			||||||
 | 
					// 		switch err.(type) {
 | 
				
			||||||
 | 
					// 		case RecipeMissingFromCatalogue:
 | 
				
			||||||
 | 
					// 			meta = RecipeMeta{}
 | 
				
			||||||
 | 
					// 		default:
 | 
				
			||||||
 | 
					// 			return Recipe2{}, err
 | 
				
			||||||
 | 
					// 		}
 | 
				
			||||||
 | 
					// 	}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 	return Recipe2{
 | 
				
			||||||
 | 
					// 		Name:   r.Name,
 | 
				
			||||||
 | 
					// 		Config: config,
 | 
				
			||||||
 | 
					// 		Meta:   meta,
 | 
				
			||||||
 | 
					// 	}, nil
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r Recipe) LoadConfig() error {
 | 
				
			||||||
 | 
						if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pattern := fmt.Sprintf("%s/%s/compose**yml", config.RECIPES_DIR, recipeName)
 | 
						pattern := fmt.Sprintf("%s/compose**yml", r.Dir)
 | 
				
			||||||
	composeFiles, err := filepath.Glob(pattern)
 | 
						composeFiles, err := filepath.Glob(pattern)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return Recipe{}, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(composeFiles) == 0 {
 | 
						if len(composeFiles) == 0 {
 | 
				
			||||||
		return Recipe{}, fmt.Errorf("%s is missing a compose.yml or compose.*.yml file?", recipeName)
 | 
							return fmt.Errorf("%s is missing a compose.yml or compose.*.yml file?", r.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample")
 | 
					 | 
				
			||||||
	sampleEnv, err := config.ReadEnv(envSamplePath)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return Recipe{}, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	opts := stack.Deploy{Composefiles: composeFiles}
 | 
						opts := stack.Deploy{Composefiles: composeFiles}
 | 
				
			||||||
 | 
						sampleEnv, err := r.SampleEnv()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	config, err := loader.LoadComposefile(opts, sampleEnv)
 | 
						config, err := loader.LoadComposefile(opts, sampleEnv)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return Recipe{}, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						r.Config = config
 | 
				
			||||||
	meta, err := GetRecipeMeta(recipeName, offline)
 | 
						return nil
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		switch err.(type) {
 | 
					 | 
				
			||||||
		case RecipeMissingFromCatalogue:
 | 
					 | 
				
			||||||
			meta = RecipeMeta{}
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return Recipe{}, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return Recipe{
 | 
					 | 
				
			||||||
		Name:   recipeName,
 | 
					 | 
				
			||||||
		Config: config,
 | 
					 | 
				
			||||||
		Meta:   meta,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r Recipe) SampleEnv() (map[string]string, error) {
 | 
					func (r Recipe) SampleEnv() (map[string]string, error) {
 | 
				
			||||||
@ -264,33 +254,71 @@ func (r Recipe) SampleEnv() (map[string]string, error) {
 | 
				
			|||||||
	return sampleEnv, nil
 | 
						return sampleEnv, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Recipe struct {
 | 
				
			||||||
 | 
						Name        string
 | 
				
			||||||
 | 
						NameEscaped string
 | 
				
			||||||
 | 
						Dir         string
 | 
				
			||||||
 | 
						GitURL      string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Config *composetypes.Config
 | 
				
			||||||
 | 
						Meta   RecipeMeta
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Get(recipeName string) (Recipe, error) {
 | 
				
			||||||
 | 
						if !strings.Contains(recipeName, "/") {
 | 
				
			||||||
 | 
							return Recipe{
 | 
				
			||||||
 | 
								Name:   recipeName,
 | 
				
			||||||
 | 
								GitURL: fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipeName),
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u, err := url.Parse(recipeName)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return Recipe{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						u.Scheme = "https"
 | 
				
			||||||
 | 
						u.RawPath, err = url.JoinPath(u.RawPath, ".git")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return Recipe{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return Recipe{
 | 
				
			||||||
 | 
							Name:        recipeName,
 | 
				
			||||||
 | 
							NameEscaped: escapeRecipeName(recipeName),
 | 
				
			||||||
 | 
							Dir:         path.Join(config.RECIPES_DIR, escapeRecipeName(recipeName)),
 | 
				
			||||||
 | 
							GitURL:      u.String(),
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func escapeRecipeName(recipeName string) string {
 | 
				
			||||||
 | 
						recipeName = strings.ReplaceAll(recipeName, "/", "_")
 | 
				
			||||||
 | 
						recipeName = strings.ReplaceAll(recipeName, ".", "_")
 | 
				
			||||||
 | 
						return recipeName
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Ensure makes sure the recipe exists, is up to date and has the latest version checked out.
 | 
					// Ensure makes sure the recipe exists, is up to date and has the latest version checked out.
 | 
				
			||||||
func Ensure(recipeName string) error {
 | 
					func (r Recipe) Ensure() error {
 | 
				
			||||||
	if err := EnsureExists(recipeName); err != nil {
 | 
						if err := r.EnsureExists(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := EnsureUpToDate(recipeName); err != nil {
 | 
						if err := r.EnsureUpToDate(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := EnsureLatest(recipeName); err != nil {
 | 
						if err := r.EnsureLatest(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EnsureExists ensures that a recipe is locally cloned
 | 
					// EnsureExists ensures that the recipe is locally cloned
 | 
				
			||||||
func EnsureExists(recipeName string) error {
 | 
					func (r Recipe) EnsureExists() error {
 | 
				
			||||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
						if _, err := os.Stat(r.Dir); os.IsNotExist(err) {
 | 
				
			||||||
 | 
							logrus.Debugf("%s does not exist, attemmpting to clone", r.Dir)
 | 
				
			||||||
	if _, err := os.Stat(recipeDir); os.IsNotExist(err) {
 | 
							if err := gitPkg.Clone(r.Dir, r.GitURL); err != nil {
 | 
				
			||||||
		logrus.Debugf("%s does not exist, attemmpting to clone", recipeDir)
 | 
					 | 
				
			||||||
		url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipeName)
 | 
					 | 
				
			||||||
		if err := gitPkg.Clone(recipeDir, url); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := gitPkg.EnsureGitRepo(recipeDir); err != nil {
 | 
						if err := gitPkg.EnsureGitRepo(r.Dir); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -298,14 +326,12 @@ func EnsureExists(recipeName string) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EnsureVersion checks whether a specific version exists for a recipe.
 | 
					// EnsureVersion checks whether a specific version exists for a recipe.
 | 
				
			||||||
func EnsureVersion(recipeName, version string) error {
 | 
					func (r Recipe) EnsureVersion(version string) error {
 | 
				
			||||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
						if err := gitPkg.EnsureGitRepo(r.Dir); err != nil {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := gitPkg.EnsureGitRepo(recipeDir); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo, err := git.PlainOpen(recipeDir)
 | 
						repo, err := git.PlainOpen(r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -329,11 +355,11 @@ func EnsureVersion(recipeName, version string) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	joinedTags := strings.Join(parsedTags, ", ")
 | 
						joinedTags := strings.Join(parsedTags, ", ")
 | 
				
			||||||
	if joinedTags != "" {
 | 
						if joinedTags != "" {
 | 
				
			||||||
		logrus.Debugf("read %s as tags for recipe %s", joinedTags, recipeName)
 | 
							logrus.Debugf("read %s as tags for recipe %s", joinedTags, r.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if tagRef.String() == "" {
 | 
						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()
 | 
						worktree, err := repo.Worktree()
 | 
				
			||||||
@ -350,37 +376,33 @@ func EnsureVersion(recipeName, version string) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logrus.Debugf("successfully checked %s out to %s in %s", recipeName, tagRef.Short(), recipeDir)
 | 
						logrus.Debugf("successfully checked %s out to %s in %s", r.Name, tagRef.Short(), r.Dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EnsureIsClean makes sure that the recipe repository has no unstaged changes.
 | 
					// EnsureIsClean makes sure that the recipe repository has no unstaged changes.
 | 
				
			||||||
func EnsureIsClean(recipeName string) error {
 | 
					func (r Recipe) EnsureIsClean() error {
 | 
				
			||||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
						isClean, err := gitPkg.IsClean(r.Dir)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	isClean, err := gitPkg.IsClean(recipeDir)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("unable to check git clean status in %s: %s", recipeDir, err)
 | 
							return fmt.Errorf("unable to check git clean status in %s: %s", r.Dir, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !isClean {
 | 
						if !isClean {
 | 
				
			||||||
		msg := "%s (%s) has locally unstaged changes? please commit/remove your changes before proceeding"
 | 
							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, r.Dir)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EnsureLatest makes sure the latest commit is checked out for a local recipe repository
 | 
					// EnsureLatest makes sure the latest commit is checked out for the local recipe repository
 | 
				
			||||||
func EnsureLatest(recipeName string) error {
 | 
					func (r Recipe) EnsureLatest() error {
 | 
				
			||||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
						if err := gitPkg.EnsureGitRepo(r.Dir); err != nil {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := gitPkg.EnsureGitRepo(recipeDir); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo, err := git.PlainOpen(recipeDir)
 | 
						repo, err := git.PlainOpen(r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -390,7 +412,7 @@ func EnsureLatest(recipeName string) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	branch, err := gitPkg.GetDefaultBranch(repo, recipeDir)
 | 
						branch, err := gitPkg.GetDefaultBranch(repo, r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -402,7 +424,7 @@ func EnsureLatest(recipeName string) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := worktree.Checkout(checkOutOpts); err != nil {
 | 
						if err := worktree.Checkout(checkOutOpts); err != nil {
 | 
				
			||||||
		logrus.Debugf("failed to check out %s in %s", branch, recipeDir)
 | 
							logrus.Debugf("failed to check out %s in %s", branch, r.Dir)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -410,18 +432,17 @@ func EnsureLatest(recipeName string) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ChaosVersion constructs a chaos mode recipe version.
 | 
					// ChaosVersion constructs a chaos mode recipe version.
 | 
				
			||||||
func ChaosVersion(recipeName string) (string, error) {
 | 
					func (r Recipe) ChaosVersion() (string, error) {
 | 
				
			||||||
	var version string
 | 
						var version string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	head, err := gitPkg.GetRecipeHead(recipeName)
 | 
						head, err := gitPkg.GetHead(r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return version, err
 | 
							return version, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	version = formatter.SmallSHA(head.String())
 | 
						version = formatter.SmallSHA(head.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
						isClean, err := gitPkg.IsClean(r.Dir)
 | 
				
			||||||
	isClean, err := gitPkg.IsClean(recipeDir)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return version, err
 | 
							return version, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -464,22 +485,22 @@ func GetVersionLabelLocal(recipe Recipe) (string, error) {
 | 
				
			|||||||
	return label, nil
 | 
						return label, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetRecipeFeaturesAndCategory(recipeName string) (Features, string, error) {
 | 
					func (r Recipe) GetRecipeFeaturesAndCategory() (Features, string, error) {
 | 
				
			||||||
	feat := Features{}
 | 
						feat := Features{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var category string
 | 
						var category string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	readmePath := path.Join(config.RECIPES_DIR, recipeName, "README.md")
 | 
						readmePath := path.Join(r.Dir, "README.md")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logrus.Debugf("attempting to open %s for recipe metadata parsing", readmePath)
 | 
						logrus.Debugf("attempting to open %s for recipe metadata parsing", readmePath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	readmeFS, err := ioutil.ReadFile(readmePath)
 | 
						readmeFS, err := os.ReadFile(readmePath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return feat, category, err
 | 
							return feat, category, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	readmeMetadata, err := GetStringInBetween( // Find text between delimiters
 | 
						readmeMetadata, err := GetStringInBetween( // Find text between delimiters
 | 
				
			||||||
		recipeName,
 | 
							r.Name,
 | 
				
			||||||
		string(readmeFS),
 | 
							string(readmeFS),
 | 
				
			||||||
		"<!-- metadata -->", "<!-- endmetadata -->",
 | 
							"<!-- metadata -->", "<!-- endmetadata -->",
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
@ -530,7 +551,7 @@ func GetRecipeFeaturesAndCategory(recipeName string) (Features, string, error) {
 | 
				
			|||||||
		if strings.Contains(val, "**Image**") {
 | 
							if strings.Contains(val, "**Image**") {
 | 
				
			||||||
			imageMetadata, err := GetImageMetadata(strings.TrimSpace(
 | 
								imageMetadata, err := GetImageMetadata(strings.TrimSpace(
 | 
				
			||||||
				strings.TrimPrefix(val, "* **Image**:"),
 | 
									strings.TrimPrefix(val, "* **Image**:"),
 | 
				
			||||||
			), recipeName)
 | 
								), r.Name)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -597,38 +618,36 @@ func GetStringInBetween(recipeName, str, start, end string) (result string, err
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EnsureUpToDate ensures that the local repo is synced to the remote
 | 
					// EnsureUpToDate ensures that the local repo is synced to the remote
 | 
				
			||||||
func EnsureUpToDate(recipeName string) error {
 | 
					func (r Recipe) EnsureUpToDate() error {
 | 
				
			||||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
						repo, err := git.PlainOpen(r.Dir)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	repo, err := git.PlainOpen(recipeDir)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("unable to open %s: %s", recipeDir, err)
 | 
							return fmt.Errorf("unable to open %s: %s", r.Dir, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	remotes, err := repo.Remotes()
 | 
						remotes, err := repo.Remotes()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("unable to read remotes in %s: %s", recipeDir, err)
 | 
							return fmt.Errorf("unable to read remotes in %s: %s", r.Dir, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(remotes) == 0 {
 | 
						if len(remotes) == 0 {
 | 
				
			||||||
		logrus.Debugf("cannot ensure %s is up-to-date, no git remotes configured", recipeName)
 | 
							logrus.Debugf("cannot ensure %s is up-to-date, no git remotes configured", r.Name)
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	worktree, err := repo.Worktree()
 | 
						worktree, err := repo.Worktree()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("unable to open git work tree in %s: %s", recipeDir, err)
 | 
							return fmt.Errorf("unable to open git work tree in %s: %s", r.Dir, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	branch, err := gitPkg.CheckoutDefaultBranch(repo, recipeDir)
 | 
						branch, err := gitPkg.CheckoutDefaultBranch(repo, r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("unable to check out default branch in %s: %s", recipeDir, err)
 | 
							return fmt.Errorf("unable to check out default branch in %s: %s", r.Dir, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fetchOpts := &git.FetchOptions{Tags: git.AllTags}
 | 
						fetchOpts := &git.FetchOptions{Tags: git.AllTags}
 | 
				
			||||||
	if err := repo.Fetch(fetchOpts); err != nil {
 | 
						if err := repo.Fetch(fetchOpts); err != nil {
 | 
				
			||||||
		if !strings.Contains(err.Error(), "already up-to-date") {
 | 
							if !strings.Contains(err.Error(), "already up-to-date") {
 | 
				
			||||||
			return fmt.Errorf("unable to fetch tags in %s: %s", recipeDir, err)
 | 
								return fmt.Errorf("unable to fetch tags in %s: %s", r.Dir, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -640,11 +659,11 @@ func EnsureUpToDate(recipeName string) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if err := worktree.Pull(opts); err != nil {
 | 
						if err := worktree.Pull(opts); err != nil {
 | 
				
			||||||
		if !strings.Contains(err.Error(), "already up-to-date") {
 | 
							if !strings.Contains(err.Error(), "already up-to-date") {
 | 
				
			||||||
			return fmt.Errorf("unable to git pull in %s: %s", recipeDir, err)
 | 
								return fmt.Errorf("unable to git pull in %s: %s", r.Dir, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logrus.Debugf("fetched latest git changes for %s", recipeName)
 | 
						logrus.Debugf("fetched latest git changes for %s", r.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -672,7 +691,7 @@ func ReadRecipeCatalogue(offline bool) (RecipeCatalogue, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// readRecipeCatalogueFS reads the catalogue from the file system.
 | 
					// readRecipeCatalogueFS reads the catalogue from the file system.
 | 
				
			||||||
func readRecipeCatalogueFS(target interface{}) error {
 | 
					func readRecipeCatalogueFS(target interface{}) error {
 | 
				
			||||||
	recipesJSONFS, err := ioutil.ReadFile(config.RECIPES_JSON)
 | 
						recipesJSONFS, err := os.ReadFile(config.RECIPES_JSON)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -724,20 +743,20 @@ func (r RecipeMissingFromCatalogue) Error() string {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetRecipeMeta retrieves the recipe metadata from the recipe catalogue.
 | 
					// GetRecipeMeta retrieves the recipe metadata from the recipe catalogue.
 | 
				
			||||||
func GetRecipeMeta(recipeName string, offline bool) (RecipeMeta, error) {
 | 
					func (r Recipe) GetRecipeMeta(offline bool) (RecipeMeta, error) {
 | 
				
			||||||
	catl, err := ReadRecipeCatalogue(offline)
 | 
						catl, err := ReadRecipeCatalogue(offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return RecipeMeta{}, err
 | 
							return RecipeMeta{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	recipeMeta, ok := catl[recipeName]
 | 
						recipeMeta, ok := catl[r.Name]
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return RecipeMeta{}, RecipeMissingFromCatalogue{
 | 
							return RecipeMeta{}, RecipeMissingFromCatalogue{
 | 
				
			||||||
			err: fmt.Sprintf("recipe %s does not exist?", recipeName),
 | 
								err: fmt.Sprintf("recipe %s does not exist?", r.Name),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logrus.Debugf("recipe metadata retrieved for %s", recipeName)
 | 
						logrus.Debugf("recipe metadata retrieved for %s", r.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return recipeMeta, nil
 | 
						return recipeMeta, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -864,13 +883,12 @@ func ReadReposMetadata() (RepoCatalogue, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetRecipeVersions retrieves all recipe versions.
 | 
					// GetRecipeVersions retrieves all recipe versions.
 | 
				
			||||||
func GetRecipeVersions(recipeName string, offline bool) (RecipeVersions, error) {
 | 
					func (r Recipe) GetVersions(offline bool) (RecipeVersions, error) {
 | 
				
			||||||
	versions := RecipeVersions{}
 | 
						versions := RecipeVersions{}
 | 
				
			||||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logrus.Debugf("attempting to open git repository in %s", recipeDir)
 | 
						logrus.Debugf("attempting to open git repository in %s", r.Dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo, err := git.PlainOpen(recipeDir)
 | 
						repo, err := git.PlainOpen(r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return versions, err
 | 
							return versions, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -888,7 +906,7 @@ func GetRecipeVersions(recipeName string, offline bool) (RecipeVersions, error)
 | 
				
			|||||||
	if err := gitTags.ForEach(func(ref *plumbing.Reference) (err error) {
 | 
						if err := gitTags.ForEach(func(ref *plumbing.Reference) (err error) {
 | 
				
			||||||
		tag := strings.TrimPrefix(string(ref.Name()), "refs/tags/")
 | 
							tag := strings.TrimPrefix(string(ref.Name()), "refs/tags/")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		logrus.Debugf("processing %s for %s", tag, recipeName)
 | 
							logrus.Debugf("processing %s for %s", tag, r.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		checkOutOpts := &git.CheckoutOptions{
 | 
							checkOutOpts := &git.CheckoutOptions{
 | 
				
			||||||
			Create: false,
 | 
								Create: false,
 | 
				
			||||||
@ -896,19 +914,18 @@ func GetRecipeVersions(recipeName string, offline bool) (RecipeVersions, error)
 | 
				
			|||||||
			Branch: plumbing.ReferenceName(ref.Name()),
 | 
								Branch: plumbing.ReferenceName(ref.Name()),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := worktree.Checkout(checkOutOpts); err != nil {
 | 
							if err := worktree.Checkout(checkOutOpts); err != nil {
 | 
				
			||||||
			logrus.Debugf("failed to check out %s in %s", tag, recipeDir)
 | 
								logrus.Debugf("failed to check out %s in %s", tag, r.Dir)
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		logrus.Debugf("successfully checked out %s in %s", ref.Name(), recipeDir)
 | 
							logrus.Debugf("successfully checked out %s in %s", ref.Name(), r.Dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		recipe, err := Get(recipeName, offline)
 | 
							if err := r.LoadConfig(); err != nil {
 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		versionMeta := make(map[string]ServiceMeta)
 | 
							versionMeta := make(map[string]ServiceMeta)
 | 
				
			||||||
		for _, service := range recipe.Config.Services {
 | 
							for _, service := range r.Config.Services {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			img, err := reference.ParseNormalizedNamed(service.Image)
 | 
								img, err := reference.ParseNormalizedNamed(service.Image)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
@ -941,14 +958,14 @@ func GetRecipeVersions(recipeName string, offline bool) (RecipeVersions, error)
 | 
				
			|||||||
		return versions, err
 | 
							return versions, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = gitPkg.CheckoutDefaultBranch(repo, recipeDir)
 | 
						_, err = gitPkg.CheckoutDefaultBranch(repo, r.Dir)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return versions, err
 | 
							return versions, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sortRecipeVersions(versions)
 | 
						sortRecipeVersions(versions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logrus.Debugf("collected %s for %s", versions, recipeName)
 | 
						logrus.Debugf("collected %s for %s", versions, r.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return versions, nil
 | 
						return versions, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetVersionLabelLocalDoesNotUseTimeoutLabel(t *testing.T) {
 | 
					func TestGetVersionLabelLocalDoesNotUseTimeoutLabel(t *testing.T) {
 | 
				
			||||||
	offline := true
 | 
						offline := true
 | 
				
			||||||
	recipe, err := Get("traefik", offline)
 | 
						recipe, err := Get2("traefik", offline)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user