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

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/github/hub/github"
     8  	"github.com/github/hub/utils"
     9  )
    10  
    11  var cmdFork = &Command{
    12  	Run:   fork,
    13  	Usage: "fork [--no-remote]",
    14  	Short: "Make a fork of a remote repository on GitHub and add as remote",
    15  	Long: `Forks the original project (referenced by "origin" remote) on GitHub and
    16  adds a new remote for it under your username.
    17  `,
    18  }
    19  
    20  var flagForkNoRemote bool
    21  
    22  func init() {
    23  	cmdFork.Flag.BoolVar(&flagForkNoRemote, "no-remote", false, "")
    24  
    25  	CmdRunner.Use(cmdFork)
    26  }
    27  
    28  /*
    29    $ gh fork
    30    [ repo forked on GitHub ]
    31    > git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
    32  
    33    $ gh fork --no-remote
    34    [ repo forked on GitHub ]
    35  */
    36  func fork(cmd *Command, args *Args) {
    37  	localRepo, err := github.LocalRepo()
    38  	utils.Check(err)
    39  
    40  	project, err := localRepo.MainProject()
    41  	if err != nil {
    42  		utils.Check(fmt.Errorf("Error: repository under 'origin' remote is not a GitHub project"))
    43  	}
    44  
    45  	config := github.CurrentConfig()
    46  	host, err := config.PromptForHost(project.Host)
    47  	if err != nil {
    48  		utils.Check(github.FormatError("forking repository", err))
    49  	}
    50  
    51  	forkProject := github.NewProject(host.User, project.Name, project.Host)
    52  	client := github.NewClient(project.Host)
    53  	existingRepo, err := client.Repository(forkProject)
    54  	if err == nil {
    55  		var parentURL *github.URL
    56  		if parent := existingRepo.Parent; parent != nil {
    57  			parentURL, _ = github.ParseURL(parent.HTMLURL)
    58  		}
    59  		if parentURL == nil || !project.SameAs(parentURL.Project) {
    60  			err = fmt.Errorf("Error creating fork: %s already exists on %s",
    61  				forkProject, forkProject.Host)
    62  			utils.Check(err)
    63  		}
    64  	} else {
    65  		if !args.Noop {
    66  			_, err := client.ForkRepository(project)
    67  			utils.Check(err)
    68  		}
    69  	}
    70  
    71  	if flagForkNoRemote {
    72  		os.Exit(0)
    73  	} else {
    74  		originRemote, _ := localRepo.OriginRemote()
    75  		originURL := originRemote.URL.String()
    76  		url := forkProject.GitURL("", "", true)
    77  		args.Replace("git", "remote", "add", "-f", forkProject.Owner, originURL)
    78  		args.After("git", "remote", "set-url", forkProject.Owner, url)
    79  		args.After("echo", fmt.Sprintf("new remote: %s", forkProject.Owner))
    80  	}
    81  }