added requested changes
This commit is contained in:
parent
5946c98096
commit
dd98c7f51f
2 changed files with 225 additions and 234 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue