github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/internal/commands/config_registries.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/pkg/errors" 8 "github.com/spf13/cobra" 9 10 "github.com/buildpacks/pack/internal/config" 11 "github.com/buildpacks/pack/internal/slices" 12 "github.com/buildpacks/pack/internal/stringset" 13 "github.com/buildpacks/pack/internal/style" 14 "github.com/buildpacks/pack/pkg/logging" 15 "github.com/buildpacks/pack/registry" 16 ) 17 18 var ( 19 bpRegistryExplanation = "A Buildpack Registry is a (still experimental) place to publish, store, and discover buildpacks. " 20 ) 21 22 var ( 23 setDefault bool 24 registryType string 25 ) 26 27 func ConfigRegistries(logger logging.Logger, cfg config.Config, cfgPath string) *cobra.Command { 28 cmd := &cobra.Command{ 29 Use: "registries", 30 Aliases: []string{"registry", "registreis"}, 31 Short: "List, add and remove registries", 32 Long: bpRegistryExplanation + "\nYou can use the attached commands to list, add, and remove registries from your config", 33 RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 34 listRegistries(args, logger, cfg) 35 return nil 36 }), 37 } 38 39 listCmd := generateListCmd("registries", logger, cfg, listRegistries) 40 listCmd.Example = "pack config registries list" 41 listCmd.Long = bpRegistryExplanation + "List Registries saved in the pack config.\n\nShow the registries that are either added by default or have been explicitly added by using `pack config registries add`" 42 cmd.AddCommand(listCmd) 43 44 addCmd := generateAdd("registries", logger, cfg, cfgPath, addRegistry) 45 addCmd.Args = cobra.ExactArgs(2) 46 addCmd.Example = "pack config registries add my-registry https://github.com/buildpacks/my-registry" 47 addCmd.Long = bpRegistryExplanation + "Users can add registries from the config by using registries remove, and publish/yank buildpacks from it, as well as use those buildpacks when building applications." 48 addCmd.Flags().BoolVar(&setDefault, "default", false, "Set this buildpack registry as the default") 49 addCmd.Flags().StringVar(®istryType, "type", "github", "Type of buildpack registry [git|github]") 50 cmd.AddCommand(addCmd) 51 52 rmCmd := generateRemove("registries", logger, cfg, cfgPath, removeRegistry) 53 rmCmd.Example = "pack config registries remove myregistry" 54 rmCmd.Long = bpRegistryExplanation + "Users can remove registries from the config by using `pack config registries remove <registry>`" 55 cmd.AddCommand(rmCmd) 56 57 cmd.AddCommand(ConfigRegistriesDefault(logger, cfg, cfgPath)) 58 59 AddHelpFlag(cmd, "registries") 60 return cmd 61 } 62 63 func addRegistry(args []string, logger logging.Logger, cfg config.Config, cfgPath string) error { 64 newRegistry := config.Registry{ 65 Name: args[0], 66 URL: args[1], 67 Type: registryType, 68 } 69 70 return addRegistryToConfig(logger, newRegistry, setDefault, cfg, cfgPath) 71 } 72 73 func addRegistryToConfig(logger logging.Logger, newRegistry config.Registry, setDefault bool, cfg config.Config, cfgPath string) error { 74 if newRegistry.Name == config.OfficialRegistryName { 75 return errors.Errorf("%s is a reserved registry, please provide a different name", 76 style.Symbol(config.OfficialRegistryName)) 77 } 78 79 if _, ok := stringset.FromSlice(registry.Types)[newRegistry.Type]; !ok { 80 return errors.Errorf("%s is not a valid type. Supported types are: %s.", 81 style.Symbol(newRegistry.Type), 82 strings.Join(slices.MapString(registry.Types, style.Symbol), ", ")) 83 } 84 85 if registriesContains(config.GetRegistries(cfg), newRegistry.Name) { 86 return errors.Errorf("Buildpack registry %s already exists.", 87 style.Symbol(newRegistry.Name)) 88 } 89 90 if setDefault { 91 cfg.DefaultRegistryName = newRegistry.Name 92 } 93 cfg.Registries = append(cfg.Registries, newRegistry) 94 if err := config.Write(cfg, cfgPath); err != nil { 95 return errors.Wrapf(err, "writing config to %s", cfgPath) 96 } 97 98 logger.Infof("Successfully added %s to registries", style.Symbol(newRegistry.Name)) 99 return nil 100 } 101 102 func removeRegistry(args []string, logger logging.Logger, cfg config.Config, cfgPath string) error { 103 registryName := args[0] 104 105 if registryName == config.OfficialRegistryName { 106 return errors.Errorf("%s is a reserved registry name, please provide a different registry", 107 style.Symbol(config.OfficialRegistryName)) 108 } 109 110 index := findRegistryIndex(cfg.Registries, registryName) 111 if index < 0 { 112 return errors.Errorf("registry %s does not exist", style.Symbol(registryName)) 113 } 114 115 cfg.Registries = removeBPRegistry(index, cfg.Registries) 116 if cfg.DefaultRegistryName == registryName { 117 cfg.DefaultRegistryName = config.OfficialRegistryName 118 } 119 120 if err := config.Write(cfg, cfgPath); err != nil { 121 return errors.Wrapf(err, "writing config to %s", cfgPath) 122 } 123 124 logger.Infof("Successfully removed %s from registries", style.Symbol(registryName)) 125 return nil 126 } 127 128 func listRegistries(args []string, logger logging.Logger, cfg config.Config) { 129 for _, currRegistry := range config.GetRegistries(cfg) { 130 isDefaultRegistry := (currRegistry.Name == cfg.DefaultRegistryName) || 131 (currRegistry.Name == config.OfficialRegistryName && cfg.DefaultRegistryName == "") 132 133 logger.Info(fmtRegistry( 134 currRegistry, 135 isDefaultRegistry, 136 logger.IsVerbose())) 137 } 138 logging.Tip(logger, "Run %s to add additional registries", style.Symbol("pack config registries add")) 139 } 140 141 // Local private funcs 142 func fmtRegistry(registry config.Registry, isDefaultRegistry, isVerbose bool) string { 143 registryOutput := fmt.Sprintf(" %s", registry.Name) 144 if isDefaultRegistry { 145 registryOutput = fmt.Sprintf("* %s", registry.Name) 146 } 147 if isVerbose { 148 registryOutput = fmt.Sprintf("%-12s %s", registryOutput, registry.URL) 149 } 150 151 return registryOutput 152 } 153 154 func registriesContains(registries []config.Registry, registry string) bool { 155 return findRegistryIndex(registries, registry) != -1 156 } 157 158 func findRegistryIndex(registries []config.Registry, registryName string) int { 159 for index, r := range registries { 160 if r.Name == registryName { 161 return index 162 } 163 } 164 165 return -1 166 } 167 168 func removeBPRegistry(index int, registries []config.Registry) []config.Registry { 169 registries[index] = registries[len(registries)-1] 170 return registries[:len(registries)-1] 171 }