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/urfave/cli" ) func sortServiceByName(versions [][]string) func(i, j int) bool { return func(i, j int) bool { // NOTE(d1): corresponds to the `tableCol` definition below if versions[i][1] == "app" { return true } return versions[i][1] < versions[j][1] } } var recipeVersionCommand = cli.Command{ Name: "versions", Aliases: []string{"v"}, Usage: "List recipe versions", ArgsUsage: "", Flags: []cli.Flag{ internal.DebugFlag, internal.OfflineFlag, internal.NoInputFlag, internal.MachineReadableFlag, }, Before: internal.SubCommandBefore, BashComplete: autocomplete.RecipeNameComplete, Action: func(c *cli.Context) error { var warnMessages []string recipe := internal.ValidateRecipe(c) 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) } var allRows [][]string for i := len(recipeMeta.Versions) - 1; i >= 0; i-- { table, err := formatter.CreateTable() if err != nil { log.Fatal(err) } table.Headers("SERVICE", "NAME", "TAG") for version, meta := range recipeMeta.Versions[i] { var rows [][]string for service, serviceMeta := range meta { rows = append(rows, []string{service, serviceMeta.Image, serviceMeta.Tag}) allRows = append(allRows, []string{version, service, serviceMeta.Image, serviceMeta.Tag}) } sort.Slice(rows, sortServiceByName(rows)) table.Rows(rows...) if !internal.MachineReadable { fmt.Println(table) log.Infof("VERSION: %s", version) } } } if !internal.MachineReadable { for _, warnMsg := range warnMessages { log.Warn(warnMsg) } } 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) return nil } return nil }, }