Repository: seachicken/gh-poi (go)

Issue:
GH Poi does not work with multiple github account workaround
**Description**
Bear with me, as this is half way between a bug report and a feature request. I am also willing to help 'fix' this, if given some pointers on where and how.

I like the extension, and would love to use it more, however... If you have used the strategy to handle multiple github accounts (a version of which is [here](https://medium.com/the-andela-way/a-practical-guide-to-managing-multiple-github-accounts-8e7970c8fd46)), you potentially have a non-resolving domain in your remotes somewhere, along the lines of `git@github.com-work:me/blah.git`. The hack in the `.ssh/config` file turns this back into github.com, and everything is good as far as git goes (and the correct identity/ssh key gets used)

However, of course this doesn't work in gh-poi:

```
== DRY RUN ==
✕ Fetching pull requests...
failed to run external command: gh
error connecting to github.com-work
check your internet connection or https://githubstatus.com
```
I'm not entirely sure what I am suggesting here. Something along the lines of: If its an ssh type remote, then check `~/.ssh/config` for a remapping?

I'm not entirely sure. I do know, however, that I am not the only person who uses this method, so thought I would open a conversation on it.

**Additional context**

None that I can think of.


Pull request:
Suport ssh alias name
Fixes #39 

Patch:
diff --git a/conn/command.go b/conn/command.go
index e974b5f..c9d9bcf 100644
--- a/conn/command.go
+++ b/conn/command.go
@@ -32,6 +32,13 @@ func (conn *Connection) GetRemoteNames() (string, error) {
 	return run("git", args)
 }
 
+func (conn *Connection) GetSshConfig(name string) (string, error) {
+	args := []string{
+		"-T", "-G", name,
+	}
+	return run("ssh", args)
+}
+
 func (conn *Connection) GetRepoNames(hostname string, repoName string) (string, error) {
 	args := []string{
 		"repo", "view", hostname + "/" + repoName,
diff --git a/conn/fixtures/ssh/config_github.com.txt b/conn/fixtures/ssh/config_github.com.txt
new file mode 100644
index 0000000..4e21f92
--- /dev/null
+++ b/conn/fixtures/ssh/config_github.com.txt
@@ -0,0 +1,2 @@
+user owner
+hostname github.com
diff --git a/conn/stub.go b/conn/stub.go
index 44382e9..369eea4 100644
--- a/conn/stub.go
+++ b/conn/stub.go
@@ -78,6 +78,18 @@ func (s *Stub) GetRemoteNames(filename string, err error, conf *Conf) *Stub {
 	return s
 }
 
+func (s *Stub) GetSshConfig(filename string, err error, conf *Conf) *Stub {
+	s.t.Helper()
+	configure(
+		s.Conn.
+			EXPECT().
+			GetSshConfig(gomock.Any()).
+			Return(s.readFile("ssh", "config", filename), err),
+		conf,
+	)
+	return s
+}
+
 func (s *Stub) GetRepoNames(filename string, err error, conf *Conf) *Stub {
 	s.t.Helper()
 	configure(
diff --git a/mocks/poi_mock.go b/mocks/poi_mock.go
index aa36ed4..d55099a 100644
--- a/mocks/poi_mock.go
+++ b/mocks/poi_mock.go
@@ -197,6 +197,21 @@ func (mr *MockConnectionMockRecorder) GetRepoNames(hostname, repoName interface{
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRepoNames", reflect.TypeOf((*MockConnection)(nil).GetRepoNames), hostname, repoName)
 }
 
+// GetSshConfig mocks base method.
+func (m *MockConnection) GetSshConfig(name string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetSshConfig", name)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetSshConfig indicates an expected call of GetSshConfig.
+func (mr *MockConnectionMockRecorder) GetSshConfig(name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSshConfig", reflect.TypeOf((*MockConnection)(nil).GetSshConfig), name)
+}
+
 // GetUncommittedChanges mocks base method.
 func (m *MockConnection) GetUncommittedChanges() (string, error) {
 	m.ctrl.T.Helper()
diff --git a/poi.go b/poi.go
index 76766d3..dfa6f6e 100644
--- a/poi.go
+++ b/poi.go
@@ -16,6 +16,7 @@ type (
 	Connection interface {
 		CheckRepos(hostname string, repoNames []string) error
 		GetRemoteNames() (string, error)
+		GetSshConfig(name string) (string, error)
 		GetRepoNames(hostname string, repoName string) (string, error)
 		GetBranchNames() (string, error)
 		GetMergedBranchNames() (string, error)
@@ -81,6 +82,9 @@ func GetBranches(conn Connection, dryRun bool) ([]Branch, error) {
 		remotes := toRemotes(splitLines(remoteNames))
 		if remote, err := getPrimaryRemote(remotes); err == nil {
 			hostname = remote.Hostname
+			if config, err := conn.GetSshConfig(hostname); err == nil {
+				hostname = findHostname(splitLines(config), hostname)
+			}
 			primaryRepoName = remote.RepoName
 		}
 	} else {
@@ -207,6 +211,16 @@ func getPrimaryRemote(remotes []Remote) (Remote, error) {
 	return remotes[0], nil
 }
 
+func findHostname(params []string, defaultName string) string {
+	for _, param := range params {
+		kv := strings.Split(param, " ")
+		if kv[0] == "hostname" {
+			return kv[1]
+		}
+	}
+	return defaultName
+}
+
 func extractMergedBranchNames(mergedNames []string) []string {
 	result := []string{}
 	r := regexp.MustCompile(`^[ *]+(.+)`)


Test patch:
diff --git a/poi_test.go b/poi_test.go
index 3531701..370c718 100644
--- a/poi_test.go
+++ b/poi_test.go
@@ -16,6 +16,7 @@ func Test_ShouldBeDeletableWhenBranchesAssociatedWithMergedPR(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main_issue1", nil, nil).
@@ -69,6 +70,7 @@ func Test_ShouldBeDeletableWhenBranchesAssociatedWithSquashAndMergedPR(t *testin
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -121,6 +123,7 @@ func Test_ShouldBeDeletableWhenBranchesAssociatedWithUpstreamSquashAndMergedPR(t
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin_upstream", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -173,6 +176,7 @@ func Test_ShouldBeDeletableWhenPRCheckoutBranchesAssociatedWithUpstreamSquashAnd
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin_upstream", nil, nil).
 		GetBranchNames("@main_forkMain", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -225,6 +229,7 @@ func Test_ShouldBeDeletableWhenBranchIsCheckedOutWithTheCheckIsFalse(t *testing.
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("main_@issue1", nil, nil).
 		GetMergedBranchNames("main", nil, nil).
@@ -278,6 +283,7 @@ func Test_ShouldBeDeletableWhenBranchIsCheckedOutWithTheCheckIsTrue(t *testing.T
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("main_@issue1", nil, nil).
 		GetMergedBranchNames("main", nil, nil).
@@ -331,6 +337,7 @@ func Test_ShouldBeDeletableWhenBranchIsCheckedOutWithoutADefaultBranch(t *testin
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@issue1", nil, nil).
 		GetMergedBranchNames("empty", nil, nil).
@@ -383,6 +390,7 @@ func Test_ShouldNotDeletableWhenBranchHasUncommittedChanges(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("main_@issue1", nil, nil).
 		GetMergedBranchNames("main", nil, nil).
@@ -436,6 +444,7 @@ func Test_ShouldNotDeletableWhenBranchesAssociatedWithClosedPR(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -488,6 +497,7 @@ func Test_ShouldBeDeletableWhenBranchesAssociatedWithSquashAndMergedAndClosedPRs
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -547,6 +557,7 @@ func Test_ShouldNotDeletableWhenBranchesAssociatedWithNotFullyMergedPR(t *testin
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -602,6 +613,7 @@ func Test_ShouldNotDeletableWhenDefaultBranchAssociatedWithMergedPR(t *testing.T
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -654,6 +666,7 @@ func Test_BranchesAndPRsAreNotAssociatedWhenManyLocalCommitsAreAhead(t *testing.
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -702,6 +715,7 @@ func Test_ShouldBeNoCommitHistoryWhenTheFirstCommitOfATopicBranchIsAssociatedWit
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -743,6 +757,7 @@ func Test_ShouldBeNoCommitHistoryWhenDetachedBranch(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("main_@detached", nil, nil).
 		GetMergedBranchNames("main", nil, nil).
@@ -788,12 +803,43 @@ func Test_ReturnsAnErrorWhenGetRemoteNamesFails(t *testing.T) {
 	assert.NotNil(t, err)
 }
 
+func Test_DoesNotReturnsAnErrorWhenGetSshConfigFails(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+
+	s := conn.Setup(ctrl).
+		CheckRepos(nil, nil).
+		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", errors.New("failed to run external command: ssh"), nil).
+		GetRepoNames("origin", nil, nil).
+		GetBranchNames("@main_issue1", nil, nil).
+		GetMergedBranchNames("@main", nil, nil).
+		GetLog([]conn.LogStub{
+			{"main", "main"}, {"issue1", "issue1"},
+		}, nil, nil).
+		GetAssociatedRefNames([]conn.AssociatedBranchNamesStub{
+			{"a97e9630426df5d34ca9ee77ae1159bdfd5ff8f0", "issue1"},
+			{"6ebe3d30d23531af56bd23b5a098d3ccae2a534a", "main_issue1"},
+		}, nil, nil).
+		GetPullRequests("issue1Merged", nil, nil).
+		GetUncommittedChanges("", nil, nil).
+		GetConfig([]conn.ConfigStub{
+			{"branch.main.merge", "main"},
+			{"branch.issue1.merge", "issue1"},
+		}, nil, nil)
+
+	_, err := GetBranches(s.Conn, false)
+
+	assert.Nil(t, err)
+}
+
 func Test_ReturnsAnErrorWhenGetRepoNamesFails(t *testing.T) {
 	ctrl := gomock.NewController(t)
 	defer ctrl.Finish()
 
 	s := conn.Setup(ctrl).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", errors.New("failed to run external command: gh"), nil)
 
 	_, err := GetBranches(s.Conn, false)
@@ -808,6 +854,7 @@ func Test_ReturnsAnErrorWhenCheckReposFails(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(errors.New("failed to run external command: gh"), nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil)
 
 	_, err := GetBranches(s.Conn, false)
@@ -822,6 +869,7 @@ func Test_ReturnsAnErrorWhenGetBranchNamesFails(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", errors.New("failed to run external command: git"), nil)
 
@@ -837,6 +885,7 @@ func Test_ReturnsAnErrorWhenGetMergedBranchNames(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", errors.New("failed to run external command: git"), nil)
@@ -853,6 +902,7 @@ func Test_ReturnsAnErrorWhenGetLogFails(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -872,6 +922,7 @@ func Test_ReturnsAnErrorWhenGetAssociatedRefNamesFails(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -895,6 +946,7 @@ func Test_ReturnsAnErrorWhenGetPullRequestsFails(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -919,6 +971,7 @@ func Test_ReturnsAnErrorWhenGetUncommittedChangesFails(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("@main_issue1", nil, nil).
 		GetMergedBranchNames("@main", nil, nil).
@@ -948,6 +1001,7 @@ func Test_ReturnsAnErrorWhenCheckoutBranchFails(t *testing.T) {
 	s := conn.Setup(ctrl).
 		CheckRepos(nil, nil).
 		GetRemoteNames("origin", nil, nil).
+		GetSshConfig("github.com", nil, nil).
 		GetRepoNames("origin", nil, nil).
 		GetBranchNames("main_@issue1", nil, nil).
 		GetMergedBranchNames("main", nil, nil).