package cmd import ( "code.gitea.io/sdk/gitea" "errors" "fmt" "gitea.com/jolheiser/beaver" "gitea.com/jolheiser/beaver/color" "gitea.com/jolheiser/sip/modules/markdown" "gitea.com/jolheiser/sip/modules/sdk" "github.com/AlecAivazis/survey/v2" "github.com/urfave/cli/v2" "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 } ownerRepo := strings.Split(answers.Repo, "/") opts := gitea.ListIssueOption{KeyWord: answers.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 { if pulls { if issue.PullRequest != nil { filtered = append(filtered, 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 }