2020-02-17 06:28:11 +01:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
|
|
"fmt"
|
2020-02-17 21:50:02 +01:00
|
|
|
"gitea.com/jolheiser/sip/modules/git"
|
|
|
|
"gitea.com/jolheiser/sip/modules/markdown"
|
2020-02-17 06:28:11 +01:00
|
|
|
"github.com/AlecAivazis/survey/v2"
|
|
|
|
"github.com/urfave/cli/v2"
|
2020-02-27 03:53:11 +01:00
|
|
|
"go.jolheiser.com/beaver/color"
|
2020-02-17 06:28:11 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var PullsCreate = cli.Command{
|
2020-02-27 03:53:11 +01:00
|
|
|
Name: "create",
|
|
|
|
Aliases: []string{"new"},
|
|
|
|
Usage: "Create a new pull request",
|
|
|
|
Action: doPullCreate,
|
2020-02-17 06:28:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func doPullCreate(ctx *cli.Context) error {
|
|
|
|
fmt.Println()
|
|
|
|
url := color.New(color.FgYellow).Format(fmt.Sprintf("%s/%s/%s", ctx.String("url"), ctx.String("owner"), ctx.String("repo")))
|
|
|
|
fmt.Println(color.New(color.FgCyan).Format("Creating a new pull request for"), url)
|
|
|
|
|
|
|
|
token, err := requireToken(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
client := gitea.NewClient(ctx.String("url"), token)
|
|
|
|
|
|
|
|
upstreams, err := client.ListRepoBranches(getUpstreamRepo()[1], getUpstreamRepo()[2])
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
bases := make([]string, len(upstreams))
|
|
|
|
defUpstream := upstreams[0].Name
|
|
|
|
for idx, upstream := range upstreams {
|
|
|
|
if upstream.Name == "master" {
|
|
|
|
defUpstream = upstream.Name
|
|
|
|
}
|
|
|
|
bases[idx] = upstream.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
origins, err := client.ListRepoBranches(getOriginRepo()[1], getOriginRepo()[2])
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
heads := make([]string, len(origins))
|
|
|
|
defOrigin := origins[0].Name
|
|
|
|
for idx, origin := range origins {
|
2020-02-27 03:53:11 +01:00
|
|
|
originName := origin.Name
|
|
|
|
if ctx.String("owner") != getOriginRepo()[1] {
|
|
|
|
originName = getOriginRepo()[1] + ":" + originName
|
|
|
|
}
|
2020-02-17 06:28:11 +01:00
|
|
|
if origin.Name == git.Branch() {
|
2020-02-27 03:53:11 +01:00
|
|
|
defOrigin = originName
|
2020-02-17 06:28:11 +01:00
|
|
|
}
|
2020-02-27 03:53:11 +01:00
|
|
|
heads[idx] = originName
|
2020-02-17 06:28:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var confirmed bool
|
|
|
|
var title, body string
|
|
|
|
base := defUpstream
|
|
|
|
head := defOrigin
|
|
|
|
|
|
|
|
for !confirmed {
|
|
|
|
questions := []*survey.Question{
|
|
|
|
{
|
|
|
|
Name: "title",
|
|
|
|
Prompt: &survey.Input{Message: "Title", Default: title},
|
|
|
|
Validate: survey.Required,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "body",
|
|
|
|
Prompt: &survey.Multiline{Message: "Description", Default: body},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "base",
|
|
|
|
Prompt: &survey.Select{Message: "Base target", Options: bases, Default: base},
|
|
|
|
Validate: survey.Required,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "head",
|
|
|
|
Prompt: &survey.Select{Message: "Head target", Options: heads, Default: head},
|
|
|
|
Validate: survey.Required,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
answers := struct {
|
|
|
|
Title string
|
|
|
|
Body string
|
|
|
|
Base string
|
|
|
|
Head string
|
|
|
|
}{}
|
|
|
|
|
|
|
|
if err := survey.Ask(questions, &answers); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
title = answers.Title
|
|
|
|
body = answers.Body
|
|
|
|
base = answers.Base
|
|
|
|
head = answers.Head
|
|
|
|
|
|
|
|
preview, err := markdown.Render(body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("%s\n\n%s\n", title, preview)
|
|
|
|
confirm := &survey.Confirm{Message: "Preview above, enter to create or 'n' to edit", Default: true}
|
|
|
|
|
|
|
|
if err := survey.AskOne(confirm, &confirmed); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pull, err := client.CreatePullRequest(ctx.String("owner"), ctx.String("repo"), gitea.CreatePullRequestOption{Title: title, Body: body, Base: base, Head: head})
|
|
|
|
if err != nil {
|
|
|
|
if fmt.Sprint(err) == "409 Conflict" { // Hard-coded in the SDK
|
|
|
|
return existingPR(client, getUpstreamRepo()[1], getUpstreamRepo()[2], head, err)
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
info := color.Info
|
|
|
|
cyan := color.New(color.FgCyan)
|
|
|
|
fmt.Println(info.Format("PR"), cyan.Format(fmt.Sprintf("#%d", pull.Index)), info.Format("created!"))
|
|
|
|
fmt.Println(cyan.Format(fmt.Sprintf("%s/%s/%s/pulls/%d", ctx.String("url"), ctx.String("owner"), ctx.String("repo"), pull.Index)))
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func existingPR(client *gitea.Client, owner, repo, head string, pullErr error) error {
|
|
|
|
pulls, err := client.ListRepoPullRequests(owner, repo, gitea.ListPullRequestsOptions{State: "open"})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, pull := range pulls {
|
|
|
|
compare := fmt.Sprintf("%s:%s", pull.Head.Repository.Owner.UserName, pull.Head.Name)
|
|
|
|
if compare == head {
|
|
|
|
fmt.Println(color.New(color.FgCyan).Format("PR already exists at"), color.New(color.FgYellow).Format(pull.HTMLURL))
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pullErr
|
|
|
|
}
|