package recipe import ( "os" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/formatter" "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: "fetch [recipe | --all] [flags]", Aliases: []string{"f"}, Short: "Clone recipe(s) locally", Long: `Using "--force/-f" Git syncs an existing recipe. It does not erase unstaged changes.`, Args: cobra.RangeArgs(0, 1), Example: ` # 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("missing [recipe] or --all/-a") } if recipeName != "" && fetchAllRecipes { log.Fatal("cannot use [recipe] and --all/-a together") } ensureCtx := internal.GetEnsureContext() if recipeName != "" { r := recipe.Get(recipeName) if _, err := os.Stat(r.Dir); !os.IsNotExist(err) { if !force { log.Warnf("%s is already fetched", r.Name) return } } r = internal.ValidateRecipe(args, cmd.Name()) if sshRemote { if r.SSHURL == "" { log.Warnf("unable to discover SSH remote for %s", r.Name) return } repo, err := git.PlainOpen(r.Dir) if err != nil { log.Fatalf("unable to open %s: %s", r.Dir, err) } if err = repo.DeleteRemote("origin"); err != nil { log.Fatalf("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.Fatalf("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), "fetching latest recipes...") 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, "all", "a", false, "fetch all recipes", ) RecipeFetchCommand.Flags().BoolVarP( &sshRemote, "ssh", "s", false, "automatically set ssh remote", ) RecipeFetchCommand.Flags().BoolVarP( &force, "force", "f", false, "force re-fetch", ) }