From 59f239bddc51d8cd79cd83a2d3fbaf20756a7ea5 Mon Sep 17 00:00:00 2001 From: Fotios Lindiakos Date: Wed, 1 Apr 2020 15:08:29 -0400 Subject: [PATCH] Parse args to find an explicit directory name --- command/repo.go | 30 ++++++++++++++++--- command/repo_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/command/repo.go b/command/repo.go index 03080ce65..85da23d23 100644 --- a/command/repo.go +++ b/command/repo.go @@ -51,12 +51,14 @@ A repository can be supplied as an argument in any of the following formats: } var repoCloneCmd = &cobra.Command{ - Use: "clone ", + Use: "clone []", 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' options, separate them with '--'. + +In order to clone to a specific directory, provide it before the '--' instead of after the other additional options.`, RunE: repoClone, } @@ -87,9 +89,29 @@ With no argument, the repository for the current directory is displayed.`, RunE: repoView, } +func parseExtraArgs(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 := append(args, cloneURL) - target = path.Base(strings.TrimSuffix(cloneURL, ".git")) + cloneArgs, target := parseExtraArgs(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...) diff --git a/command/repo_test.go b/command/repo_test.go index f0d271cf8..957c1d419 100644 --- a/command/repo_test.go +++ b/command/repo_test.go @@ -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 := parseExtraArgs(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",