/* $ gh create ... create repo on github ... > git remote add -f origin [email protected]:YOUR_USER/CURRENT_REPO.git # with description: $ gh create -d 'It shall be mine, all mine!' $ gh create recipes [ repo created on GitHub ] > git remote add origin [email protected]:YOUR_USER/recipes.git $ gh create sinatra/recipes [ repo created in GitHub organization ] > git remote add origin [email protected]:sinatra/recipes.git */ func create(command *Command, args *Args) { _, err := git.Dir() if err != nil { err = fmt.Errorf("'create' must be run from inside a git repository") utils.Check(err) } var newRepoName string if args.IsParamsEmpty() { newRepoName, err = utils.DirName() utils.Check(err) } else { reg := regexp.MustCompile("^[^-]") if !reg.MatchString(args.FirstParam()) { err = fmt.Errorf("invalid argument: %s", args.FirstParam()) utils.Check(err) } newRepoName = args.FirstParam() } configs := github.CurrentConfigs() credentials := configs.DefaultCredentials() owner := credentials.User if strings.Contains(newRepoName, "/") { split := strings.SplitN(newRepoName, "/", 2) owner = split[0] newRepoName = split[1] } project := github.NewProject(owner, newRepoName, credentials.Host) gh := github.NewClient(project.Host) var action string if gh.IsRepositoryExist(project) { fmt.Printf("%s already exists on %s\n", project, project.Host) action = "set remote origin" } else { action = "created repository" if !args.Noop { repo, err := gh.CreateRepository(project, flagCreateDescription, flagCreateHomepage, flagCreatePrivate) utils.Check(err) project = github.NewProject(repo.FullName, "", project.Host) } } remote, _ := github.OriginRemote() if remote == nil { url := project.GitURL("", "", true) args.Replace("git", "remote", "add", "-f", "origin", url) } else { args.Replace("git", "remote", "-v") } args.After("echo", fmt.Sprintf("%s:", action), project.String()) }
func tranformFetchArgs(args *Args) error { names := parseRemoteNames(args) localRepo := github.LocalRepo() projects := make(map[*github.Project]bool) ownerRegexp := regexp.MustCompile(OwnerRe) for _, name := range names { if ownerRegexp.MatchString(name) { _, err := localRepo.RemoteByName(name) if err != nil { project := github.NewProject(name, "", "") gh := github.NewClient(project.Host) repo, err := gh.Repository(project) if err != nil { continue } projects[project] = repo.Private } } } for project, private := range projects { args.Before("git", "remote", "add", project.Owner, project.GitURL("", "", private)) } return nil }
/* $ gh browse > open https://github.com/YOUR_USER/CURRENT_REPO $ gh browse commit/SHA > open https://github.com/YOUR_USER/CURRENT_REPO/commit/SHA $ gh browse issues > open https://github.com/YOUR_USER/CURRENT_REPO/issues $ gh browse -p jingweno/gh > open https://github.com/jingweno/gh $ gh browse -p jingweno/gh commit/SHA > open https://github.com/jingweno/gh/commit/SHA $ gh browse -p resque > open https://github.com/YOUR_USER/resque $ gh browse -p resque network > open https://github.com/YOUR_USER/resque/network */ func browse(command *Command, args *Args) { var ( project *github.Project branch *github.Branch err error ) localRepo := github.LocalRepo() if flagBrowseProject != "" { // gh browse -p jingweno/gh // gh browse -p gh project = github.NewProject("", flagBrowseProject, "") } else { // gh browse branch, project, err = localRepo.RemoteBranchAndProject("") utils.Check(err) } if project == nil { err := fmt.Errorf(command.FormattedUsage()) utils.Check(err) } master := localRepo.MasterBranch() if branch == nil { branch = master } var subpage string if !args.IsParamsEmpty() { subpage = args.RemoveParam(0) } if subpage == "commits" { subpage = fmt.Sprintf("commits/%s", branchInURL(branch)) } else if subpage == "tree" || subpage == "" { if !reflect.DeepEqual(branch, master) && branch.IsRemote() { subpage = fmt.Sprintf("tree/%s", branchInURL(branch)) } } pageUrl := project.WebURL("", "", subpage) launcher, err := utils.BrowserLauncher() utils.Check(err) if flagBrowseURLOnly { args.Replace("echo", pageUrl) } else { args.Replace(launcher[0], "", launcher[1:]...) args.AppendParams(pageUrl) } }
func parsePullRequestProject(context *github.Project, s string) (p *github.Project, ref string) { p = context ref = s if strings.Contains(s, ":") { split := strings.SplitN(s, ":", 2) ref = split[1] var name string if !strings.Contains(split[0], "/") { name = context.Name } p = github.NewProject(split[0], name, context.Host) } return }
func transformInitArgs(args *Args) error { if !parseInitFlag(args) { return nil } name, err := utils.DirName() if err != nil { return err } project := github.NewProject("", name, "") url := project.GitURL("", "", true) args.After("git", "remote", "add", "origin", url) return nil }
/* $ gh compare refactor > open https://github.com/CURRENT_REPO/compare/refactor $ gh compare 1.0..1.1 > open https://github.com/CURRENT_REPO/compare/1.0...1.1 $ gh compare -u other-user patch > open https://github.com/other-user/REPO/compare/patch */ func compare(command *Command, args *Args) { localRepo := github.LocalRepo() var ( branch *github.Branch project *github.Project r string err error ) branch, project, err = localRepo.RemoteBranchAndProject("") utils.Check(err) if args.IsParamsEmpty() { master := localRepo.MasterBranch() if master.ShortName() == branch.ShortName() { err = fmt.Errorf(command.FormattedUsage()) utils.Check(err) } else { r = branch.ShortName() } } else { r = parseCompareRange(args.RemoveParam(args.ParamsSize() - 1)) if args.IsParamsEmpty() { project, err = localRepo.CurrentProject() utils.Check(err) } else { project = github.NewProject(args.RemoveParam(args.ParamsSize()-1), "", "") } } r = strings.Replace(r, "/", ";", -1) subpage := utils.ConcatPaths("compare", r) url := project.WebURL("", "", subpage) launcher, err := utils.BrowserLauncher() utils.Check(err) if flagCompareURLOnly { args.Replace("echo", url) } else { args.Replace(launcher[0], "", launcher[1:]...) args.AppendParams(url) } }
func transformRemoteArgs(args *Args) { ownerWithName := args.LastParam() owner, name := parseRepoNameOwner(ownerWithName) if owner == "" { return } localRepo := github.LocalRepo() var repoName string if name == "" { project, err := localRepo.MainProject() if err == nil { repoName = project.Name } else { repoName, err = utils.DirName() utils.Check(err) } name = repoName } words := args.Words() isPriavte := parseRemotePrivateFlag(args) if len(words) == 2 && words[1] == "origin" { // gh add origin credentials := github.CurrentConfigs().DefaultCredentials() owner = credentials.User name = repoName } else if len(words) == 2 { // gh remote add jingweno foo/bar if idx := args.IndexOfParam(words[1]); idx != -1 { args.ReplaceParam(idx, owner) } } else { args.RemoveParam(args.ParamsSize() - 1) } project := github.NewProject(owner, name, "") // for GitHub Enterprise isPriavte = isPriavte || project.Host != github.GitHubHost url := project.GitURL(name, owner, isPriavte) args.AppendParams(url) }
func transformCloneArgs(args *Args) { isSSH := parseClonePrivateFlag(args) hasValueRegxp := regexp.MustCompile("^(--(upload-pack|template|depth|origin|branch|reference|name)|-[ubo])$") nameWithOwnerRegexp := regexp.MustCompile(NameWithOwnerRe) for i := 0; i < args.ParamsSize(); i++ { a := args.Params[i] if strings.HasPrefix(a, "-") { if hasValueRegxp.MatchString(a) { i++ } } else { if nameWithOwnerRegexp.MatchString(a) && !isDir(a) { name, owner := parseCloneNameAndOwner(a) var credentials *github.Credentials if owner == "" { configs := github.CurrentConfigs() credentials = configs.DefaultCredentials() 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) } break } } }
/* $ gh fork [ repo forked on GitHub ] > git remote add -f YOUR_USER [email protected]:YOUR_USER/CURRENT_REPO.git $ gh fork --no-remote [ repo forked on GitHub ] */ func fork(cmd *Command, args *Args) { localRepo := github.LocalRepo() project, err := localRepo.MainProject() utils.Check(err) configs := github.CurrentConfigs() credentials := configs.PromptFor(project.Host) forkProject := github.NewProject(credentials.User, project.Name, project.Host) client := github.NewClient(project.Host) existingRepo, err := client.Repository(forkProject) if err == nil { var parentURL *github.URL if parent := existingRepo.Parent; parent != nil { parentURL, _ = github.ParseURL(parent.HTMLURL) } if parentURL == nil || !reflect.DeepEqual(parentURL.Project, project) { err = fmt.Errorf("Error creating fork: %s already exists on %s", forkProject, forkProject.Host) utils.Check(err) } } else { if !args.Noop { _, err := client.ForkRepository(project) utils.Check(err) } } if flagForkNoRemote { os.Exit(0) } else { u := forkProject.GitURL("", "", true) args.Replace("git", "remote", "add", "-f", forkProject.Owner, u) args.After("echo", fmt.Sprintf("new remote: %s", forkProject.Owner)) } }