package recipe import ( "bytes" "errors" "fmt" "os" "path" "text/template" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/git" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" "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, internal.OfflineFlag, internal.GitNameFlag, internal.GitEmailFlag, }, Before: internal.SubCommandBefore, Usage: "Create a new recipe", ArgsUsage: "", Description: ` Create a new recipe. Abra uses the built-in example repository which is available here: https://git.coopcloud.tech/coop-cloud/example`, Action: func(c *cli.Context) error { recipeName := c.Args().First() r := recipe.Get(recipeName) if recipeName == "" { internal.ShowSubcommandHelpAndError(c, errors.New("no recipe name provided")) } if _, err := os.Stat(r.Dir); !os.IsNotExist(err) { log.Fatalf("%s recipe directory already exists?", r.Dir) } url := fmt.Sprintf("%s/example.git", config.REPOS_BASE_URL) if err := git.Clone(r.Dir, url); err != nil { log.Fatal(err) } gitRepo := path.Join(r.Dir, ".git") if err := os.RemoveAll(gitRepo); err != nil { log.Fatal(err) } log.Debugf("removed example git repo in %s", gitRepo) meta := newRecipeMeta(recipeName) for _, path := range []string{r.ReadmePath, r.SampleEnvPath} { tpl, err := template.ParseFiles(path) if err != nil { log.Fatal(err) } var templated bytes.Buffer if err := tpl.Execute(&templated, meta); err != nil { log.Fatal(err) } if err := os.WriteFile(path, templated.Bytes(), 0o644); err != nil { log.Fatal(err) } } if err := git.Init(r.Dir, true, internal.GitName, internal.GitEmail); err != nil { log.Fatal(err) } log.Infof("new recipe '%s' created: %s", recipeName, path.Join(r.Dir)) log.Info("happy hacking 🎉") 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", } }