actually add command
This commit is contained in:
parent
dfd567bf7f
commit
9efe96575e
1 changed files with 207 additions and 0 deletions
207
command/pr_create.go
Normal file
207
command/pr_create.go
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/github/gh-cli/api"
|
||||
"github.com/github/gh-cli/context"
|
||||
"github.com/github/gh-cli/git"
|
||||
"github.com/github/gh-cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
_draftF bool
|
||||
_titleF string
|
||||
_bodyF string
|
||||
_baseF string
|
||||
)
|
||||
|
||||
func prCreate(ctx context.Context) error {
|
||||
ucc, err := git.UncommittedChangeCount()
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"could not determine state of working directory: %v", err)
|
||||
}
|
||||
if ucc > 0 {
|
||||
noun := "change"
|
||||
if ucc > 1 {
|
||||
noun = noun + "s"
|
||||
}
|
||||
|
||||
fmt.Printf("%s %d uncommitted %s %s", utils.Red("!!!"),
|
||||
ucc, noun, utils.Red("!!!"))
|
||||
}
|
||||
|
||||
head, err := ctx.Branch()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not determine current branch: %s", err)
|
||||
}
|
||||
|
||||
remote, err := guessRemote(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = git.Push(remote, fmt.Sprintf("HEAD:%s", head)); err != nil {
|
||||
return fmt.Errorf("was not able to push to remote '%s': %s", remote, err)
|
||||
}
|
||||
|
||||
interactive := _titleF == "" || _bodyF == ""
|
||||
|
||||
inProgress := struct {
|
||||
Body string
|
||||
Title string
|
||||
}{}
|
||||
|
||||
if interactive {
|
||||
confirmed := false
|
||||
editor := determineEditor()
|
||||
|
||||
for !confirmed {
|
||||
titleQuestion := &survey.Question{
|
||||
Name: "title",
|
||||
Prompt: &survey.Input{
|
||||
Message: "PR Title",
|
||||
Default: inProgress.Title,
|
||||
},
|
||||
}
|
||||
bodyQuestion := &survey.Question{
|
||||
Name: "body",
|
||||
Prompt: &survey.Editor{
|
||||
Message: fmt.Sprintf("PR Body (%s)", editor),
|
||||
FileName: "*.md",
|
||||
Default: inProgress.Body,
|
||||
AppendDefault: true,
|
||||
Editor: editor,
|
||||
},
|
||||
}
|
||||
|
||||
qs := []*survey.Question{}
|
||||
if _titleF == "" {
|
||||
qs = append(qs, titleQuestion)
|
||||
}
|
||||
if _bodyF == "" {
|
||||
qs = append(qs, bodyQuestion)
|
||||
}
|
||||
|
||||
err := survey.Ask(qs, &inProgress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not prompt: %s", err)
|
||||
}
|
||||
confirmAnswers := struct {
|
||||
Confirmation string
|
||||
}{}
|
||||
confirmQs := []*survey.Question{
|
||||
{
|
||||
Name: "confirmation",
|
||||
Prompt: &survey.Select{
|
||||
Message: "Submit?",
|
||||
Options: []string{
|
||||
"Yes",
|
||||
"Edit",
|
||||
"Cancel",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err = survey.Ask(confirmQs, &confirmAnswers)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not prompt: %s", err)
|
||||
}
|
||||
|
||||
switch confirmAnswers.Confirmation {
|
||||
case "Yes":
|
||||
confirmed = true
|
||||
case "Edit":
|
||||
continue
|
||||
case "Cancel":
|
||||
fmt.Println(utils.Red("Discarding PR."))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
title := _titleF
|
||||
if title == "" {
|
||||
title = inProgress.Title
|
||||
}
|
||||
body := _bodyF
|
||||
if body == "" {
|
||||
body = inProgress.Body
|
||||
}
|
||||
base := _baseF
|
||||
if base == "" {
|
||||
base = "master"
|
||||
}
|
||||
|
||||
client, err := apiClientForContext(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not initialize api client: %s", err)
|
||||
}
|
||||
|
||||
repo, err := ctx.BaseRepo()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not determine GitHub repo: %s", err)
|
||||
}
|
||||
|
||||
payload, err := api.CreatePullRequest(client, repo, title, body, _draftF, base, head)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create PR: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println(payload)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func guessRemote(ctx context.Context) (string, error) {
|
||||
remotes, err := ctx.Remotes()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not determine suitable remote: %s", err)
|
||||
}
|
||||
|
||||
remote, err := remotes.FindByName("origin", "github")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not determine suitable remote: %s", err)
|
||||
}
|
||||
|
||||
return remote.Name, nil
|
||||
}
|
||||
|
||||
func determineEditor() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return "notepad"
|
||||
}
|
||||
if v := os.Getenv("VISUAL"); v != "" {
|
||||
return v
|
||||
}
|
||||
if e := os.Getenv("EDITOR"); e != "" {
|
||||
return e
|
||||
}
|
||||
return "nano"
|
||||
}
|
||||
|
||||
var prCreateCmd = &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a pull request",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
ctx := contextForCommand(cmd)
|
||||
return prCreate(ctx)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
prCreateCmd.Flags().BoolVarP(&_draftF, "draft", "d", false,
|
||||
"Mark PR as a draft")
|
||||
prCreateCmd.Flags().StringVarP(&_titleF, "title", "t", "",
|
||||
"Supply a title. Will prompt for one otherwise.")
|
||||
prCreateCmd.Flags().StringVarP(&_bodyF, "body", "b", "",
|
||||
"Supply a body. Will prompt for one otherwise.")
|
||||
prCreateCmd.Flags().StringVarP(&_baseF, "base", "T", "",
|
||||
"The branch into which you want your code merged")
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue