A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
1package main
2
3import (
4 "fmt"
5 "os"
6 "sort"
7
8 "github.com/charmbracelet/huh"
9 "github.com/spf13/cobra"
10)
11
12func newSwitchCmd() *cobra.Command {
13 return &cobra.Command{
14 Use: "switch [registry]",
15 Short: "Switch the active account for a registry",
16 Long: "Switch the active account used for Docker operations.\nDefault registry: atcr.io",
17 Args: cobra.MaximumNArgs(1),
18 RunE: runSwitch,
19 }
20}
21
22func runSwitch(cmd *cobra.Command, args []string) error {
23 serverURL := "atcr.io"
24 if len(args) > 0 {
25 serverURL = args[0]
26 }
27
28 appViewURL := buildAppViewURL(serverURL)
29
30 cfg, err := loadConfig()
31 if err != nil {
32 return fmt.Errorf("loading config: %w", err)
33 }
34
35 reg := cfg.findRegistry(appViewURL)
36 if reg == nil || len(reg.Accounts) == 0 {
37 fmt.Fprintf(os.Stderr, "No accounts configured for %s.\n", serverURL)
38 fmt.Fprintf(os.Stderr, "Run: docker-credential-atcr login\n")
39 return nil
40 }
41
42 if len(reg.Accounts) == 1 {
43 for h := range reg.Accounts {
44 fmt.Fprintf(os.Stderr, "Only one account (%s) — nothing to switch.\n", h)
45 }
46 return nil
47 }
48
49 // For exactly 2 accounts, just toggle
50 if len(reg.Accounts) == 2 {
51 for h := range reg.Accounts {
52 if h != reg.Active {
53 reg.Active = h
54 if err := cfg.save(); err != nil {
55 return fmt.Errorf("saving config: %w", err)
56 }
57 fmt.Printf("Switched to %s on %s\n", h, serverURL)
58 return nil
59 }
60 }
61 }
62
63 // 3+ accounts: interactive select
64 var handles []string
65 for h := range reg.Accounts {
66 handles = append(handles, h)
67 }
68 sort.Strings(handles)
69
70 var options []huh.Option[string]
71 for _, h := range handles {
72 label := h
73 if h == reg.Active {
74 label += " (current)"
75 }
76 options = append(options, huh.NewOption(label, h))
77 }
78
79 var selected string
80 err = huh.NewSelect[string]().
81 Title("Select account for " + serverURL).
82 Options(options...).
83 Value(&selected).
84 Run()
85 if err != nil {
86 return err
87 }
88
89 reg.Active = selected
90 if err := cfg.save(); err != nil {
91 return fmt.Errorf("saving config: %w", err)
92 }
93
94 fmt.Printf("Switched to %s on %s\n", selected, serverURL)
95 return nil
96}