diff --git a/pkg/repository/repository.go b/pkg/repository/repository.go index eb7f129..58bcb43 100644 --- a/pkg/repository/repository.go +++ b/pkg/repository/repository.go @@ -5,6 +5,7 @@ package repository import ( "errors" "fmt" + "net/url" "os" "strings" @@ -133,14 +134,7 @@ func Current() (Repository, error) { } translator := ssh.NewTranslator() - for _, r := range remotes { - if r.FetchURL != nil { - r.FetchURL = translator.Translate(r.FetchURL) - } - if r.PushURL != nil { - r.PushURL = translator.Translate(r.PushURL) - } - } + translateRemotes(remotes, translator.Translate) hosts := auth.KnownHosts() @@ -156,3 +150,30 @@ func Current() (Repository, error) { return r, nil } + +func translateRemotes(remotes git.RemoteSet, translate func(*url.URL) *url.URL) { + for _, remote := range remotes { + hasFetchInfo := false + if remote.FetchURL != nil { + remote.FetchURL = translate(remote.FetchURL) + hasFetchInfo = updateRemoteInfo(remote, remote.FetchURL) + } + if remote.PushURL != nil { + remote.PushURL = translate(remote.PushURL) + if !hasFetchInfo { + updateRemoteInfo(remote, remote.PushURL) + } + } + } +} + +func updateRemoteInfo(remote *git.Remote, u *url.URL) bool { + host, owner, repo, err := git.RepoInfoFromURL(u) + if err != nil { + return false + } + remote.Host = host + remote.Owner = owner + remote.Repo = repo + return true +} diff --git a/pkg/repository/repository_test.go b/pkg/repository/repository_test.go index 0430eab..b1a44c2 100644 --- a/pkg/repository/repository_test.go +++ b/pkg/repository/repository_test.go @@ -1,12 +1,67 @@ package repository import ( + "net/url" "testing" + "github.com/cli/go-gh/v2/internal/git" "github.com/cli/go-gh/v2/internal/testutils" "github.com/stretchr/testify/assert" ) +func TestTranslateRemotesRefreshesRepositoryInfo(t *testing.T) { + translate := func(u *url.URL) *url.URL { + translated := *u + translated.Host = "github.com" + return &translated + } + + t.Run("SSH host alias", func(t *testing.T) { + u, err := url.Parse("ssh://git@github.com-work/owner/repo.git") + if err != nil { + t.Fatal(err) + } + remotes := git.RemoteSet{&git.Remote{ + Name: "origin", + FetchURL: u, + Host: "github.com-work", + Owner: "owner", + Repo: "repo", + }} + + translateRemotes(remotes, translate) + + filtered := remotes.FilterByHosts([]string{"github.com"}) + assert.Len(t, filtered, 1) + assert.Equal(t, "github.com", remotes[0].Host) + assert.Equal(t, "owner", remotes[0].Owner) + assert.Equal(t, "repo", remotes[0].Repo) + }) + + t.Run("invalid fetch URL falls back to push URL", func(t *testing.T) { + fetchURL, err := url.Parse("ssh://git@github.com-work/") + if err != nil { + t.Fatal(err) + } + pushURL, err := url.Parse("ssh://git@github.com-work/owner/repo.git") + if err != nil { + t.Fatal(err) + } + remotes := git.RemoteSet{&git.Remote{ + Name: "origin", + FetchURL: fetchURL, + PushURL: pushURL, + Host: "github.com-work", + }} + + translateRemotes(remotes, translate) + + assert.Equal(t, "github.com", remotes[0].Host) + assert.Equal(t, "owner", remotes[0].Owner) + assert.Equal(t, "repo", remotes[0].Repo) + }) +} + func TestParse(t *testing.T) { testutils.StubConfig(t, "")