package recipe import ( "bytes" "errors" "fmt" "io/ioutil" "os" "path" "text/template" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/git" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) // recipeMetadata is the recipe metadata for the README.md type recipeMetadata struct { Name string Description string Category string Status string Image string Healthcheck string Backups string Email string Tests string SSO string } var recipeNewCommand = cli.Command{ Name: "new", Aliases: []string{"n"}, Flags: []cli.Flag{ internal.DebugFlag, internal.NoInputFlag, }, Before: internal.SubCommandBefore, Usage: "Create a new recipe", ArgsUsage: "", Description: ` This command creates a new recipe. Abra uses our built-in example repository which is available here: https://git.coopcloud.tech/coop-cloud/example Files within the example repository make use of the Golang templating system which Abra uses to inject values into the generated recipe folder (e.g. name of recipe and domain in the sample environment config). `, Action: func(c *cli.Context) error { recipeName := c.Args().First() if recipeName == "" { internal.ShowSubcommandHelpAndError(c, errors.New("no recipe name provided")) } directory := path.Join(config.RECIPES_DIR, recipeName) if _, err := os.Stat(directory); !os.IsNotExist(err) { logrus.Fatalf("%s recipe directory already exists?", directory) } url := fmt.Sprintf("%s/example.git", config.REPOS_BASE_URL) if err := git.Clone(directory, url); err != nil { logrus.Fatal(err) } gitRepo := path.Join(config.RECIPES_DIR, recipeName, ".git") if err := os.RemoveAll(gitRepo); err != nil { logrus.Fatal(err) } logrus.Debugf("removed example git repo in %s", gitRepo) meta := newRecipeMeta(recipeName) toParse := []string{ path.Join(config.RECIPES_DIR, recipeName, "README.md"), path.Join(config.RECIPES_DIR, recipeName, ".env.sample"), } for _, path := range toParse { tpl, err := template.ParseFiles(path) if err != nil { logrus.Fatal(err) } var templated bytes.Buffer if err := tpl.Execute(&templated, meta); err != nil { logrus.Fatal(err) } if err := ioutil.WriteFile(path, templated.Bytes(), 0644); err != nil { logrus.Fatal(err) } } newGitRepo := path.Join(config.RECIPES_DIR, recipeName) if err := git.Init(newGitRepo, true); err != nil { logrus.Fatal(err) } fmt.Print(fmt.Sprintf(` Your new %s recipe has been created in %s. In order to share your recipe, you can upload it the git repository to: https://git.coopcloud.tech/coop-cloud/%s If you're not sure how to do that, come chat with us: https://docs.coopcloud.tech/contact See "abra recipe -h" for additional recipe maintainer commands. Happy Hacking! `, recipeName, path.Join(config.RECIPES_DIR, recipeName), recipeName)) return nil }, } // newRecipeMeta creates a new recipeMetadata instance with defaults func newRecipeMeta(recipeName string) recipeMetadata { return recipeMetadata{ Name: recipeName, Description: "> One line description of the recipe", Category: "Apps", Status: "0", Image: fmt.Sprintf("[`%s`](https://hub.docker.com/r/%s), 4, upstream", recipeName, recipeName), Healthcheck: "No", Backups: "No", Email: "No", Tests: "No", SSO: "No", } }