detached 4a715dc

fix: address review findings — DisplayName, dead code, error consistency

commit
4a715dc082445191e50e422f4918bd3e0bdbecd2
author
brice · · 2026-04-04 11:44 UTC
parent
40943be
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +19 -106
M internal/adapters/in/cli/auth.go +8 -28
@@ -276,11 +276,7 @@ func runAuthLoginVerify(ctx context.Context, out io.Writer) error {
276276 return fmt.Errorf("no remote specified. Use --remote or 'gordon remotes use <name>'")
277277 }
278278 if resolved.Token == "" {
279- name := resolved.Name
280- if name == "" {
281- name = resolved.URL
282- }
283- return fmt.Errorf("no token stored for remote '%s'; use: gordon auth login --token <token>", name)
279+ return fmt.Errorf("no token stored for remote '%s'; use: gordon auth login --token <token>", resolved.DisplayName())
284280 }
285281
286282 client := remote.NewClient(resolved.URL, remoteClientOptions(resolved.Token, resolved.InsecureTLS)...)
@@ -288,19 +284,11 @@ func runAuthLoginVerify(ctx context.Context, out io.Writer) error {
288284 defer cancel()
289285
290286 if _, err := client.GetStatus(verifyCtx); err != nil {
291- name := resolved.Name
292- if name == "" {
293- name = resolved.URL
294- }
295- _ = cliWriteLine(out, styles.RenderWarning(fmt.Sprintf("Token verification failed for '%s': %v", name, err)))
287+ _ = cliWriteLine(out, styles.RenderWarning(fmt.Sprintf("Token verification failed for '%s': %v", resolved.DisplayName(), err)))
296288 return fmt.Errorf("authentication failed")
297289 }
298290
299- name := resolved.Name
300- if name == "" {
301- name = resolved.URL
302- }
303- _ = cliWriteLine(out, styles.RenderSuccess(fmt.Sprintf("Authenticated to '%s'", name)))
291+ _ = cliWriteLine(out, styles.RenderSuccess(fmt.Sprintf("Authenticated to '%s'", resolved.DisplayName())))
304292 return nil
305293 }
306294
@@ -334,11 +322,7 @@ func runAuthShowToken(out io.Writer) error {
334322 return fmt.Errorf("no remote specified. Use --remote or 'gordon remotes use <name>'")
335323 }
336324 if resolved.Token == "" {
337- name := resolved.Name
338- if name == "" {
339- name = resolved.URL
340- }
341- return fmt.Errorf("no token found for remote '%s'", name)
325+ return fmt.Errorf("no token found for remote '%s'", resolved.DisplayName())
342326 }
343327
344328 if f, ok := out.(*os.File); ok && isatty.IsTerminal(f.Fd()) {
@@ -708,28 +692,24 @@ Examples:
708692 gordon auth status Check status of active remote
709693 gordon auth status --remote prod Check specific remote`,
710694 RunE: func(cmd *cobra.Command, args []string) error {
711- return runAuthStatus()
695+ return runAuthStatus(cmd.Context())
712696 },
713697 }
714698 return cmd
715699 }
716700
717701 // runAuthStatus checks authentication status for the active remote.
718-func runAuthStatus() error {
702+func runAuthStatus(ctx context.Context) error {
719703 resolved, isRemote := remote.Resolve(remoteFlag, tokenFlag, insecureTLSFlag)
720704 if !isRemote {
721- return fmt.Errorf("no active remote configured. Use 'gordon remotes use <name>' or --remote flag")
705+ return fmt.Errorf("no remote specified. Use --remote or 'gordon remotes use <name>'")
722706 }
723707
724708 client := remote.NewClient(resolved.URL, remoteClientOptions(resolved.Token, resolved.InsecureTLS)...)
725709
726- name := resolved.Name
727- if name == "" {
728- name = resolved.URL
729- }
710+ name := resolved.DisplayName()
730711 fmt.Printf("Checking authentication status for '%s'...\n", name)
731712
732- ctx := context.Background()
733713 status, err := client.VerifyAuth(ctx)
734714 if err != nil {
735715 return handleAuthVerifyError(err, name, resolved.URL)
@@ -276,11 +276,7 @@ func runAuthLoginVerify(ctx context.Context, out io.Writer) error {
276 return fmt.Errorf("no remote specified. Use --remote or 'gordon remotes use <name>'")276 return fmt.Errorf("no remote specified. Use --remote or 'gordon remotes use <name>'")
277 }277 }
278 if resolved.Token == "" {278 if resolved.Token == "" {
279- name := resolved.Name279+ return fmt.Errorf("no token stored for remote '%s'; use: gordon auth login --token <token>", resolved.DisplayName())
280- if name == "" {
281- name = resolved.URL
282- }
283- return fmt.Errorf("no token stored for remote '%s'; use: gordon auth login --token <token>", name)
284 }280 }
285 281
286 client := remote.NewClient(resolved.URL, remoteClientOptions(resolved.Token, resolved.InsecureTLS)...)282 client := remote.NewClient(resolved.URL, remoteClientOptions(resolved.Token, resolved.InsecureTLS)...)
@@ -288,19 +284,11 @@ func runAuthLoginVerify(ctx context.Context, out io.Writer) error {
288 defer cancel()284 defer cancel()
289 285
290 if _, err := client.GetStatus(verifyCtx); err != nil {286 if _, err := client.GetStatus(verifyCtx); err != nil {
291- name := resolved.Name287+ _ = cliWriteLine(out, styles.RenderWarning(fmt.Sprintf("Token verification failed for '%s': %v", resolved.DisplayName(), err)))
292- if name == "" {
293- name = resolved.URL
294- }
295- _ = cliWriteLine(out, styles.RenderWarning(fmt.Sprintf("Token verification failed for '%s': %v", name, err)))
296 return fmt.Errorf("authentication failed")288 return fmt.Errorf("authentication failed")
297 }289 }
298 290
299- name := resolved.Name291+ _ = cliWriteLine(out, styles.RenderSuccess(fmt.Sprintf("Authenticated to '%s'", resolved.DisplayName())))
300- if name == "" {
301- name = resolved.URL
302- }
303- _ = cliWriteLine(out, styles.RenderSuccess(fmt.Sprintf("Authenticated to '%s'", name)))
304 return nil292 return nil
305 }293 }
306 294
@@ -334,11 +322,7 @@ func runAuthShowToken(out io.Writer) error {
334 return fmt.Errorf("no remote specified. Use --remote or 'gordon remotes use <name>'")322 return fmt.Errorf("no remote specified. Use --remote or 'gordon remotes use <name>'")
335 }323 }
336 if resolved.Token == "" {324 if resolved.Token == "" {
337- name := resolved.Name325+ return fmt.Errorf("no token found for remote '%s'", resolved.DisplayName())
338- if name == "" {
339- name = resolved.URL
340- }
341- return fmt.Errorf("no token found for remote '%s'", name)
342 }326 }
343 327
344 if f, ok := out.(*os.File); ok && isatty.IsTerminal(f.Fd()) {328 if f, ok := out.(*os.File); ok && isatty.IsTerminal(f.Fd()) {
@@ -708,28 +692,24 @@ Examples:
708 gordon auth status Check status of active remote692 gordon auth status Check status of active remote
709 gordon auth status --remote prod Check specific remote`,693 gordon auth status --remote prod Check specific remote`,
710 RunE: func(cmd *cobra.Command, args []string) error {694 RunE: func(cmd *cobra.Command, args []string) error {
711- return runAuthStatus()695+ return runAuthStatus(cmd.Context())
712 },696 },
713 }697 }
714 return cmd698 return cmd
715 }699 }
716 700
717 // runAuthStatus checks authentication status for the active remote.701 // runAuthStatus checks authentication status for the active remote.
718-func runAuthStatus() error {702+func runAuthStatus(ctx context.Context) error {
719 resolved, isRemote := remote.Resolve(remoteFlag, tokenFlag, insecureTLSFlag)703 resolved, isRemote := remote.Resolve(remoteFlag, tokenFlag, insecureTLSFlag)
720 if !isRemote {704 if !isRemote {
721- return fmt.Errorf("no active remote configured. Use 'gordon remotes use <name>' or --remote flag")705+ return fmt.Errorf("no remote specified. Use --remote or 'gordon remotes use <name>'")
722 }706 }
723 707
724 client := remote.NewClient(resolved.URL, remoteClientOptions(resolved.Token, resolved.InsecureTLS)...)708 client := remote.NewClient(resolved.URL, remoteClientOptions(resolved.Token, resolved.InsecureTLS)...)
725 709
726- name := resolved.Name710+ name := resolved.DisplayName()
727- if name == "" {
728- name = resolved.URL
729- }
730 fmt.Printf("Checking authentication status for '%s'...\n", name)711 fmt.Printf("Checking authentication status for '%s'...\n", name)
731 712
732- ctx := context.Background()
733 status, err := client.VerifyAuth(ctx)713 status, err := client.VerifyAuth(ctx)
734 if err != nil {714 if err != nil {
735 return handleAuthVerifyError(err, name, resolved.URL)715 return handleAuthVerifyError(err, name, resolved.URL)
M internal/adapters/in/cli/remote/config.go +11 -28
@@ -172,34 +172,6 @@ func ResolveTokenForRemote(name string, entry RemoteEntry) string {
172172 return ""
173173 }
174174
175-// ResolveInsecureTLSForRemote resolves insecure TLS behavior for a named remote.
176-// Precedence: flag > env > specific remote config.
177-func ResolveInsecureTLSForRemote(flagInsecure bool, remoteName string) bool {
178- remotes, _ := LoadRemotes("")
179- return resolveInsecureTLS(flagInsecure, remotes, remoteName)
180-}
181-
182-func resolveInsecureTLS(flagInsecure bool, remotes *ClientConfig, remoteName string) bool {
183- if flagInsecure {
184- return true
185- }
186-
187- if env := os.Getenv("GORDON_INSECURE"); env != "" {
188- if value, err := strconv.ParseBool(env); err == nil {
189- return value
190- }
191- fmt.Fprintf(os.Stderr, "WARNING: invalid GORDON_INSECURE value %q, ignoring\n", env)
192- }
193-
194- if remoteName != "" && remotes != nil {
195- if remote, ok := remotes.Remotes[remoteName]; ok && remote.InsecureTLS {
196- return true
197- }
198- }
199-
200- return false
201-}
202-
203175 // ResolvedRemote holds the fully resolved remote target.
204176 // Name is empty for ad-hoc URLs passed directly via flag or env.
205177 type ResolvedRemote struct {
@@ -209,6 +181,14 @@ type ResolvedRemote struct {
209181 InsecureTLS bool
210182 }
211183
184+// DisplayName returns the remote name, or the URL if unnamed (ad-hoc).
185+func (r *ResolvedRemote) DisplayName() string {
186+ if r.Name != "" {
187+ return r.Name
188+ }
189+ return r.URL
190+}
191+
212192 // resolveTokenForTarget resolves the authentication token.
213193 // Precedence: flag > GORDON_TOKEN env > stored token for named remote.
214194 func resolveTokenForTarget(flagToken, name string, remotes *ClientConfig) string {
@@ -258,6 +238,9 @@ func Resolve(flagRemote, flagToken string, flagInsecure bool) (*ResolvedRemote,
258238 remotes, _ := LoadRemotes("")
259239
260240 name, url, found := resolveTarget(flagRemote, remotes)
241+ if !found && flagRemote != "" && !strings.HasPrefix(flagRemote, "http://") && !strings.HasPrefix(flagRemote, "https://") {
242+ return nil, false
243+ }
261244 if !found {
262245 if envRemote := os.Getenv("GORDON_REMOTE"); envRemote != "" {
263246 name, url, found = resolveTarget(envRemote, remotes)
@@ -172,34 +172,6 @@ func ResolveTokenForRemote(name string, entry RemoteEntry) string {
172 return ""172 return ""
173 }173 }
174 174
175-// ResolveInsecureTLSForRemote resolves insecure TLS behavior for a named remote.
176-// Precedence: flag > env > specific remote config.
177-func ResolveInsecureTLSForRemote(flagInsecure bool, remoteName string) bool {
178- remotes, _ := LoadRemotes("")
179- return resolveInsecureTLS(flagInsecure, remotes, remoteName)
180-}
181-
182-func resolveInsecureTLS(flagInsecure bool, remotes *ClientConfig, remoteName string) bool {
183- if flagInsecure {
184- return true
185- }
186-
187- if env := os.Getenv("GORDON_INSECURE"); env != "" {
188- if value, err := strconv.ParseBool(env); err == nil {
189- return value
190- }
191- fmt.Fprintf(os.Stderr, "WARNING: invalid GORDON_INSECURE value %q, ignoring\n", env)
192- }
193-
194- if remoteName != "" && remotes != nil {
195- if remote, ok := remotes.Remotes[remoteName]; ok && remote.InsecureTLS {
196- return true
197- }
198- }
199-
200- return false
201-}
202-
203 // ResolvedRemote holds the fully resolved remote target.175 // ResolvedRemote holds the fully resolved remote target.
204 // Name is empty for ad-hoc URLs passed directly via flag or env.176 // Name is empty for ad-hoc URLs passed directly via flag or env.
205 type ResolvedRemote struct {177 type ResolvedRemote struct {
@@ -209,6 +181,14 @@ type ResolvedRemote struct {
209 InsecureTLS bool181 InsecureTLS bool
210 }182 }
211 183
184+// DisplayName returns the remote name, or the URL if unnamed (ad-hoc).
185+func (r *ResolvedRemote) DisplayName() string {
186+ if r.Name != "" {
187+ return r.Name
188+ }
189+ return r.URL
190+}
191+
212 // resolveTokenForTarget resolves the authentication token.192 // resolveTokenForTarget resolves the authentication token.
213 // Precedence: flag > GORDON_TOKEN env > stored token for named remote.193 // Precedence: flag > GORDON_TOKEN env > stored token for named remote.
214 func resolveTokenForTarget(flagToken, name string, remotes *ClientConfig) string {194 func resolveTokenForTarget(flagToken, name string, remotes *ClientConfig) string {
@@ -258,6 +238,9 @@ func Resolve(flagRemote, flagToken string, flagInsecure bool) (*ResolvedRemote,
258 remotes, _ := LoadRemotes("")238 remotes, _ := LoadRemotes("")
259 239
260 name, url, found := resolveTarget(flagRemote, remotes)240 name, url, found := resolveTarget(flagRemote, remotes)
241+ if !found && flagRemote != "" && !strings.HasPrefix(flagRemote, "http://") && !strings.HasPrefix(flagRemote, "https://") {
242+ return nil, false
243+ }
261 if !found {244 if !found {
262 if envRemote := os.Getenv("GORDON_REMOTE"); envRemote != "" {245 if envRemote := os.Getenv("GORDON_REMOTE"); envRemote != "" {
263 name, url, found = resolveTarget(envRemote, remotes)246 name, url, found = resolveTarget(envRemote, remotes)
D internal/adapters/in/cli/remote/config_test.go +0 -50
@@ -1,50 +0,0 @@
1-package remote
2-
3-import (
4- "testing"
5-)
6-
7-func TestResolveInsecureTLSForRemote_FromRemoteEntry(t *testing.T) {
8- t.Setenv("XDG_CONFIG_HOME", t.TempDir())
9-
10- remotes := &ClientConfig{
11- Active: "prod",
12- Remotes: map[string]RemoteEntry{
13- "prod": {
14- URL: "https://gordon.example.com",
15- InsecureTLS: true,
16- },
17- },
18- }
19- if err := SaveRemotes("", remotes); err != nil {
20- t.Fatalf("save remotes: %v", err)
21- }
22-
23- if !ResolveInsecureTLSForRemote(false, "prod") {
24- t.Fatalf("expected insecure TLS true from remote entry")
25- }
26-}
27-
28-func TestResolveInsecureTLSForRemote_DefaultSecure(t *testing.T) {
29- t.Setenv("XDG_CONFIG_HOME", t.TempDir())
30-
31- // With no flag, no env, and no config, TLS should be secure by default
32- if ResolveInsecureTLSForRemote(false, "") {
33- t.Fatalf("expected insecure TLS false by default")
34- }
35-}
36-
37-func TestResolveInsecureTLSForRemote_EnvAndFlagPrecedence(t *testing.T) {
38- t.Setenv("XDG_CONFIG_HOME", t.TempDir())
39- t.Setenv("GORDON_INSECURE", "true")
40-
41- // env=true should enable when flag is false
42- if !ResolveInsecureTLSForRemote(false, "") {
43- t.Fatalf("expected insecure TLS true from env")
44- }
45-
46- // flag=true should always enable
47- if !ResolveInsecureTLSForRemote(true, "") {
48- t.Fatalf("expected insecure TLS true from flag")
49- }
50-}
@@ -1,50 +0,0 @@
1-package remote
2-
3-import (
4- "testing"
5-)
6-
7-func TestResolveInsecureTLSForRemote_FromRemoteEntry(t *testing.T) {
8- t.Setenv("XDG_CONFIG_HOME", t.TempDir())
9-
10- remotes := &ClientConfig{
11- Active: "prod",
12- Remotes: map[string]RemoteEntry{
13- "prod": {
14- URL: "https://gordon.example.com",
15- InsecureTLS: true,
16- },
17- },
18- }
19- if err := SaveRemotes("", remotes); err != nil {
20- t.Fatalf("save remotes: %v", err)
21- }
22-
23- if !ResolveInsecureTLSForRemote(false, "prod") {
24- t.Fatalf("expected insecure TLS true from remote entry")
25- }
26-}
27-
28-func TestResolveInsecureTLSForRemote_DefaultSecure(t *testing.T) {
29- t.Setenv("XDG_CONFIG_HOME", t.TempDir())
30-
31- // With no flag, no env, and no config, TLS should be secure by default
32- if ResolveInsecureTLSForRemote(false, "") {
33- t.Fatalf("expected insecure TLS false by default")
34- }
35-}
36-
37-func TestResolveInsecureTLSForRemote_EnvAndFlagPrecedence(t *testing.T) {
38- t.Setenv("XDG_CONFIG_HOME", t.TempDir())
39- t.Setenv("GORDON_INSECURE", "true")
40-
41- // env=true should enable when flag is false
42- if !ResolveInsecureTLSForRemote(false, "") {
43- t.Fatalf("expected insecure TLS true from env")
44- }
45-
46- // flag=true should always enable
47- if !ResolveInsecureTLSForRemote(true, "") {
48- t.Fatalf("expected insecure TLS true from flag")
49- }
50-}

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