github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/internal/commands/suggest_builders.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 "sort" 6 "sync" 7 "text/tabwriter" 8 9 "github.com/spf13/cobra" 10 11 bldr "github.com/buildpacks/pack/internal/builder" 12 "github.com/buildpacks/pack/internal/style" 13 "github.com/buildpacks/pack/pkg/logging" 14 ) 15 16 // Deprecated: Use `builder suggest` instead. 17 func SuggestBuilders(logger logging.Logger, inspector BuilderInspector) *cobra.Command { 18 cmd := &cobra.Command{ 19 Use: "suggest-builders", 20 Hidden: true, 21 Args: cobra.NoArgs, 22 Short: "Display list of recommended builders", 23 Example: "pack suggest-builders", 24 Run: func(cmd *cobra.Command, s []string) { 25 deprecationWarning(logger, "suggest-builder", "builder suggest") 26 suggestBuilders(logger, inspector) 27 }, 28 } 29 30 return cmd 31 } 32 33 func suggestSettingBuilder(logger logging.Logger, inspector BuilderInspector) { 34 logger.Info("Please select a default builder with:") 35 logger.Info("") 36 logger.Info("\tpack config default-builder <builder-image>") 37 logger.Info("") 38 suggestBuilders(logger, inspector) 39 } 40 41 func suggestBuilders(logger logging.Logger, client BuilderInspector) { 42 suggestedBuilders := []bldr.KnownBuilder{} 43 for _, knownBuilder := range bldr.KnownBuilders { 44 if knownBuilder.Suggested { 45 suggestedBuilders = append(suggestedBuilders, knownBuilder) 46 } 47 } 48 WriteSuggestedBuilder(logger, client, suggestedBuilders) 49 } 50 51 func WriteSuggestedBuilder(logger logging.Logger, inspector BuilderInspector, builders []bldr.KnownBuilder) { 52 sort.Slice(builders, func(i, j int) bool { 53 if builders[i].Vendor == builders[j].Vendor { 54 return builders[i].Image < builders[j].Image 55 } 56 57 return builders[i].Vendor < builders[j].Vendor 58 }) 59 60 logger.Info("Suggested builders:") 61 62 // Fetch descriptions concurrently. 63 descriptions := make([]string, len(builders)) 64 65 var wg sync.WaitGroup 66 wg.Add(len(builders)) 67 68 for i, builder := range builders { 69 go func(w *sync.WaitGroup, i int, builder bldr.KnownBuilder) { 70 descriptions[i] = getBuilderDescription(builder, inspector) 71 w.Done() 72 }(&wg, i, builder) 73 } 74 75 wg.Wait() 76 77 tw := tabwriter.NewWriter(logger.Writer(), 10, 10, 5, ' ', tabwriter.TabIndent) 78 for i, builder := range builders { 79 fmt.Fprintf(tw, "\t%s:\t%s\t%s\t\n", builder.Vendor, style.Symbol(builder.Image), descriptions[i]) 80 } 81 fmt.Fprintln(tw) 82 83 logging.Tip(logger, "Learn more about a specific builder with:") 84 logger.Info("\tpack builder inspect <builder-image>") 85 } 86 87 func getBuilderDescription(builder bldr.KnownBuilder, inspector BuilderInspector) string { 88 info, err := inspector.InspectBuilder(builder.Image, false) 89 if err == nil && info != nil && info.Description != "" { 90 return info.Description 91 } 92 93 return builder.DefaultDescription 94 } 95 96 func isSuggestedBuilder(builder string) bool { 97 for _, knownBuilder := range bldr.KnownBuilders { 98 if builder == knownBuilder.Image && knownBuilder.Suggested { 99 return true 100 } 101 } 102 103 return false 104 }