sip/cmd/pulls_create.go
John Olheiser 5ecbcde518
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Change to vanity URL (#37)
Fix YAML

New changes, generate docs, and add Drone for main

Signed-off-by: jolheiser <john.olheiser@gmail.com>

Merge branch 'master' of gitea.com:jolheiser/sip into vanity

Change to vanity URL

Signed-off-by: jolheiser <john.olheiser@gmail.com>

Co-authored-by: jolheiser <john.olheiser@gmail.com>
Reviewed-on: #37
2020-09-21 19:21:07 +00:00

152 lines
3.8 KiB
Go

package cmd
import (
"fmt"
"strings"
"go.jolheiser.com/sip/flag"
"go.jolheiser.com/sip/git"
"go.jolheiser.com/sip/markdown"
"code.gitea.io/sdk/gitea"
"github.com/AlecAivazis/survey/v2"
"github.com/urfave/cli/v2"
"go.jolheiser.com/beaver/color"
)
var PullsCreate = cli.Command{
Name: "create",
Aliases: []string{"new"},
Usage: "Create a new pull request",
Action: doPullCreate,
}
func doPullCreate(_ *cli.Context) error {
fmt.Println()
url := color.New(color.FgYellow).Format(flag.FullURL())
fmt.Println(color.New(color.FgCyan).Format("Creating a new pull request for"), url)
client, err := getClient(true)
if err != nil {
return err
}
repo, _, err := client.GetRepo(flag.Upstream.Owner, flag.Upstream.Repo)
if err != nil {
return err
}
upstreams, _, err := client.ListRepoBranches(flag.Upstream.Owner, flag.Upstream.Repo, gitea.ListRepoBranchesOptions{})
if err != nil {
return err
}
bases := make([]string, len(upstreams))
defUpstream := repo.DefaultBranch
for idx, upstream := range upstreams {
bases[idx] = upstream.Name
}
origins, _, err := client.ListRepoBranches(flag.Origin.Owner, flag.Origin.Repo, gitea.ListRepoBranchesOptions{})
if err != nil {
return err
}
heads := make([]string, len(origins))
defOrigin := origins[0].Name
for idx, origin := range origins {
originName := origin.Name
if flag.Owner != flag.Origin.Owner {
originName = flag.Origin.Owner + ":" + originName
}
if strings.EqualFold(origin.Name, git.Branch()) {
defOrigin = originName
}
heads[idx] = originName
}
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(flag.Owner, flag.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, flag.Upstream.Owner, flag.Upstream.Repo, 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/pulls/%d", flag.FullURL(), 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
}