detached 3819799

feat(cli): add remotes set-token command

commit
3819799dfbb321ada1dd17fcf9a00bb721c50f39
author
bnema · · 2026-01-18 03:17 UTC
parent
db5f449
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +44 -0
M internal/adapters/in/cli/remotes.go +44 -0
@@ -28,6 +28,7 @@ Configuration is stored in ~/.config/gordon/remotes.toml`,
2828 cmd.AddCommand(newRemotesAddCmd())
2929 cmd.AddCommand(newRemotesRemoveCmd())
3030 cmd.AddCommand(newRemotesUseCmd())
31+ cmd.AddCommand(newRemotesSetTokenCmd())
3132
3233 return cmd
3334 }
@@ -246,6 +247,49 @@ Examples:
246247 }
247248 }
248249
250+// newRemotesSetTokenCmd creates the remotes set-token command.
251+func newRemotesSetTokenCmd() *cobra.Command {
252+ return &cobra.Command{
253+ Use: "set-token <name> <token>",
254+ Short: "Set the token for a remote",
255+ Long: `Set or update the authentication token for a saved remote.
256+
257+This is useful when:
258+- The server uses token-based authentication (not password auth)
259+- You have a pre-generated token from 'gordon auth token generate'
260+- You want to update an expired token
261+
262+For servers with password authentication, use 'gordon auth login' instead.
263+
264+Examples:
265+ gordon remotes set-token prod eyJhbGciOiJIUzI1NiIs...
266+ gordon remotes set-token staging $(cat token.txt)`,
267+ Args: cobra.ExactArgs(2),
268+ RunE: func(cmd *cobra.Command, args []string) error {
269+ name := args[0]
270+ token := args[1]
271+
272+ // Verify remote exists
273+ remotes, _, err := remote.ListRemotes()
274+ if err != nil {
275+ return fmt.Errorf("failed to list remotes: %w", err)
276+ }
277+
278+ if _, exists := remotes[name]; !exists {
279+ fmt.Println(styles.RenderError(fmt.Sprintf("Remote '%s' not found", name)))
280+ return nil
281+ }
282+
283+ if err := remote.UpdateRemoteToken(name, token); err != nil {
284+ return fmt.Errorf("failed to update token: %w", err)
285+ }
286+
287+ fmt.Println(styles.RenderSuccess(fmt.Sprintf("Token updated for remote '%s'", name)))
288+ return nil
289+ },
290+ }
291+}
292+
249293 // normalizeURL ensures the URL has a protocol scheme, defaulting to https.
250294 func normalizeURL(url string) string {
251295 if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
@@ -28,6 +28,7 @@ Configuration is stored in ~/.config/gordon/remotes.toml`,
28 cmd.AddCommand(newRemotesAddCmd())28 cmd.AddCommand(newRemotesAddCmd())
29 cmd.AddCommand(newRemotesRemoveCmd())29 cmd.AddCommand(newRemotesRemoveCmd())
30 cmd.AddCommand(newRemotesUseCmd())30 cmd.AddCommand(newRemotesUseCmd())
31+ cmd.AddCommand(newRemotesSetTokenCmd())
31 32
32 return cmd33 return cmd
33 }34 }
@@ -246,6 +247,49 @@ Examples:
246 }247 }
247 }248 }
248 249
250+// newRemotesSetTokenCmd creates the remotes set-token command.
251+func newRemotesSetTokenCmd() *cobra.Command {
252+ return &cobra.Command{
253+ Use: "set-token <name> <token>",
254+ Short: "Set the token for a remote",
255+ Long: `Set or update the authentication token for a saved remote.
256+
257+This is useful when:
258+- The server uses token-based authentication (not password auth)
259+- You have a pre-generated token from 'gordon auth token generate'
260+- You want to update an expired token
261+
262+For servers with password authentication, use 'gordon auth login' instead.
263+
264+Examples:
265+ gordon remotes set-token prod eyJhbGciOiJIUzI1NiIs...
266+ gordon remotes set-token staging $(cat token.txt)`,
267+ Args: cobra.ExactArgs(2),
268+ RunE: func(cmd *cobra.Command, args []string) error {
269+ name := args[0]
270+ token := args[1]
271+
272+ // Verify remote exists
273+ remotes, _, err := remote.ListRemotes()
274+ if err != nil {
275+ return fmt.Errorf("failed to list remotes: %w", err)
276+ }
277+
278+ if _, exists := remotes[name]; !exists {
279+ fmt.Println(styles.RenderError(fmt.Sprintf("Remote '%s' not found", name)))
280+ return nil
281+ }
282+
283+ if err := remote.UpdateRemoteToken(name, token); err != nil {
284+ return fmt.Errorf("failed to update token: %w", err)
285+ }
286+
287+ fmt.Println(styles.RenderSuccess(fmt.Sprintf("Token updated for remote '%s'", name)))
288+ return nil
289+ },
290+ }
291+}
292+
249 // normalizeURL ensures the URL has a protocol scheme, defaulting to https.293 // normalizeURL ensures the URL has a protocol scheme, defaulting to https.
250 func normalizeURL(url string) string {294 func normalizeURL(url string) string {
251 if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {295 if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close