Merge pull request #727 from thefotios/respect-clone-target
Respect clone target Closes #721
This commit is contained in:
commit
43b28f769b
2 changed files with 112 additions and 20 deletions
|
|
@ -51,12 +51,12 @@ A repository can be supplied as an argument in any of the following formats:
|
|||
}
|
||||
|
||||
var repoCloneCmd = &cobra.Command{
|
||||
Use: "clone <repo>",
|
||||
Use: "clone <repo> [<directory>]",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Short: "Clone a repository locally",
|
||||
Long: `Clone a GitHub repository locally.
|
||||
|
||||
To pass 'git clone' options, separate them with '--'.`,
|
||||
To pass 'git clone' flags, separate them with '--'.`,
|
||||
RunE: repoClone,
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +87,41 @@ With no argument, the repository for the current directory is displayed.`,
|
|||
RunE: repoView,
|
||||
}
|
||||
|
||||
func parseCloneArgs(extraArgs []string) (args []string, target string) {
|
||||
args = extraArgs
|
||||
|
||||
if len(args) > 0 {
|
||||
if !strings.HasPrefix(args[0], "-") {
|
||||
target, args = args[0], args[1:]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func runClone(cloneURL string, args []string) (target string, err error) {
|
||||
cloneArgs, target := parseCloneArgs(args)
|
||||
|
||||
cloneArgs = append(cloneArgs, cloneURL)
|
||||
|
||||
// If the args contain an explicit target, pass it to clone
|
||||
// otherwise, parse the URL to determine where git cloned it to so we can return it
|
||||
if target != "" {
|
||||
cloneArgs = append(cloneArgs, target)
|
||||
} else {
|
||||
target = path.Base(strings.TrimSuffix(cloneURL, ".git"))
|
||||
}
|
||||
|
||||
cloneArgs = append([]string{"clone"}, cloneArgs...)
|
||||
|
||||
cloneCmd := git.GitCommand(cloneArgs...)
|
||||
cloneCmd.Stdin = os.Stdin
|
||||
cloneCmd.Stdout = os.Stdout
|
||||
cloneCmd.Stderr = os.Stderr
|
||||
|
||||
err = run.PrepareCmd(cloneCmd).Run()
|
||||
return
|
||||
}
|
||||
|
||||
func repoClone(cmd *cobra.Command, args []string) error {
|
||||
cloneURL := args[0]
|
||||
if !strings.Contains(cloneURL, ":") {
|
||||
|
|
@ -115,21 +150,13 @@ func repoClone(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
}
|
||||
|
||||
cloneArgs := []string{"clone"}
|
||||
cloneArgs = append(cloneArgs, args[1:]...)
|
||||
cloneArgs = append(cloneArgs, cloneURL)
|
||||
|
||||
cloneCmd := git.GitCommand(cloneArgs...)
|
||||
cloneCmd.Stdin = os.Stdin
|
||||
cloneCmd.Stdout = os.Stdout
|
||||
cloneCmd.Stderr = os.Stderr
|
||||
err := run.PrepareCmd(cloneCmd).Run()
|
||||
cloneDir, err := runClone(cloneURL, args[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if parentRepo != nil {
|
||||
err := addUpstreamRemote(parentRepo, cloneURL)
|
||||
err := addUpstreamRemote(parentRepo, cloneDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -138,10 +165,9 @@ func repoClone(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func addUpstreamRemote(parentRepo ghrepo.Interface, cloneURL string) error {
|
||||
func addUpstreamRemote(parentRepo ghrepo.Interface, cloneDir string) error {
|
||||
// TODO: support SSH remote URLs
|
||||
upstreamURL := fmt.Sprintf("https://github.com/%s.git", ghrepo.FullName(parentRepo))
|
||||
cloneDir := path.Base(strings.TrimSuffix(cloneURL, ".git"))
|
||||
|
||||
cloneCmd := git.GitCommand("-C", cloneDir, "remote", "add", "upstream", upstreamURL)
|
||||
cloneCmd.Stdout = os.Stdout
|
||||
|
|
@ -425,16 +451,12 @@ func repoFork(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
}
|
||||
if cloneDesired {
|
||||
cloneCmd := git.GitCommand("clone", forkedRepo.CloneURL)
|
||||
cloneCmd.Stdin = os.Stdin
|
||||
cloneCmd.Stdout = os.Stdout
|
||||
cloneCmd.Stderr = os.Stderr
|
||||
err = run.PrepareCmd(cloneCmd).Run()
|
||||
cloneDir, err := runClone(forkedRepo.CloneURL, []string{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to clone fork: %w", err)
|
||||
}
|
||||
|
||||
err = addUpstreamRemote(toFork, forkedRepo.CloneURL)
|
||||
err = addUpstreamRemote(toFork, cloneDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
|
@ -337,6 +338,65 @@ func TestRepoFork_in_parent_survey_no(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestParseExtraArgs(t *testing.T) {
|
||||
type Wanted struct {
|
||||
args []string
|
||||
dir string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
want Wanted
|
||||
}{
|
||||
{
|
||||
name: "args and target",
|
||||
args: []string{"target_directory", "-o", "upstream", "--depth", "1"},
|
||||
want: Wanted{
|
||||
args: []string{"-o", "upstream", "--depth", "1"},
|
||||
dir: "target_directory",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only args",
|
||||
args: []string{"-o", "upstream", "--depth", "1"},
|
||||
want: Wanted{
|
||||
args: []string{"-o", "upstream", "--depth", "1"},
|
||||
dir: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only target",
|
||||
args: []string{"target_directory"},
|
||||
want: Wanted{
|
||||
args: []string{},
|
||||
dir: "target_directory",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no args",
|
||||
args: []string{},
|
||||
want: Wanted{
|
||||
args: []string{},
|
||||
dir: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
args, dir := parseCloneArgs(tt.args)
|
||||
got := Wanted{
|
||||
args: args,
|
||||
dir: dir,
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("got %#v want %#v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestRepoClone(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -348,11 +408,21 @@ func TestRepoClone(t *testing.T) {
|
|||
args: "repo clone OWNER/REPO",
|
||||
want: "git clone https://github.com/OWNER/REPO.git",
|
||||
},
|
||||
{
|
||||
name: "shorthand with directory",
|
||||
args: "repo clone OWNER/REPO target_directory",
|
||||
want: "git clone https://github.com/OWNER/REPO.git target_directory",
|
||||
},
|
||||
{
|
||||
name: "clone arguments",
|
||||
args: "repo clone OWNER/REPO -- -o upstream --depth 1",
|
||||
want: "git clone -o upstream --depth 1 https://github.com/OWNER/REPO.git",
|
||||
},
|
||||
{
|
||||
name: "clone arguments with directory",
|
||||
args: "repo clone OWNER/REPO target_directory -- -o upstream --depth 1",
|
||||
want: "git clone -o upstream --depth 1 https://github.com/OWNER/REPO.git target_directory",
|
||||
},
|
||||
{
|
||||
name: "HTTPS URL",
|
||||
args: "repo clone https://github.com/OWNER/REPO",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue