package credhelper import ( "fmt" "os" "sort" "github.com/charmbracelet/huh" "github.com/spf13/cobra" ) func newSwitchCmd() *cobra.Command { return &cobra.Command{ Use: "switch [registry]", Short: "Switch the active account for a registry", Long: "Switch the active account used for Docker operations.\nDefault registry: " + cfg.DefaultRegistry, Args: cobra.MaximumNArgs(1), RunE: runSwitch, } } func runSwitch(cmd *cobra.Command, args []string) error { serverURL := cfg.DefaultRegistry if len(args) > 0 { serverURL = args[0] } appViewURL := buildAppViewURL(serverURL) sc, err := loadConfigForWrite() if err != nil { return err } reg := sc.findRegistry(appViewURL) if reg == nil || len(reg.Accounts) == 0 { fmt.Fprintf(os.Stderr, "No accounts configured for %s.\n", serverURL) fmt.Fprintf(os.Stderr, "Run: %s login\n", cfg.BinaryName) return nil } if len(reg.Accounts) == 1 { for _, acct := range reg.Accounts { fmt.Fprintf(os.Stderr, "Only one account (%s) — nothing to switch.\n", acct.Handle) } return nil } // For exactly 2 accounts, just toggle if len(reg.Accounts) == 2 { active := reg.activeAccount() for _, acct := range reg.Accounts { if acct != active { reg.setActive(acct) if err := sc.save(); err != nil { return fmt.Errorf("saving config: %w", err) } fmt.Printf("Switched to %s on %s\n", acct.Handle, serverURL) return nil } } } // 3+ accounts: interactive select. Options display the handle but carry the // account's key (DID) as the value. accts := make([]*Account, 0, len(reg.Accounts)) for _, acct := range reg.Accounts { accts = append(accts, acct) } sort.Slice(accts, func(i, j int) bool { return accts[i].Handle < accts[j].Handle }) active := reg.activeAccount() var options []huh.Option[string] for _, acct := range accts { label := acct.Handle if acct == active { label += " (current)" } options = append(options, huh.NewOption(label, acct.key())) } var selected string err = huh.NewSelect[string](). Title("Select account for " + serverURL). Options(options...). Value(&selected). Run() if err != nil { return err } reg.Active = selected if err := sc.save(); err != nil { return fmt.Errorf("saving config: %w", err) } label := selected if acct := reg.find(selected); acct != nil { label = acct.Handle } fmt.Printf("Switched to %s on %s\n", label, serverURL) return nil }