Issue transfer early arg parsing

This commit is contained in:
William Martin 2025-04-16 16:01:05 +02:00
parent 5c67c1944b
commit f55138c896
2 changed files with 79 additions and 13 deletions

View file

@ -20,7 +20,7 @@ type TransferOptions struct {
IO *iostreams.IOStreams
BaseRepo func() (ghrepo.Interface, error)
IssueSelector string
IssueNumber int
DestRepoSelector string
}
@ -36,8 +36,23 @@ func NewCmdTransfer(f *cmdutil.Factory, runF func(*TransferOptions) error) *cobr
Short: "Transfer issue to another repository",
Args: cmdutil.ExactArgs(2, "issue and destination repository are required"),
RunE: func(cmd *cobra.Command, args []string) error {
opts.BaseRepo = f.BaseRepo
opts.IssueSelector = args[0]
issueNumber, baseRepo, err := shared.ParseIssueFromArg(args[0])
if err != nil {
return err
}
// If the args provided the base repo then use that directly.
if baseRepo, present := baseRepo.Value(); present {
opts.BaseRepo = func() (ghrepo.Interface, error) {
return baseRepo, nil
}
} else {
// support `-R, --repo` override
opts.BaseRepo = f.BaseRepo
}
opts.IssueNumber = issueNumber
opts.DestRepoSelector = args[1]
if runF != nil {
@ -57,7 +72,12 @@ func transferRun(opts *TransferOptions) error {
return err
}
issue, baseRepo, err := shared.IssueFromArgWithFields(httpClient, opts.BaseRepo, opts.IssueSelector, []string{"id", "number"})
baseRepo, err := opts.BaseRepo()
if err != nil {
return err
}
issue, err := shared.FindIssueOrPR(httpClient, baseRepo, opts.IssueNumber, []string{"id", "number"})
if err != nil {
return err
}

View file

@ -15,6 +15,7 @@ import (
"github.com/cli/cli/v2/test"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func runCommand(rt http.RoundTripper, cli string) (*test.CmdOut, error) {
@ -57,18 +58,49 @@ func runCommand(rt http.RoundTripper, cli string) (*test.CmdOut, error) {
func TestNewCmdTransfer(t *testing.T) {
tests := []struct {
name string
cli string
wants TransferOptions
wantErr string
name string
cli string
wants TransferOptions
wantBaseRepo ghrepo.Interface
wantErr bool
}{
{
name: "issue name",
cli: "3252 OWNER/REPO",
name: "no argument",
cli: "",
wantErr: true,
},
{
name: "issue number argument",
cli: "--repo cli/repo 23 OWNER/REPO",
wants: TransferOptions{
IssueSelector: "3252",
IssueNumber: 23,
DestRepoSelector: "OWNER/REPO",
},
wantBaseRepo: ghrepo.New("cli", "repo"),
},
{
name: "argument is hash prefixed number",
// Escaping is required here to avoid what I think is shellex treating it as a comment.
cli: "--repo cli/repo \\#23 OWNER/REPO",
wants: TransferOptions{
IssueNumber: 23,
DestRepoSelector: "OWNER/REPO",
},
wantBaseRepo: ghrepo.New("cli", "repo"),
},
{
name: "argument is a URL",
cli: "https://github.com/cli/cli/issues/23 OWNER/REPO",
wants: TransferOptions{
IssueNumber: 23,
DestRepoSelector: "OWNER/REPO",
},
wantBaseRepo: ghrepo.New("cli", "cli"),
},
{
name: "argument cannot be parsed to an issue",
cli: "unparseable OWNER/REPO",
wantErr: true,
},
}
@ -84,15 +116,29 @@ func TestNewCmdTransfer(t *testing.T) {
gotOpts = opts
return nil
})
cmdutil.EnableRepoOverride(cmd, f)
cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{})
_, cErr := cmd.ExecuteC()
assert.NoError(t, cErr)
assert.Equal(t, tt.wants.IssueSelector, gotOpts.IssueSelector)
if tt.wantErr {
require.Error(t, cErr)
return
}
require.NoError(t, cErr)
assert.Equal(t, tt.wants.IssueNumber, gotOpts.IssueNumber)
assert.Equal(t, tt.wants.DestRepoSelector, gotOpts.DestRepoSelector)
actualBaseRepo, err := gotOpts.BaseRepo()
require.NoError(t, err)
assert.True(
t,
ghrepo.IsSame(tt.wantBaseRepo, actualBaseRepo),
"expected base repo %+v, got %+v", tt.wantBaseRepo, actualBaseRepo,
)
})
}
}