clone.go 2.4 KB
Newer Older
J
Jingwen Owen Ou 已提交
1 2 3
package commands

import (
J
Jingwen Owen Ou 已提交
4
	"github.com/github/hub/github"
J
Jingwen Owen Ou 已提交
5 6 7 8 9 10 11
	"regexp"
	"strings"
)

var cmdClone = &Command{
	Run:          clone,
	GitExtension: true,
J
Jingwen Owen Ou 已提交
12
	Usage:        "clone [-p] OPTIONS [USER/]REPOSITORY DIRECTORY",
J
Jingwen Owen Ou 已提交
13
	Short:        "Clone a remote repository into a new directory",
14 15 16 17 18
	Long: `Clone repository "git://github.com/USER/REPOSITORY.git" into
DIRECTORY as with git-clone(1). When USER/ is omitted, assumes
your GitHub login. With -p, clone private repositories over SSH.
For repositories under your GitHub login, -p is implicit.
`,
J
Jingwen Owen Ou 已提交
19 20
}

21 22 23 24
func init() {
	CmdRunner.Use(cmdClone)
}

J
Jingwen Owen Ou 已提交
25 26
/**
  $ gh clone jingweno/gh
J
Jingwen Owen Ou 已提交
27
  > git clone git://github.com/jingweno/gh.git
J
Jingwen Owen Ou 已提交
28 29 30 31

  $ gh clone -p jingweno/gh
  > git clone git@github.com:jingweno/gh.git

J
Jingwen Owen Ou 已提交
32 33
  $ gh clone jekyll_and_hyde
  > git clone git://github.com/YOUR_LOGIN/jekyll_and_hyde.git
J
Jingwen Owen Ou 已提交
34

J
Jingwen Owen Ou 已提交
35 36
  $ gh clone -p jekyll_and_hyde
  > git clone git@github.com:YOUR_LOGIN/jekyll_and_hyde.git
J
Jingwen Owen Ou 已提交
37 38
*/
func clone(command *Command, args *Args) {
J
Jingwen Owen Ou 已提交
39
	if !args.IsParamsEmpty() {
J
Jingwen Owen Ou 已提交
40 41 42 43 44 45 46 47
		transformCloneArgs(args)
	}
}

func transformCloneArgs(args *Args) {
	isSSH := parseClonePrivateFlag(args)
	hasValueRegxp := regexp.MustCompile("^(--(upload-pack|template|depth|origin|branch|reference|name)|-[ubo])$")
	nameWithOwnerRegexp := regexp.MustCompile(NameWithOwnerRe)
J
Jingwen Owen Ou 已提交
48 49
	for i := 0; i < args.ParamsSize(); i++ {
		a := args.Params[i]
50 51 52

		if strings.HasPrefix(a, "-") {
			if hasValueRegxp.MatchString(a) {
J
Jingwen Owen Ou 已提交
53
				i++
54
			}
J
Jingwen Owen Ou 已提交
55 56 57 58 59 60
		} else {
			if nameWithOwnerRegexp.MatchString(a) && !isDir(a) {
				name, owner := parseCloneNameAndOwner(a)
				var credentials *github.Credentials
				if owner == "" {
					configs := github.CurrentConfigs()
61
					credentials = configs.DefaultCredentials()
J
Jingwen Owen Ou 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
					owner = credentials.User
				}

				var host string
				if credentials != nil {
					host = credentials.Host
				}

				project := github.NewProject(owner, name, host)
				isSSH = isSSH ||
					args.Command != "submodule" &&
						credentials != nil &&
						project.Owner == credentials.User

				url := project.GitURL(name, owner, isSSH)
				args.ReplaceParam(i, url)
78 79
			}

J
Jingwen Owen Ou 已提交
80 81 82 83 84 85
			break
		}
	}
}

func parseClonePrivateFlag(args *Args) bool {
J
Jingwen Owen Ou 已提交
86 87
	if i := args.IndexOfParam("-p"); i != -1 {
		args.RemoveParam(i)
J
Jingwen Owen Ou 已提交
88 89 90 91 92
		return true
	}

	return false
}
93 94 95 96 97 98 99 100 101 102 103

func parseCloneNameAndOwner(arg string) (name, owner string) {
	name, owner = arg, ""
	if strings.Contains(arg, "/") {
		split := strings.SplitN(arg, "/", 2)
		name = split[1]
		owner = split[0]
	}

	return
}