added requested changes

This commit is contained in:
Parth Patel 2021-10-21 11:27:02 -04:00
parent 5946c98096
commit dd98c7f51f
2 changed files with 225 additions and 234 deletions

View file

@ -8,6 +8,7 @@ import (
"net/http"
"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/context"
"github.com/cli/cli/v2/git"
@ -25,7 +26,6 @@ type RenameOptions struct {
Config func() (config.Config, error)
BaseRepo func() (ghrepo.Interface, error)
Remotes func() (context.Remotes, error)
oldRepoSelector string
newRepoSelector string
}
@ -46,32 +46,39 @@ func NewCmdRename(f *cmdutil.Factory, runf func(*RenameOptions) error) *cobra.Co
}
cmd := &cobra.Command{
Use: "rename [-R] [<repository>] [<new-name>]",
Use: "rename [<repository>] [<new-name>]",
Short: "Rename a repository",
Long: `Rename a GitHub repository
Long: heredoc.Doc(`Rename a GitHub repository
With no argument, the repository for the current directory is renamed using a prompt
With one argument, the repository of the current directory is renamed using the argument
With '-R', and two arguments the given repository is replaced with the new name `,
With '-R', and two arguments the given repository is replaced with the new name`),
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
opts.BaseRepo = f.BaseRepo
opts.newRepoSelector = args[0]
} else {
if !opts.IO.CanPrompt() {
return &cmdutil.FlagError{
Err: errors.New("could not prompt: proceed with prompt")}
}
} else if !opts.IO.CanPrompt() {
return &cmdutil.FlagError{
Err: errors.New("could not prompt: proceed with a repo name")}
}
if runf != nil {
return runf(opts)
}
return renameRun(opts)
},
}
cmd.Flags().StringVarP(&opts.oldRepoSelector, "repo", "R", "", "pass in two arguments to rename a repository")
cmdutil.EnableRepoOverride(cmd, f)
return cmd
}
func renameRun(opts *RenameOptions) error {
cs := opts.IO.ColorScheme()
httpClient, err := opts.HttpClient()
if err != nil {
@ -80,71 +87,48 @@ func renameRun(opts *RenameOptions) error {
apiClient := api.NewClientFromHTTP(httpClient)
var input renameRepo
var oldRepo ghrepo.Interface
var newRepo ghrepo.Interface
var baseRemote *context.Remote
newRepoName := opts.newRepoSelector
if opts.oldRepoSelector == "" {
var newRepoName string
currRepo, err := opts.BaseRepo()
currRepo, err := opts.BaseRepo()
if err != nil {
return err
}
if opts.newRepoSelector == "" {
err = prompt.SurveyAskOne(
&survey.Input{
Message: "Rename current repo to: ",
},
&newRepoName,
)
if err != nil {
return err
}
if opts.newRepoSelector != "" && opts.oldRepoSelector == "" {
newRepoName = opts.newRepoSelector
} else {
err = prompt.SurveyAskOne(
&survey.Input{
Message: "Rename current repo to: ",
},
&newRepoName,
)
if err != nil {
return err
}
}
oldRepo = ghrepo.NewWithHost(currRepo.RepoOwner(), currRepo.RepoName(), currRepo.RepoHost())
newRepo = ghrepo.NewWithHost(currRepo.RepoOwner(), newRepoName, currRepo.RepoHost())
input = renameRepo{
RepoHost: currRepo.RepoHost(),
RepoOwner: currRepo.RepoOwner(),
RepoName: currRepo.RepoName(),
Name: newRepoName,
}
} else {
oldRepoURL := opts.oldRepoSelector
newRepoName := opts.newRepoSelector
currRepo, err := ghrepo.FromFullName(oldRepoURL)
if err != nil {
return fmt.Errorf("argument error: %w", err)
}
oldRepo = ghrepo.NewWithHost(currRepo.RepoOwner(), currRepo.RepoName(), currRepo.RepoHost())
input = renameRepo{
RepoHost: currRepo.RepoHost(),
RepoOwner: currRepo.RepoOwner(),
RepoName: currRepo.RepoName(),
Name: newRepoName,
}
}
err = runRename(apiClient, oldRepo.RepoHost(), input)
input = renameRepo{
RepoHost: currRepo.RepoHost(),
RepoOwner: currRepo.RepoOwner(),
RepoName: currRepo.RepoName(),
Name: newRepoName,
}
newRepo = ghrepo.NewWithHost(currRepo.RepoOwner(), newRepoName, currRepo.RepoHost())
err = runRename(apiClient, currRepo.RepoHost(), input)
if err != nil {
return fmt.Errorf("API called failed: %s, please check your parameters", err)
}
if opts.oldRepoSelector == "" {
if opts.newRepoSelector == "" {
cfg, err := opts.Config()
if err != nil {
return err
}
protocol, err := cfg.Get(oldRepo.RepoHost(), "git_protocol")
protocol, err := cfg.Get(currRepo.RepoHost(), "git_protocol")
if err != nil {
return err
}
@ -154,7 +138,7 @@ func renameRun(opts *RenameOptions) error {
return err
}
baseRemote, err := remotes.FindByRepo(oldRepo.RepoOwner(), oldRepo.RepoName())
baseRemote, err = remotes.FindByRepo(currRepo.RepoOwner(), currRepo.RepoName())
if err != nil {
return err
}
@ -168,8 +152,8 @@ func renameRun(opts *RenameOptions) error {
if opts.IO.IsStdoutTTY() {
fmt.Fprintf(opts.IO.Out, "%s Renamed repository %s\n", cs.SuccessIcon(), input.RepoOwner+"/"+input.Name)
if opts.oldRepoSelector == "" {
fmt.Fprintf(opts.IO.Out, `%s Updated the "origin" remote`, cs.SuccessIcon())
if opts.newRepoSelector == "" {
fmt.Fprintf(opts.IO.Out, "%s Updated the %q remote", cs.SuccessIcon(), baseRemote.Name)
}
}

View file

@ -1,186 +1,193 @@
package rename
// import (
// "fmt"
// "net/http"
// "testing"
import (
"bytes"
"net/http"
"testing"
// "github.com/cli/cli/v2/pkg/cmdutil"
// "github.com/cli/cli/v2/internal/ghrepo"
// "github.com/cli/cli/v2/pkg/httpmock"
// "github.com/cli/cli/v2/pkg/iostreams"
// "github.com/cli/cli/v2/pkg/prompt"
"github.com/cli/cli/v2/context"
"github.com/cli/cli/v2/git"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/httpmock"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/prompt"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
)
// "github.com/google/shlex"
// "github.com/stretchr/testify/assert"
// "github.com/stretchr/testify/require"
// )
func TestNewCmdRename(t *testing.T) {
testCases := []struct {
name string
input string
output RenameOptions
errMsg string
tty bool
wantErr bool
}{
{
name: "no arguments no tty",
input: "",
errMsg: "could not prompt: proceed with prompt",
wantErr: true,
},
{
name: "one argument",
input: "REPO",
output: RenameOptions{
newRepoSelector: "REPO",
},
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
io, _, _, _ := iostreams.Test()
io.SetStdinTTY(tt.tty)
io.SetStdoutTTY(tt.tty)
f := &cmdutil.Factory{
IOStreams: io,
}
// func TestNewCmdRename(t *testing.T) {
// testCases := []struct {
// name string
// args string
// wantOpts RenameOptions
// wantErr string
// }{
// {
// name: "no arguments",
// args: "",
// wantErr: "cannot rename: repository argument required",
// },
// {
// name: "correct argument",
// args: "OWNER/REPO REPOS",
// wantOpts: RenameOptions{
// oldRepoSelector: "OWNER/REPO",
// newRepoSelector: "REPOS",
// },
// },
// }
// for _, tt := range testCases {
// t.Run(tt.name, func(t *testing.T) {
// io, stdin, stdout, stderr := iostreams.Test()
// fac := &cmdutil.Factory{IOStreams: io}
argv, err := shlex.Split(tt.input)
assert.NoError(t, err)
var gotOpts *RenameOptions
cmd := NewCmdRename(f, func(opts *RenameOptions) error {
gotOpts = opts
return nil
})
cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{})
// var opts *RenameOptions
// cmd := NewCmdRename(fac, func(co *RenameOptions) error {
// opts = co
// return nil
// })
_, err = cmd.ExecuteC()
if tt.wantErr {
assert.Error(t, err)
assert.Equal(t, tt.errMsg, err.Error())
return
}
assert.NoError(t, err)
assert.Equal(t, tt.output.newRepoSelector, gotOpts.newRepoSelector)
})
}
}
// argv, err := shlex.Split(tt.args)
// require.NoError(t, err)
// cmd.SetArgs(argv)
func TestRenameRun(t *testing.T) {
testCases := []struct {
name string
opts RenameOptions
httpStubs func(*httpmock.Registry)
askStubs func(*prompt.AskStubber)
wantOut string
tty bool
prompt bool
}{
{
name: "none argument",
wantOut: "✓ Renamed repository OWNER/NEW_REPO\n✓ Updated the \"origin\" remote",
askStubs: func(q *prompt.AskStubber) {
q.StubOne("NEW_REPO")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("PATCH", "repos/OWNER/REPO"),
httpmock.StatusStringResponse(204, "{}"))
},
tty: true,
},
{
name: "owner repo change name prompt",
opts: RenameOptions{
BaseRepo: func() (ghrepo.Interface, error) {
return ghrepo.New("OWNER", "REPO"), nil
},
},
wantOut: "✓ Renamed repository OWNER/NEW_REPO\n",
askStubs: func(q *prompt.AskStubber) {
q.StubOne("NEW_REPO")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("PATCH", "repos/OWNER/REPO"),
httpmock.StatusStringResponse(204, "{}"))
},
prompt: true,
},
{
name: "owner repo change name argument ",
opts: RenameOptions{
newRepoSelector: "REPO",
},
askStubs: func(q *prompt.AskStubber) {
q.StubOne("OWNER/REPO")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.GraphQL(`query RepositoryInfo\b`),
httpmock.StringResponse(`
{
"data": {
"repository": {
"id": "THE-ID",
"name": "REPO",
"owner": {
"login": "OWNER"
}
}
}
}`))
reg.Register(
httpmock.REST("PATCH", "repos/OWNER/REPO"),
httpmock.StatusStringResponse(204, "{}"))
},
},
}
// cmd.SetIn(stdin)
// cmd.SetOut(stdout)
// cmd.SetErr(stderr)
for _, tt := range testCases {
q, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(q)
}
// _, err = cmd.ExecuteC()
// if tt.wantErr != "" {
// assert.EqualError(t, err, tt.wantErr)
// return
// } else {
// assert.NoError(t, err)
// }
tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
repo, _ := ghrepo.FromFullName("OWNER/REPO")
return repo, nil
}
// assert.Equal(t, "", stdout.String())
// assert.Equal(t, "", stderr.String())
tt.opts.Config = func() (config.Config, error) {
return config.NewBlankConfig(), nil
}
// assert.Equal(t, tt.wantOpts.oldRepoSelector, opts.oldRepoSelector)
// assert.Equal(t, tt.wantOpts.newRepoSelector, opts.newRepoSelector)
// })
// }
// }
tt.opts.Remotes = func() (context.Remotes, error) {
r, _ := ghrepo.FromFullName("OWNER/REPO")
var remotes context.Remotes
remotes = append(remotes, &context.Remote{
Remote: &git.Remote{Name: "origin"},
Repo: r,
})
return remotes, nil
}
// func TestRenameRun(t *testing.T) {
// testCases := []struct {
// name string
// opts RenameOptions
// httpStubs func(*httpmock.Registry)
// askStubs func(*prompt.AskStubber)
// wantOut string
// tty bool
// prompt bool
// }{
// {
// name: "owner repo change name using flag",
// opts: RenameOptions{
// oldRepoSelector: "OWNER/REPO",
// newRepoSelector: "NEW_REPO",
// flagRepo: true,
// },
// wantOut: "✓ Renamed repository OWNER/NEW_REPO\n",
// httpStubs: func(reg *httpmock.Registry) {
// reg.Register(
// httpmock.GraphQL(`query UserCurrent\b`),
// httpmock.StringResponse(`{"data":{"viewer":{"login":"OWNER"}}}`))
// reg.Register(
// httpmock.REST("PATCH", "repos/OWNER/REPO"),
// httpmock.StatusStringResponse(204, "{}"))
// },
// tty: true,
// },
// {
// name: "owner repo change name prompt",
// opts: RenameOptions{
// BaseRepo: func() (ghrepo.Interface, error) {
// return ghrepo.New("OWNER", "REPO"), nil
// },
// oldRepoSelector: "NEW_REPO",
// },
// wantOut: "✓ Renamed repository OWNER/NEW_REPO\n",
// askStubs: func(q *prompt.AskStubber) {
// q.StubOne("NEW_REPO")
// },
// httpStubs: func(reg *httpmock.Registry) {
// reg.Register(
// httpmock.REST("PATCH", "repos/OWNER/REPO"),
// httpmock.StatusStringResponse(204, "{}"))
// },
// prompt: true,
// },
// {
// name: "owner repo change name argument ",
// opts: RenameOptions{
// newRepoSelector: "REPO",
// flagRepo: false,
// },
// askStubs: func(q *prompt.AskStubber) {
// q.StubOne("OWNER/REPO")
// },
// httpStubs: func(reg *httpmock.Registry) {
// reg.Register(
// httpmock.GraphQL(`query RepositoryInfo\b`),
// httpmock.StringResponse(`
// {
// "data": {
// "repository": {
// "id": "THE-ID",
// "name": "REPO",
// "owner": {
// "login": "OWNER"
// }
// }
// }
// }`))
// reg.Register(
// httpmock.REST("PATCH", "repos/OWNER/REPO"),
// httpmock.StatusStringResponse(204, "{}"))
// },
// },
// }
reg := &httpmock.Registry{}
if tt.httpStubs != nil {
tt.httpStubs(reg)
}
tt.opts.HttpClient = func() (*http.Client, error) {
return &http.Client{Transport: reg}, nil
}
// for _, tt := range testCases {
// q, teardown := prompt.InitAskStubber()
// defer teardown()
// if tt.askStubs != nil {
// tt.askStubs(q)
// }
io, _, stdout, _ := iostreams.Test()
io.SetStdinTTY(tt.tty)
io.SetStdoutTTY(tt.tty)
tt.opts.IO = io
// tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
// repo, _ := ghrepo.FromFullName(tt.opts.oldRepoSelector)
// return repo, nil
// }
// reg := &httpmock.Registry{}
// if tt.httpStubs != nil {
// tt.httpStubs(reg)
// }
// tt.opts.HttpClient = func() (*http.Client, error) {
// return &http.Client{Transport: reg}, nil
// }
// io, _, stdout, _ := iostreams.Test()
// io.SetStdinTTY(tt.tty)
// io.SetStdoutTTY(tt.tty)
// tt.opts.IO = io
// t.Run(tt.name, func(t *testing.T) {
// defer reg.Verify(t)
// err := renameRun(&tt.opts)
// assert.NoError(t, err)
// assert.Equal(t, tt.wantOut, stdout.String())
// })
// }
// }
t.Run(tt.name, func(t *testing.T) {
defer reg.Verify(t)
err := renameRun(&tt.opts)
assert.NoError(t, err)
assert.Equal(t, tt.wantOut, stdout.String())
})
}
}