package recipe import ( "fmt" "sort" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/log" recipePkg "coopcloud.tech/abra/pkg/recipe" "github.com/spf13/cobra" ) var RecipeVersionCommand = &cobra.Command{ Use: "versions [flags]", Aliases: []string{"v"}, Short: "List recipe versions", Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return autocomplete.RecipeNameComplete() }, Run: func(cmd *cobra.Command, args []string) { var warnMessages []string recipe := internal.ValidateRecipe(args, cmd.Name()) catl, err := recipePkg.ReadRecipeCatalogue(internal.Offline) if err != nil { log.Fatal(err) } recipeMeta, ok := catl[recipe.Name] if !ok { warnMessages = append(warnMessages, "retrieved versions from local recipe repository") recipeVersions, err := recipe.GetRecipeVersions() if err != nil { warnMessages = append(warnMessages, err.Error()) } recipeMeta = recipePkg.RecipeMeta{Versions: recipeVersions} } if len(recipeMeta.Versions) == 0 { log.Fatalf("%s has no published versions?", recipe.Name) } for i := len(recipeMeta.Versions) - 1; i >= 0; i-- { table, err := formatter.CreateTable() if err != nil { log.Fatal(err) } table.Headers("SERVICE", "IMAGE", "TAG", "VERSION") for version, meta := range recipeMeta.Versions[i] { var allRows [][]string var rows [][]string for service, serviceMeta := range meta { recipeVersion := version if service != "app" { recipeVersion = "" } rows = append(rows, []string{ service, serviceMeta.Image, serviceMeta.Tag, recipeVersion, }) allRows = append(allRows, []string{ version, service, serviceMeta.Image, serviceMeta.Tag, recipeVersion, }) } sort.Slice(rows, sortServiceByName(rows)) table.Rows(rows...) if !internal.MachineReadable { if err := formatter.PrintTable(table); err != nil { log.Fatal(err) } continue } if internal.MachineReadable { sort.Slice(allRows, sortServiceByName(allRows)) headers := []string{"VERSION", "SERVICE", "NAME", "TAG"} out, err := formatter.ToJSON(headers, allRows) if err != nil { log.Fatal("unable to render to JSON: %s", err) } fmt.Println(out) continue } } } if !internal.MachineReadable { for _, warnMsg := range warnMessages { log.Warn(warnMsg) } } }, } func sortServiceByName(versions [][]string) func(i, j int) bool { return func(i, j int) bool { return versions[i][0] < versions[j][0] } } func init() { RecipeVersionCommand.Flags().BoolVarP( &internal.MachineReadable, "machine", "m", false, "print machine-readable output", ) }