Parse args to find an explicit directory name

This commit is contained in:
Fotios Lindiakos 2020-04-01 15:08:29 -04:00
parent ed62b7bbd5
commit 59f239bddc
No known key found for this signature in database
GPG key ID: 91BDC79C39F348FD
2 changed files with 96 additions and 4 deletions

View file

@ -51,12 +51,14 @@ 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' 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...)

View file

@ -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",