forked from toolshed/abra
refactor(recipe): introduce new recipe struct and move some methods
This commit is contained in:
@ -213,21 +213,22 @@ func (r Recipe) Tags() ([]string, error) {
|
||||
|
||||
// Get retrieves a recipe.
|
||||
func Get(recipeName string, offline bool) (Recipe, error) {
|
||||
if err := EnsureExists(recipeName); err != nil {
|
||||
r := Get2(recipeName)
|
||||
if err := r.EnsureExists(); err != nil {
|
||||
return Recipe{}, err
|
||||
}
|
||||
|
||||
pattern := fmt.Sprintf("%s/%s/compose**yml", config.RECIPES_DIR, recipeName)
|
||||
pattern := fmt.Sprintf("%s/%s/compose**yml", config.RECIPES_DIR, r.Name)
|
||||
composeFiles, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return Recipe{}, err
|
||||
}
|
||||
|
||||
if len(composeFiles) == 0 {
|
||||
return Recipe{}, fmt.Errorf("%s is missing a compose.yml or compose.*.yml file?", recipeName)
|
||||
return Recipe{}, fmt.Errorf("%s is missing a compose.yml or compose.*.yml file?", r.Name)
|
||||
}
|
||||
|
||||
envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample")
|
||||
envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample")
|
||||
sampleEnv, err := envfile.ReadEnv(envSamplePath)
|
||||
if err != nil {
|
||||
return Recipe{}, err
|
||||
@ -239,7 +240,7 @@ func Get(recipeName string, offline bool) (Recipe, error) {
|
||||
return Recipe{}, err
|
||||
}
|
||||
|
||||
meta, err := GetRecipeMeta(recipeName, offline)
|
||||
meta, err := GetRecipeMeta(r.Name, offline)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case RecipeMissingFromCatalogue:
|
||||
@ -265,27 +266,35 @@ func (r Recipe) SampleEnv() (map[string]string, error) {
|
||||
return sampleEnv, nil
|
||||
}
|
||||
|
||||
func Get2(name string) Recipe2 {
|
||||
return Recipe2{Name: name}
|
||||
}
|
||||
|
||||
type Recipe2 struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// Ensure makes sure the recipe exists, is up to date and has the latest version checked out.
|
||||
func Ensure(recipeName string) error {
|
||||
if err := EnsureExists(recipeName); err != nil {
|
||||
func (r Recipe2) Ensure() error {
|
||||
if err := r.EnsureExists(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := EnsureUpToDate(recipeName); err != nil {
|
||||
if err := r.EnsureUpToDate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := EnsureLatest(recipeName); err != nil {
|
||||
if err := r.EnsureLatest(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureExists ensures that a recipe is locally cloned
|
||||
func EnsureExists(recipeName string) error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
// EnsureExists ensures that the recipe is locally cloned
|
||||
func (r Recipe2) EnsureExists() error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, r.Name)
|
||||
|
||||
if _, err := os.Stat(recipeDir); os.IsNotExist(err) {
|
||||
log.Debugf("%s does not exist, attemmpting to clone", recipeDir)
|
||||
url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipeName)
|
||||
url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, r.Name)
|
||||
if err := gitPkg.Clone(recipeDir, url); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -299,8 +308,8 @@ func EnsureExists(recipeName string) error {
|
||||
}
|
||||
|
||||
// EnsureVersion checks whether a specific version exists for a recipe.
|
||||
func EnsureVersion(recipeName, version string) error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
func (r Recipe2) EnsureVersion(version string) error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, r.Name)
|
||||
|
||||
if err := gitPkg.EnsureGitRepo(recipeDir); err != nil {
|
||||
return err
|
||||
@ -330,11 +339,11 @@ func EnsureVersion(recipeName, version string) error {
|
||||
|
||||
joinedTags := strings.Join(parsedTags, ", ")
|
||||
if joinedTags != "" {
|
||||
log.Debugf("read %s as tags for recipe %s", joinedTags, recipeName)
|
||||
log.Debugf("read %s as tags for recipe %s", joinedTags, r.Name)
|
||||
}
|
||||
|
||||
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()
|
||||
@ -351,14 +360,14 @@ func EnsureVersion(recipeName, version string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("successfully checked %s out to %s in %s", recipeName, tagRef.Short(), recipeDir)
|
||||
log.Debugf("successfully checked %s out to %s in %s", r.Name, tagRef.Short(), recipeDir)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureIsClean makes sure that the recipe repository has no unstaged changes.
|
||||
func EnsureIsClean(recipeName string) error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
func (r Recipe2) EnsureIsClean() error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, r.Name)
|
||||
|
||||
isClean, err := gitPkg.IsClean(recipeDir)
|
||||
if err != nil {
|
||||
@ -367,15 +376,15 @@ func EnsureIsClean(recipeName string) error {
|
||||
|
||||
if !isClean {
|
||||
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, recipeDir)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureLatest makes sure the latest commit is checked out for a local recipe repository
|
||||
func EnsureLatest(recipeName string) error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
// EnsureLatest makes sure the latest commit is checked out for the local recipe repository
|
||||
func (r Recipe2) EnsureLatest() error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, r.Name)
|
||||
|
||||
if err := gitPkg.EnsureGitRepo(recipeDir); err != nil {
|
||||
return err
|
||||
@ -410,18 +419,71 @@ func EnsureLatest(recipeName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureUpToDate ensures that the local repo is synced to the remote
|
||||
func (r Recipe2) EnsureUpToDate() error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, r.Name)
|
||||
|
||||
repo, err := git.PlainOpen(recipeDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to open %s: %s", recipeDir, err)
|
||||
}
|
||||
|
||||
remotes, err := repo.Remotes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read remotes in %s: %s", recipeDir, err)
|
||||
}
|
||||
|
||||
if len(remotes) == 0 {
|
||||
log.Debugf("cannot ensure %s is up-to-date, no git remotes configured", r.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
worktree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to open git work tree in %s: %s", recipeDir, err)
|
||||
}
|
||||
|
||||
branch, err := gitPkg.CheckoutDefaultBranch(repo, recipeDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to check out default branch in %s: %s", recipeDir, err)
|
||||
}
|
||||
|
||||
fetchOpts := &git.FetchOptions{Tags: git.AllTags}
|
||||
if err := repo.Fetch(fetchOpts); err != nil {
|
||||
if !strings.Contains(err.Error(), "already up-to-date") {
|
||||
return fmt.Errorf("unable to fetch tags in %s: %s", recipeDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
opts := &git.PullOptions{
|
||||
Force: true,
|
||||
ReferenceName: branch,
|
||||
SingleBranch: true,
|
||||
}
|
||||
|
||||
if err := worktree.Pull(opts); err != nil {
|
||||
if !strings.Contains(err.Error(), "already up-to-date") {
|
||||
return fmt.Errorf("unable to git pull in %s: %s", recipeDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("fetched latest git changes for %s", r.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChaosVersion constructs a chaos mode recipe version.
|
||||
func ChaosVersion(recipeName string) (string, error) {
|
||||
func (r Recipe2) ChaosVersion() (string, error) {
|
||||
var version string
|
||||
|
||||
head, err := gitPkg.GetRecipeHead(recipeName)
|
||||
head, err := gitPkg.GetRecipeHead(r.Name)
|
||||
if err != nil {
|
||||
return version, err
|
||||
}
|
||||
|
||||
version = formatter.SmallSHA(head.String())
|
||||
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
recipeDir := path.Join(config.RECIPES_DIR, r.Name)
|
||||
isClean, err := gitPkg.IsClean(recipeDir)
|
||||
if err != nil {
|
||||
return version, err
|
||||
@ -597,59 +659,6 @@ func GetStringInBetween(recipeName, str, start, end string) (result string, err
|
||||
return str[s : s+e], nil
|
||||
}
|
||||
|
||||
// EnsureUpToDate ensures that the local repo is synced to the remote
|
||||
func EnsureUpToDate(recipeName string) error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
|
||||
repo, err := git.PlainOpen(recipeDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to open %s: %s", recipeDir, err)
|
||||
}
|
||||
|
||||
remotes, err := repo.Remotes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read remotes in %s: %s", recipeDir, err)
|
||||
}
|
||||
|
||||
if len(remotes) == 0 {
|
||||
log.Debugf("cannot ensure %s is up-to-date, no git remotes configured", recipeName)
|
||||
return nil
|
||||
}
|
||||
|
||||
worktree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to open git work tree in %s: %s", recipeDir, err)
|
||||
}
|
||||
|
||||
branch, err := gitPkg.CheckoutDefaultBranch(repo, recipeDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to check out default branch in %s: %s", recipeDir, err)
|
||||
}
|
||||
|
||||
fetchOpts := &git.FetchOptions{Tags: git.AllTags}
|
||||
if err := repo.Fetch(fetchOpts); err != nil {
|
||||
if !strings.Contains(err.Error(), "already up-to-date") {
|
||||
return fmt.Errorf("unable to fetch tags in %s: %s", recipeDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
opts := &git.PullOptions{
|
||||
Force: true,
|
||||
ReferenceName: branch,
|
||||
SingleBranch: true,
|
||||
}
|
||||
|
||||
if err := worktree.Pull(opts); err != nil {
|
||||
if !strings.Contains(err.Error(), "already up-to-date") {
|
||||
return fmt.Errorf("unable to git pull in %s: %s", recipeDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("fetched latest git changes for %s", recipeName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadRecipeCatalogue reads the recipe catalogue.
|
||||
func ReadRecipeCatalogue(offline bool) (RecipeCatalogue, error) {
|
||||
recipes := make(RecipeCatalogue)
|
||||
|
Reference in New Issue
Block a user