package recipe import ( "os" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" "github.com/go-git/go-git/v5" gitCfg "github.com/go-git/go-git/v5/config" "github.com/spf13/cobra" ) var RecipeFetchCommand = &cobra.Command{ Use: i18n.G("fetch [recipe | --all] [flags]"), Aliases: []string{i18n.G("f")}, Short: i18n.G("Clone recipe(s) locally"), Long: i18n.G(`Using "--force/-f" Git syncs an existing recipe. It does not erase unstaged changes.`), Args: cobra.RangeArgs(0, 1), Example: i18n.G(` # fetch from recipe catalogue abra recipe fetch gitea # fetch from remote recipe abra recipe fetch git.foo.org/recipes/myrecipe # fetch with ssh remote for hacking abra recipe fetch gitea --ssh`), ValidArgsFunction: func( cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return autocomplete.RecipeNameComplete() }, Run: func(cmd *cobra.Command, args []string) { var recipeName string if len(args) > 0 { recipeName = args[0] } if recipeName == "" && !fetchAllRecipes { log.Fatal(i18n.G("missing [recipe] or --all/-a")) } if recipeName != "" && fetchAllRecipes { log.Fatal(i18n.G("cannot use [recipe] and --all/-a together")) } if recipeName != "" { r := recipe.Get(recipeName) if _, err := os.Stat(r.Dir); !os.IsNotExist(err) { if !force { log.Warn(i18n.G("%s is already fetched", r.Name)) return } } r = internal.ValidateRecipe(args, cmd.Name()) if sshRemote { if r.SSHURL == "" { log.Warn(i18n.G("unable to discover SSH remote for %s", r.Name)) return } repo, err := git.PlainOpen(r.Dir) if err != nil { log.Fatal(i18n.G("unable to open %s: %s", r.Dir, err)) } if err = repo.DeleteRemote("origin"); err != nil { log.Fatal(i18n.G("unable to remove default remote in %s: %s", r.Dir, err)) } if _, err := repo.CreateRemote(&gitCfg.RemoteConfig{ Name: "origin", URLs: []string{r.SSHURL}, }); err != nil { log.Fatal(i18n.G("unable to set SSH remote in %s: %s", r.Dir, err)) } } return } catalogue, err := recipe.ReadRecipeCatalogue(internal.Offline) if err != nil { log.Fatal(err) } catlBar := formatter.CreateProgressbar(len(catalogue), i18n.G("fetching latest recipes...")) ensureCtx := internal.GetEnsureContext() for recipeName := range catalogue { r := recipe.Get(recipeName) if err := r.Ensure(ensureCtx); err != nil { log.Error(err) } catlBar.Add(1) } }, } var ( fetchAllRecipes bool sshRemote bool force bool ) func init() { RecipeFetchCommand.Flags().BoolVarP( &fetchAllRecipes, i18n.G("all"), i18n.G("a"), false, i18n.G("fetch all recipes"), ) RecipeFetchCommand.Flags().BoolVarP( &sshRemote, i18n.G("ssh"), i18n.G("s"), false, i18n.G("automatically set ssh remote"), ) RecipeFetchCommand.Flags().BoolVarP( &force, i18n.G("force"), i18n.G("f"), false, i18n.G("force re-fetch"), ) }