diff --git a/pkg/repository/repository.go b/pkg/repository/repository.go index eb7f129..008dd43 100644 --- a/pkg/repository/repository.go +++ b/pkg/repository/repository.go @@ -150,6 +150,22 @@ func Current() (Repository, error) { } rem := filteredRemotes[0] + for _, candidate := range filteredRemotes { + if candidate.Resolved == "" { + continue + } + if candidate.Resolved == "base" { + rem = candidate + } else { + resolved, err := ParseWithHost(candidate.Resolved, candidate.Host) + if err != nil { + return r, err + } + resolved.Host = candidate.Host + return resolved, nil + } + break + } r.Host = rem.Host r.Owner = rem.Owner r.Name = rem.Repo diff --git a/pkg/repository/repository_test.go b/pkg/repository/repository_test.go index 0430eab..f441a19 100644 --- a/pkg/repository/repository_test.go +++ b/pkg/repository/repository_test.go @@ -3,8 +3,10 @@ package repository import ( "testing" + "github.com/cli/go-gh/v2/internal/git" "github.com/cli/go-gh/v2/internal/testutils" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestParse(t *testing.T) { @@ -189,3 +191,57 @@ func TestParseWithHost(t *testing.T) { }) } } + +func TestCurrentUsesResolvedBaseRemote(t *testing.T) { + // Given a higher-ranked fork remote and a parent remote selected by gh + t.Setenv("GH_REPO", "") + testutils.StubConfig(t, ` +hosts: + github.com: + oauth_token: token +`) + t.Chdir(t.TempDir()) + _, _, err := git.Exec("init", "--quiet") + require.NoError(t, err) + _, _, err = git.Exec("remote", "add", "origin", "git@github.com:parent-org/example.git") + require.NoError(t, err) + _, _, err = git.Exec("remote", "add", "github", "git@github.com:my-user/example.git") + require.NoError(t, err) + _, _, err = git.Exec("config", "remote.origin.gh-resolved", "base") + require.NoError(t, err) + + // When the current repository is resolved + repository, err := Current() + + // Then the remote selected by gh is used instead of the name-based ranking + require.NoError(t, err) + assert.Equal(t, "github.com", repository.Host) + assert.Equal(t, "parent-org", repository.Owner) + assert.Equal(t, "example", repository.Name) +} + +func TestCurrentUsesExplicitResolvedRepository(t *testing.T) { + // Given a remote whose gh resolution names a repository on a different host + t.Setenv("GH_REPO", "") + testutils.StubConfig(t, ` +hosts: + github.com: + oauth_token: token +`) + t.Chdir(t.TempDir()) + _, _, err := git.Exec("init", "--quiet") + require.NoError(t, err) + _, _, err = git.Exec("remote", "add", "origin", "git@github.com:my-user/example.git") + require.NoError(t, err) + _, _, err = git.Exec("config", "remote.origin.gh-resolved", "ghe.example/parent-org/example") + require.NoError(t, err) + + // When the current repository is resolved + repository, err := Current() + + // Then the explicit repository is returned using the remote's host + require.NoError(t, err) + assert.Equal(t, "github.com", repository.Host) + assert.Equal(t, "parent-org", repository.Owner) + assert.Equal(t, "example", repository.Name) +}