github.com/trevoraustin/hub@v2.2.0-preview1.0.20141105230840-96d8bfc654cc+incompatible/commands/clone.go (about)

     1  package commands
     2  
     3  import (
     4  	"regexp"
     5  	"strings"
     6  
     7  	"github.com/github/hub/github"
     8  	"github.com/github/hub/utils"
     9  )
    10  
    11  var cmdClone = &Command{
    12  	Run:          clone,
    13  	GitExtension: true,
    14  	Usage:        "clone [-p] OPTIONS [USER/]REPOSITORY DIRECTORY",
    15  	Short:        "Clone a remote repository into a new directory",
    16  	Long: `Clone repository "git://github.com/USER/REPOSITORY.git" into
    17  DIRECTORY as with git-clone(1). When USER/ is omitted, assumes
    18  your GitHub login. With -p, clone private repositories over SSH.
    19  For repositories under your GitHub login, -p is implicit.
    20  `,
    21  }
    22  
    23  func init() {
    24  	CmdRunner.Use(cmdClone)
    25  }
    26  
    27  /**
    28    $ gh clone jingweno/gh
    29    > git clone git://github.com/jingweno/gh.git
    30  
    31    $ gh clone -p jingweno/gh
    32    > git clone git@github.com:jingweno/gh.git
    33  
    34    $ gh clone jekyll_and_hyde
    35    > git clone git://github.com/YOUR_LOGIN/jekyll_and_hyde.git
    36  
    37    $ gh clone -p jekyll_and_hyde
    38    > git clone git@github.com:YOUR_LOGIN/jekyll_and_hyde.git
    39  */
    40  func clone(command *Command, args *Args) {
    41  	if !args.IsParamsEmpty() {
    42  		transformCloneArgs(args)
    43  	}
    44  }
    45  
    46  func transformCloneArgs(args *Args) {
    47  	isSSH := parseClonePrivateFlag(args)
    48  	hasValueRegxp := regexp.MustCompile("^(--(upload-pack|template|depth|origin|branch|reference|name)|-[ubo])$")
    49  	nameWithOwnerRegexp := regexp.MustCompile(NameWithOwnerRe)
    50  	for i := 0; i < args.ParamsSize(); i++ {
    51  		a := args.Params[i]
    52  
    53  		if strings.HasPrefix(a, "-") {
    54  			if hasValueRegxp.MatchString(a) {
    55  				i++
    56  			}
    57  		} else {
    58  			if nameWithOwnerRegexp.MatchString(a) && !isDir(a) {
    59  				name, owner := parseCloneNameAndOwner(a)
    60  				var host *github.Host
    61  				if owner == "" {
    62  					config := github.CurrentConfig()
    63  					h, err := config.DefaultHost()
    64  					if err != nil {
    65  						utils.Check(github.FormatError("cloning repository", err))
    66  					}
    67  
    68  					host = h
    69  					owner = host.User
    70  				}
    71  
    72  				var hostStr string
    73  				if host != nil {
    74  					hostStr = host.Host
    75  				}
    76  
    77  				project := github.NewProject(owner, name, hostStr)
    78  				if !isSSH &&
    79  					args.Command != "submodule" &&
    80  					!github.IsHttpsProtocol() {
    81  					client := github.NewClient(project.Host)
    82  					repo, err := client.Repository(project)
    83  					isSSH = (err == nil) && (repo.Private || repo.Permissions.Push)
    84  				}
    85  
    86  				url := project.GitURL(name, owner, isSSH)
    87  				args.ReplaceParam(i, url)
    88  			}
    89  
    90  			break
    91  		}
    92  	}
    93  }
    94  
    95  func parseClonePrivateFlag(args *Args) bool {
    96  	if i := args.IndexOfParam("-p"); i != -1 {
    97  		args.RemoveParam(i)
    98  		return true
    99  	}
   100  
   101  	return false
   102  }
   103  
   104  func parseCloneNameAndOwner(arg string) (name, owner string) {
   105  	name, owner = arg, ""
   106  	if strings.Contains(arg, "/") {
   107  		split := strings.SplitN(arg, "/", 2)
   108  		name = split[1]
   109  		owner = split[0]
   110  	}
   111  
   112  	return
   113  }