Add generate from issues argument (#44)

Fix posible nil problem

Process only merged PRs

Rename variable

Fix github query for issues

Fix typo

Split function & fix lint

Rename variable name

Fix lint error

Add generate from issues argument

Co-authored-by: jaqra <jaqra@hotmail.com>
Reviewed-on: https://gitea.com/gitea/changelog/pulls/44
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: John Olheiser <john.olheiser@gmail.com>
This commit is contained in:
jaqra 2020-08-04 13:30:19 +00:00 committed by John Olheiser
parent f3a2d35420
commit e532c4d5cd
7 changed files with 79 additions and 39 deletions

@ -15,6 +15,7 @@ var (
TokenFlag string TokenFlag string
DetailsFlag bool DetailsFlag bool
AfterFlag int64 AfterFlag int64
IssuesFlag bool
) )
func getDefaultConfigFile() string { func getDefaultConfigFile() string {

@ -31,7 +31,7 @@ func runContributors(cmd *cli.Context) error {
return err return err
} }
s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, MilestoneFlag, TokenFlag) s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, MilestoneFlag, TokenFlag, IssuesFlag)
if err != nil { if err != nil {
return err return err
} }

@ -21,7 +21,7 @@ var (
Action: runGenerate, Action: runGenerate,
} }
labels = make(map[string]string) labels = make(map[string]string)
entries = make(map[string][]service.PullRequest) entries = make(map[string][]service.Entry)
defaultGroup string defaultGroup string
) )
@ -37,7 +37,7 @@ func runGenerate(cmd *cli.Context) error {
processGroups(cfg.Groups) processGroups(cfg.Groups)
s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, MilestoneFlag, TokenFlag) s, err := service.New(cfg.Service, cfg.Repo, cfg.BaseURL, MilestoneFlag, TokenFlag, IssuesFlag)
if err != nil { if err != nil {
return err return err
} }
@ -76,7 +76,7 @@ func runGenerate(cmd *cli.Context) error {
func processGroups(groups []config.Group) { func processGroups(groups []config.Group) {
for _, g := range groups { for _, g := range groups {
entries[g.Name] = []service.PullRequest{} entries[g.Name] = []service.Entry{}
for _, l := range g.Labels { for _, l := range g.Labels {
labels[l] = g.Name labels[l] = g.Name
} }
@ -90,7 +90,7 @@ func processGroups(groups []config.Group) {
} }
} }
func processPRs(prs []service.PullRequest, skip *regexp.Regexp) { func processPRs(prs []service.Entry, skip *regexp.Regexp) {
PRLoop: // labels in Go, let's get old school PRLoop: // labels in Go, let's get old school
for _, pr := range prs { for _, pr := range prs {
if pr.Index < AfterFlag { if pr.Index < AfterFlag {

@ -57,6 +57,12 @@ func main() {
Usage: "Only select PRs after a given index (continuing a previous changelog)", Usage: "Only select PRs after a given index (continuing a previous changelog)",
Destination: &cmd.AfterFlag, Destination: &cmd.AfterFlag,
}, },
&cli.BoolFlag{
Name: "issues",
Aliases: []string{"i"},
Usage: "Generate changelog from issues (otherwise from pulls)",
Destination: &cmd.IssuesFlag,
},
}, },
Commands: []*cli.Command{ Commands: []*cli.Command{
cmd.Generate, cmd.Generate,

@ -18,20 +18,26 @@ type Gitea struct {
BaseURL string BaseURL string
Owner string Owner string
Repo string Repo string
Issues bool
} }
// Generate returns a Gitea changelog // Generate returns a Gitea changelog
func (ge *Gitea) Generate() (string, []PullRequest, error) { func (ge *Gitea) Generate() (string, []Entry, error) {
client := gitea.NewClient(ge.BaseURL, ge.Token) client := gitea.NewClient(ge.BaseURL, ge.Token)
prs := make([]PullRequest, 0) entries := make([]Entry, 0)
milestoneID, err := ge.milestoneID(client) milestoneID, err := ge.milestoneID(client)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
tagURL := fmt.Sprintf("## [%s](%s/%s/%s/pulls?q=&type=all&state=closed&milestone=%d) - %s", ge.Milestone, ge.BaseURL, ge.Owner, ge.Repo, milestoneID, time.Now().Format("2006-01-02")) from := "pulls"
if ge.Issues {
from = "issues"
}
tagURL := fmt.Sprintf("## [%s](%s/%s/%s/%s?q=&type=all&state=closed&milestone=%d) - %s", ge.Milestone, ge.BaseURL, ge.Owner, ge.Repo, from, milestoneID, time.Now().Format("2006-01-02"))
p := 1 p := 1
// https://github.com/go-gitea/gitea/blob/d92781bf941972761177ac9e07441f8893758fd3/models/repo.go#L63 // https://github.com/go-gitea/gitea/blob/d92781bf941972761177ac9e07441f8893758fd3/models/repo.go#L63
@ -39,44 +45,61 @@ func (ge *Gitea) Generate() (string, []PullRequest, error) {
// FIXME Gitea has this hard-coded at 40 // FIXME Gitea has this hard-coded at 40
perPage := 40 perPage := 40
for { for {
results, err := client.ListRepoPullRequests(ge.Owner, ge.Repo, gitea.ListPullRequestsOptions{ options := gitea.ListIssueOption{
ListOptions: gitea.ListOptions{ ListOptions: gitea.ListOptions{
Page: p, Page: p,
PageSize: perPage, PageSize: perPage,
}, },
State: "closed", Milestones: []string{ge.Milestone},
Milestone: milestoneID, State: gitea.StateClosed,
}) Type: gitea.IssueTypePull,
}
if ge.Issues {
options.Type = gitea.IssueTypeIssue
}
issues, err := client.ListRepoIssues(ge.Owner, ge.Repo, options)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
p++
for _, pr := range results { for _, issue := range issues {
if pr != nil && pr.HasMerged { if issue != nil {
p := PullRequest{ if options.Type == gitea.IssueTypePull && issue.PullRequest != nil && !(issue.PullRequest.HasMerged) {
Title: pr.Title, continue
Index: pr.Index,
} }
labels := make([]Label, len(pr.Labels)) entry := convertToEntry(*issue)
for idx, lbl := range pr.Labels { entries = append(entries, entry)
labels[idx] = Label{
Name: lbl.Name,
}
}
p.Labels = labels
prs = append(prs, p)
} }
} }
if len(results) != perPage { if len(issues) != perPage {
break break
} }
p++
}
return tagURL, entries, nil
}
func convertToEntry(issue gitea.Issue) Entry {
entry := Entry{
Index: issue.Index,
Title: issue.Title,
}
labels := make([]Label, len(issue.Labels))
for idx, lbl := range issue.Labels {
labels[idx] = Label{
Name: lbl.Name,
}
} }
return tagURL, prs, nil entry.Labels = labels
return entry
} }
// Contributors returns a list of contributors from Gitea // Contributors returns a list of contributors from Gitea

@ -17,18 +17,24 @@ type GitHub struct {
Milestone string Milestone string
Token string Token string
Repo string Repo string
Issues bool
} }
// Generate returns a GitHub changelog // Generate returns a GitHub changelog
func (gh *GitHub) Generate() (string, []PullRequest, error) { func (gh *GitHub) Generate() (string, []Entry, error) {
tagURL := fmt.Sprintf("## [%s](https://github.com/%s/releases/tag/v%s) - %s", gh.Milestone, gh.Repo, gh.Milestone, time.Now().Format("2006-01-02")) tagURL := fmt.Sprintf("## [%s](https://github.com/%s/releases/tag/v%s) - %s", gh.Milestone, gh.Repo, gh.Milestone, time.Now().Format("2006-01-02"))
client := github.NewClient(nil) client := github.NewClient(nil)
ctx := context.Background() ctx := context.Background()
prs := make([]PullRequest, 0) prs := make([]Entry, 0)
query := fmt.Sprintf(`repo:%s is:merged milestone:"%s"`, gh.Repo, gh.Milestone) state := "merged"
if gh.Issues {
state = "closed"
}
query := fmt.Sprintf(`repo:%s is:%s milestone:"%s"`, gh.Repo, state, gh.Milestone)
p := 1 p := 1
perPage := 100 perPage := 100
for { for {
@ -43,9 +49,11 @@ func (gh *GitHub) Generate() (string, []PullRequest, error) {
} }
p++ p++
isPull := !(gh.Issues)
for _, pr := range result.Issues { for _, pr := range result.Issues {
if pr.IsPullRequest() { if pr.IsPullRequest() == isPull {
p := PullRequest{ p := Entry{
Title: pr.GetTitle(), Title: pr.GetTitle(),
Index: int64(pr.GetNumber()), Index: int64(pr.GetNumber()),
} }

@ -11,14 +11,15 @@ import (
const defaultGitea = "https://gitea.com" const defaultGitea = "https://gitea.com"
// Load returns a service from a string // New returns a service from a string
func New(serviceType, repo, baseURL, milestone, token string) (Service, error) { func New(serviceType, repo, baseURL, milestone, token string, issues bool) (Service, error) {
switch strings.ToLower(serviceType) { switch strings.ToLower(serviceType) {
case "github": case "github":
return &GitHub{ return &GitHub{
Milestone: milestone, Milestone: milestone,
Token: token, Token: token,
Repo: repo, Repo: repo,
Issues: issues,
}, nil }, nil
case "gitea": case "gitea":
ownerRepo := strings.Split(repo, "/") ownerRepo := strings.Split(repo, "/")
@ -31,6 +32,7 @@ func New(serviceType, repo, baseURL, milestone, token string) (Service, error) {
BaseURL: baseURL, BaseURL: baseURL,
Owner: ownerRepo[0], Owner: ownerRepo[0],
Repo: ownerRepo[1], Repo: ownerRepo[1],
Issues: issues,
}, nil }, nil
default: default:
return nil, fmt.Errorf("unknown service type %s", serviceType) return nil, fmt.Errorf("unknown service type %s", serviceType)
@ -39,7 +41,7 @@ func New(serviceType, repo, baseURL, milestone, token string) (Service, error) {
// Service defines how a struct can be a Changelog Service // Service defines how a struct can be a Changelog Service
type Service interface { type Service interface {
Generate() (string, []PullRequest, error) Generate() (string, []Entry, error)
Contributors() (ContributorList, error) Contributors() (ContributorList, error)
} }
@ -48,8 +50,8 @@ type Label struct {
Name string Name string
} }
// PullRequest is the minimum information needed to make a changelog entry // Entry is the minimum information needed to make a changelog entry
type PullRequest struct { type Entry struct {
Title string Title string
Index int64 Index int64
Labels []Label Labels []Label