Support for [HOST/]OWNER/REPO format

This commit is contained in:
benebsiny 2024-02-15 23:16:00 +08:00
parent 874da37a24
commit 7dfaa328aa
4 changed files with 241 additions and 21 deletions

View file

@ -13,10 +13,12 @@ import (
"github.com/spf13/cobra"
"net/http"
"strconv"
"strings"
)
type linkOpts struct {
number int32
host string
owner string
repo string
team string
@ -78,6 +80,10 @@ func NewCmdLink(f *cmdutil.Factory, runF func(config linkConfig) error) *cobra.C
return err
}
if err = validateRepoOrTeamFlag(&opts); err != nil {
return err
}
config := linkConfig{
httpClient: f.HttpClient,
config: f.Config,
@ -102,6 +108,49 @@ func NewCmdLink(f *cmdutil.Factory, runF func(config linkConfig) error) *cobra.C
return linkCmd
}
func validateRepoOrTeamFlag(opts *linkOpts) error {
linkedTarget := ""
if opts.repo != "" {
linkedTarget = opts.repo
} else if opts.team != "" {
linkedTarget = opts.team
}
if strings.Contains(linkedTarget, "/") {
nameArgs := strings.Split(linkedTarget, "/")
var host, owner, name string
if len(nameArgs) == 2 {
owner = nameArgs[0]
name = nameArgs[1]
} else if len(nameArgs) == 3 {
host = nameArgs[0]
owner = nameArgs[1]
name = nameArgs[2]
} else {
if opts.repo != "" {
return fmt.Errorf("expected the \"[HOST/]OWNER/REPO\" or \"REPO\" format, got \"%s\"", linkedTarget)
} else if opts.team != "" {
return fmt.Errorf("expected the \"[HOST/]OWNER/TEAM\" or \"TEAM\" format, got \"%s\"", linkedTarget)
}
}
if opts.owner != "" && opts.owner != owner {
return fmt.Errorf("'%s' has different owner from '%s'", linkedTarget, opts.owner)
}
opts.owner = owner
opts.host = host
if opts.repo != "" {
opts.repo = name
} else if opts.team != "" {
opts.team = name
}
}
return nil
}
func runLink(config linkConfig) error {
canPrompt := config.io.CanPrompt()
owner, err := config.client.NewOwner(canPrompt, config.opts.owner)
@ -125,22 +174,25 @@ func runLink(config linkConfig) error {
}
c := api.NewClientFromHTTP(httpClient)
cfg, err := config.config()
if err != nil {
return err
if config.opts.host == "" {
cfg, err := config.config()
if err != nil {
return err
}
host, _ := cfg.Authentication().DefaultHost()
config.opts.host = host
}
host, _ := cfg.Authentication().DefaultHost()
if config.opts.repo != "" {
return linkRepo(c, owner, host, config)
return linkRepo(c, owner, config)
} else if config.opts.team != "" {
return linkTeam(c, owner, host, config)
return linkTeam(c, owner, config)
}
return nil
}
func linkRepo(c *api.Client, owner *queries.Owner, host string, config linkConfig) error {
repo, err := api.GitHubRepo(c, ghrepo.NewWithHost(owner.Login, config.opts.repo, host))
func linkRepo(c *api.Client, owner *queries.Owner, config linkConfig) error {
repo, err := api.GitHubRepo(c, ghrepo.NewWithHost(owner.Login, config.opts.repo, config.opts.host))
if err != nil {
return err
}
@ -154,8 +206,8 @@ func linkRepo(c *api.Client, owner *queries.Owner, host string, config linkConfi
return printResults(config, owner, config.opts.repo)
}
func linkTeam(c *api.Client, owner *queries.Owner, host string, config linkConfig) error {
team, err := api.OrganizationTeam(c, host, owner.Login, config.opts.team)
func linkTeam(c *api.Client, owner *queries.Owner, config linkConfig) error {
team, err := api.OrganizationTeam(c, config.opts.host, owner.Login, config.opts.team)
if err != nil {
return err
}

View file

@ -38,8 +38,8 @@ func TestNewCmdLink(t *testing.T) {
name: "specify-nothing",
cli: "",
wants: linkOpts{
repo: "REPO",
owner: "OWNER",
repo: "REPO",
},
},
{
@ -49,6 +49,35 @@ func TestNewCmdLink(t *testing.T) {
repo: "my-repo",
},
},
{
name: "repo-flag-contains-owner",
cli: "--repo monalisa/my-repo",
wants: linkOpts{
owner: "monalisa",
repo: "my-repo",
},
},
{
name: "repo-flag-contains-owner-and-host",
cli: "--repo github.com/monalisa/my-repo",
wants: linkOpts{
host: "github.com",
owner: "monalisa",
repo: "my-repo",
},
},
{
name: "repo-flag-contains-wrong-format",
cli: "--repo h/e/l/l/o",
wantsErr: true,
wantsErrMsg: "expected the \"[HOST/]OWNER/REPO\" or \"REPO\" format, got \"h/e/l/l/o\"",
},
{
name: "repo-flag-with-owner-different-from-owner-flag",
cli: "--repo monalisa/my-repo --owner leonardo",
wantsErr: true,
wantsErrMsg: "'monalisa/my-repo' has different owner from 'leonardo'",
},
{
name: "team",
cli: "--team my-team",
@ -56,6 +85,35 @@ func TestNewCmdLink(t *testing.T) {
team: "my-team",
},
},
{
name: "team-flag-contains-owner",
cli: "--team my-org/my-team",
wants: linkOpts{
owner: "my-org",
team: "my-team",
},
},
{
name: "team-flag-contains-owner-and-host",
cli: "--team github.com/my-org/my-team",
wants: linkOpts{
host: "github.com",
owner: "my-org",
team: "my-team",
},
},
{
name: "team-flag-contains-wrong-format",
cli: "--team h/e/l/l/o",
wantsErr: true,
wantsErrMsg: "expected the \"[HOST/]OWNER/TEAM\" or \"TEAM\" format, got \"h/e/l/l/o\"",
},
{
name: "team-flag-with-owner-different-from-owner-flag",
cli: "--team my-org/my-team --owner her-org",
wantsErr: true,
wantsErrMsg: "'my-org/my-team' has different owner from 'her-org'",
},
{
name: "number",
cli: "123 --repo my-repo",

View file

@ -13,10 +13,12 @@ import (
"github.com/spf13/cobra"
"net/http"
"strconv"
"strings"
)
type unlinkOpts struct {
number int32
host string
owner string
repo string
team string
@ -78,6 +80,10 @@ func NewCmdUnlink(f *cmdutil.Factory, runF func(config unlinkConfig) error) *cob
return err
}
if err = validateRepoOrTeamFlag(&opts); err != nil {
return err
}
config := unlinkConfig{
httpClient: f.HttpClient,
config: f.Config,
@ -102,6 +108,49 @@ func NewCmdUnlink(f *cmdutil.Factory, runF func(config unlinkConfig) error) *cob
return linkCmd
}
func validateRepoOrTeamFlag(opts *unlinkOpts) error {
unlinkedTarget := ""
if opts.repo != "" {
unlinkedTarget = opts.repo
} else if opts.team != "" {
unlinkedTarget = opts.team
}
if strings.Contains(unlinkedTarget, "/") {
nameArgs := strings.Split(unlinkedTarget, "/")
var host, owner, name string
if len(nameArgs) == 2 {
owner = nameArgs[0]
name = nameArgs[1]
} else if len(nameArgs) == 3 {
host = nameArgs[0]
owner = nameArgs[1]
name = nameArgs[2]
} else {
if opts.repo != "" {
return fmt.Errorf("expected the \"[HOST/]OWNER/REPO\" or \"REPO\" format, got \"%s\"", unlinkedTarget)
} else if opts.team != "" {
return fmt.Errorf("expected the \"[HOST/]OWNER/TEAM\" or \"TEAM\" format, got \"%s\"", unlinkedTarget)
}
}
if opts.owner != "" && opts.owner != owner {
return fmt.Errorf("'%s' has different owner from '%s'", unlinkedTarget, opts.owner)
}
opts.owner = owner
opts.host = host
if opts.repo != "" {
opts.repo = name
} else if opts.team != "" {
opts.team = name
}
}
return nil
}
func runUnlink(config unlinkConfig) error {
canPrompt := config.io.CanPrompt()
owner, err := config.client.NewOwner(canPrompt, config.opts.owner)
@ -125,22 +174,25 @@ func runUnlink(config unlinkConfig) error {
}
c := api.NewClientFromHTTP(httpClient)
cfg, err := config.config()
if err != nil {
return err
if config.opts.host == "" {
cfg, err := config.config()
if err != nil {
return err
}
host, _ := cfg.Authentication().DefaultHost()
config.opts.host = host
}
host, _ := cfg.Authentication().DefaultHost()
if config.opts.repo != "" {
return unlinkRepo(c, owner, host, config)
return unlinkRepo(c, owner, config)
} else if config.opts.team != "" {
return unlinkTeam(c, owner, host, config)
return unlinkTeam(c, owner, config)
}
return nil
}
func unlinkRepo(c *api.Client, owner *queries.Owner, host string, config unlinkConfig) error {
repo, err := api.GitHubRepo(c, ghrepo.NewWithHost(owner.Login, config.opts.repo, host))
func unlinkRepo(c *api.Client, owner *queries.Owner, config unlinkConfig) error {
repo, err := api.GitHubRepo(c, ghrepo.NewWithHost(owner.Login, config.opts.repo, config.opts.host))
if err != nil {
return err
}
@ -154,8 +206,8 @@ func unlinkRepo(c *api.Client, owner *queries.Owner, host string, config unlinkC
return printResults(config, owner, config.opts.repo)
}
func unlinkTeam(c *api.Client, owner *queries.Owner, host string, config unlinkConfig) error {
team, err := api.OrganizationTeam(c, host, owner.Login, config.opts.team)
func unlinkTeam(c *api.Client, owner *queries.Owner, config unlinkConfig) error {
team, err := api.OrganizationTeam(c, config.opts.host, owner.Login, config.opts.team)
if err != nil {
return err
}

View file

@ -49,6 +49,35 @@ func TestNewCmdUnlink(t *testing.T) {
repo: "my-repo",
},
},
{
name: "repo-flag-contains-owner",
cli: "--repo monalisa/my-repo",
wants: unlinkOpts{
owner: "monalisa",
repo: "my-repo",
},
},
{
name: "repo-flag-contains-owner-and-host",
cli: "--repo github.com/monalisa/my-repo",
wants: unlinkOpts{
host: "github.com",
owner: "monalisa",
repo: "my-repo",
},
},
{
name: "repo-flag-contains-wrong-format",
cli: "--repo h/e/l/l/o",
wantsErr: true,
wantsErrMsg: "expected the \"[HOST/]OWNER/REPO\" or \"REPO\" format, got \"h/e/l/l/o\"",
},
{
name: "repo-flag-with-owner-different-from-owner-flag",
cli: "--repo monalisa/my-repo --owner leonardo",
wantsErr: true,
wantsErrMsg: "'monalisa/my-repo' has different owner from 'leonardo'",
},
{
name: "team",
cli: "--team my-team",
@ -56,6 +85,35 @@ func TestNewCmdUnlink(t *testing.T) {
team: "my-team",
},
},
{
name: "team-flag-contains-owner",
cli: "--team my-org/my-team",
wants: unlinkOpts{
owner: "my-org",
team: "my-team",
},
},
{
name: "team-flag-contains-owner-and-host",
cli: "--team github.com/my-org/my-team",
wants: unlinkOpts{
host: "github.com",
owner: "my-org",
team: "my-team",
},
},
{
name: "team-flag-contains-wrong-format",
cli: "--team h/e/l/l/o",
wantsErr: true,
wantsErrMsg: "expected the \"[HOST/]OWNER/TEAM\" or \"TEAM\" format, got \"h/e/l/l/o\"",
},
{
name: "team-flag-with-owner-different-from-owner-flag",
cli: "--team my-org/my-team --owner her-org",
wantsErr: true,
wantsErrMsg: "'my-org/my-team' has different owner from 'her-org'",
},
{
name: "number",
cli: "123 --repo my-repo",