diff --git a/pkg/cmd/auth/switch/switch.go b/pkg/cmd/auth/switch/switch.go index 750af098b..76abbe705 100644 --- a/pkg/cmd/auth/switch/switch.go +++ b/pkg/cmd/auth/switch/switch.go @@ -68,16 +68,6 @@ type hostUser struct { type candidates []hostUser -func (c candidates) inactiveOptions() []hostUser { - var inactive []hostUser - for _, candidate := range c { - if !candidate.active { - inactive = append(inactive, candidate) - } - } - return inactive -} - func switchRun(opts *SwitchOptions) error { hostname := opts.Hostname username := opts.Username @@ -125,15 +115,20 @@ func switchRun(opts *SwitchOptions) error { } } - inactiveCandidates := candidates.inactiveOptions() if len(candidates) == 0 { return errors.New("no accounts matched that criteria") } else if len(candidates) == 1 { hostname = candidates[0].host username = candidates[0].user - } else if len(inactiveCandidates) == 1 { - hostname = inactiveCandidates[0].host - username = inactiveCandidates[0].user + } else if len(candidates) == 2 && + candidates[0].host == candidates[1].host { + // If there is a single host with two users, automatically swith to the + // inactive user without prompting. + hostname = candidates[0].host + username = candidates[0].user + if candidates[0].active { + username = candidates[1].user + } } else if !opts.IO.CanPrompt() { return errors.New("unable to determine which account to switch to, please specify `--hostname` and `--user`") } else { diff --git a/pkg/cmd/auth/switch/switch_test.go b/pkg/cmd/auth/switch/switch_test.go index 87148f266..efb69a56b 100644 --- a/pkg/cmd/auth/switch/switch_test.go +++ b/pkg/cmd/auth/switch/switch_test.go @@ -320,6 +320,38 @@ func TestSwitchRun(t *testing.T) { stderr: "✓ Switched active account for ghe.io to inactive-user", }, }, + { + name: "options need to be disambiguated given two hosts, one with two users", + opts: SwitchOptions{}, + cfgHosts: []hostUsers{ + {"github.com", []user{ + {"inactive-user", "inactive-user-token"}, + {"active-user", "active-user-token"}, + }}, + {"ghe.io", []user{ + {"active-user", "active-user-token"}, + }}, + }, + prompterStubs: func(pm *prompter.PrompterMock) { + pm.SelectFunc = func(prompt, _ string, opts []string) (int, error) { + require.Equal(t, "What account do you want to switch to?", prompt) + require.Equal(t, []string{ + "inactive-user (github.com)", + "active-user (github.com) - active", + "active-user (ghe.io) - active", + }, opts) + + return prompter.IndexFor(opts, "inactive-user (github.com)") + } + }, + expectedSuccess: successfulExpectation{ + switchedHost: "github.com", + activeUser: "inactive-user", + activeToken: "inactive-user-token", + hostsCfg: "github.com:\n git_protocol: ssh\n users:\n inactive-user:\n active-user:\n user: inactive-user\nghe.io:\n git_protocol: ssh\n users:\n active-user:\n user: active-user\n", + stderr: "✓ Switched active account for github.com to inactive-user", + }, + }, { name: "when switching fails due to something other than user error, an informative message is printed to explain their new state", opts: SwitchOptions{ @@ -351,6 +383,9 @@ func TestSwitchRun(t *testing.T) { pm := &prompter.PrompterMock{} tt.prompterStubs(pm) tt.opts.Prompter = pm + defer func() { + require.Len(t, pm.SelectCalls(), 1) + }() } for _, hostUsers := range tt.cfgHosts {