1
0
mirror of https://gitea.com/jolheiser/sip synced 2024-11-23 04:12:00 +01:00
sip/cmd/issues.go

143 lines
3.4 KiB
Go
Raw Permalink Normal View History

package cmd
import (
"code.gitea.io/sdk/gitea"
"errors"
"fmt"
"gitea.com/jolheiser/sip/modules/markdown"
"gitea.com/jolheiser/sip/modules/sdk"
"github.com/AlecAivazis/survey/v2"
"github.com/urfave/cli/v2"
"go.jolheiser.com/beaver"
"go.jolheiser.com/beaver/color"
"strconv"
"strings"
)
var Issues = cli.Command{
Name: "issues",
Aliases: []string{"issue"},
Usage: "Commands for interacting with issues",
Action: doIssuesSearch,
Subcommands: []*cli.Command{
&IssuesCreate,
},
}
func doIssuesSearch(ctx *cli.Context) error {
if _, err := issuesSearch(ctx, false); err != nil {
return err
}
return nil
}
func issuesSearch(ctx *cli.Context, pulls bool) (*gitea.Issue, error) {
typ := "issues"
if pulls {
typ = "pulls"
}
issues, err := queryIssues(ctx, getClient(ctx), pulls)
if err != nil {
return nil, err
}
if len(issues) == 0 {
beaver.Errorf("No %s found!", typ)
return nil, nil
}
issueMap := make(map[string]*gitea.Issue)
for _, issue := range issues {
index := color.New(color.FgCyan).Format("#" + strconv.Itoa(int(issue.Index)))
title := color.New(color.FgYellow).Format(issue.Title)
state := color.New(color.FgGreen).Format("[open]")
if issue.PullRequest != nil && issue.PullRequest.HasMerged {
state = color.New(color.FgMagenta).Format("[merged]")
} else if issue.State == gitea.StateClosed {
state = color.New(color.FgRed).Format("[closed]")
}
lbls := make([]string, len(issue.Labels))
for idx, label := range issue.Labels {
lbls[idx] = label.Name
}
var labels string
if len(lbls) > 0 {
labels = color.New(color.FgHiBlack).Format("(" + strings.Join(lbls, ", ") + ")")
}
issueMap[fmt.Sprintf("%s %s %s %s", index, state, title, labels)] = issue
}
list := make([]string, 0)
for key := range issueMap {
list = append(list, key)
}
sel := &survey.Select{Options: list, Message: "Matching " + typ}
var selection string
if err := survey.AskOne(sel, &selection); err != nil {
return nil, err
}
body, err := markdown.Render(issueMap[selection].Body)
if err != nil {
return nil, err
}
fmt.Println(body)
return issueMap[selection], nil
}
func queryIssues(ctx *cli.Context, client *gitea.Client, pulls bool) ([]*gitea.Issue, error) {
questions := []*survey.Question{
{
Name: "repo",
Prompt: &survey.Input{Message: "Full repository name", Default: fullName(ctx)},
Validate: validateFullName,
},
{
Name: "query",
Prompt: &survey.Input{Message: "Search query"},
},
}
answers := struct {
Repo string
Query string
}{}
if err := survey.Ask(questions, &answers); err != nil {
return nil, err
}
filter := sdk.NewIssueFilter(answers.Query)
ownerRepo := strings.Split(answers.Repo, "/")
opts := gitea.ListIssueOption{KeyWord: filter.Query, State: "all"}
issues, err := sdk.GetIssues(client, ownerRepo[0], ownerRepo[1], opts)
if err != nil {
return nil, err
}
filtered := make([]*gitea.Issue, 0)
for _, issue := range issues {
// Filter out issues if searching PRs and vice-versa
if (pulls && issue.PullRequest == nil) ||
(!pulls && issue.PullRequest != nil) {
continue
}
if !filter.Match(issue) {
continue
}
filtered = append(filtered, issue)
}
return filtered, nil
}
func validateFullName(ans interface{}) error {
fullName := ans.(string)
ownerRepo := strings.Split(fullName, "/")
if len(ownerRepo) != 2 {
return errors.New("full repo name should be in form `owner/repo`")
}
return nil
}