From 36c99ce040af11efd9d8ce6368dd84c9827ec08a Mon Sep 17 00:00:00 2001 From: Cory Bennett Date: Sat, 25 May 2019 17:06:03 -0700 Subject: [PATCH] make automatic pagination on search optional, fix tests --- jiracmd/list.go | 5 +--- jiradata/SearchResults.go | 1 - search.go | 51 ++++++++++++++++++++++++++++++--------- t/100basic.t | 16 +++++++----- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/jiracmd/list.go b/jiracmd/list.go index 1fe9b14..b55df44 100644 --- a/jiracmd/list.go +++ b/jiracmd/list.go @@ -30,9 +30,6 @@ func CmdListRegistry() *jiracli.CommandRegistryEntry { return CmdListUsage(cmd, &opts, fig) }, func(o *oreo.Client, globals *jiracli.GlobalOptions) error { - if opts.MaxResults == 0 { - opts.MaxResults = 500 - } if opts.QueryFields == "" { opts.QueryFields = "assignee,created,priority,reporter,status,summary,updated,issuetype" } @@ -72,7 +69,7 @@ func CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions, fig *figtree.FigTre // List will query jira and send data to "list" template func CmdList(o *oreo.Client, globals *jiracli.GlobalOptions, opts *ListOptions) error { - data, err := jira.Search(o, globals.Endpoint.Value, opts) + data, err := jira.Search(o, globals.Endpoint.Value, opts, jira.WithAutoPagination()) if err != nil { return err } diff --git a/jiradata/SearchResults.go b/jiradata/SearchResults.go index a5077da..ace2213 100644 --- a/jiradata/SearchResults.go +++ b/jiradata/SearchResults.go @@ -777,6 +777,5 @@ type SearchResults struct { Schema JSONTypeMap `json:"schema,omitempty" yaml:"schema,omitempty"` StartAt int `json:"startAt,omitempty" yaml:"startAt,omitempty"` Total int `json:"total,omitempty" yaml:"total,omitempty"` - IsLast bool `json:"isLast,omitempty" yaml:"isLast,omitempty"` WarningMessages WarningMessages `json:"warningMessages,omitempty" yaml:"warningMessages,omitempty"` } diff --git a/search.go b/search.go index 9f4d347..66813db 100644 --- a/search.go +++ b/search.go @@ -73,13 +73,35 @@ func (o *SearchOptions) ProvideSearchRequest() *jiradata.SearchRequest { } // https://docs.atlassian.com/jira/REST/cloud/#api/2/search-searchUsingSearchRequest -func (j *Jira) Search(sp SearchProvider) (*jiradata.SearchResults, error) { - return Search(j.UA, j.Endpoint, sp) +func (j *Jira) Search(sp SearchProvider, opts ...SearchOpt) (*jiradata.SearchResults, error) { + return Search(j.UA, j.Endpoint, sp, opts...) } -func Search(ua HttpClient, endpoint string, sp SearchProvider) (*jiradata.SearchResults, error) { +type searchConfig struct { + autoPaginate bool +} + +type SearchOpt func(*searchConfig) + +func WithAutoPagination() SearchOpt { + return func(c *searchConfig) { + c.autoPaginate = true + } +} + +func Search(ua HttpClient, endpoint string, sp SearchProvider, opts ...SearchOpt) (*jiradata.SearchResults, error) { + c := &searchConfig{} + for _, opt := range opts { + opt(c) + } + req := sp.ProvideSearchRequest() - results := &jiradata.SearchResults{} + limit := req.MaxResults + if limit == 0 { + // max page size is 100 + req.MaxResults = 100 + } + issues := jiradata.Issues{} for { encoded, err := json.Marshal(req) @@ -97,18 +119,25 @@ func Search(ua HttpClient, endpoint string, sp SearchProvider) (*jiradata.Search return nil, responseError(resp) } - err = readJSON(resp.Body, results) + page := &jiradata.SearchResults{} + err = readJSON(resp.Body, page) if err != nil { return nil, err } + if !c.autoPaginate { + return page, nil + } - issues = append(issues, results.Issues...) + issues = append(issues, page.Issues...) + // if we are done paginating just force all issues onto current + // response and return + if (limit > 0 && len(issues) >= limit) || len(issues) >= page.Total { + page.Issues = issues + return page, nil + } req.StartAt = len(issues) - - if len(issues) == results.Total || results.Total == 0 { - break + if len(issues)+req.MaxResults > limit { + req.MaxResults = limit - len(issues) } } - results.Issues = issues - return results, nil } diff --git a/t/100basic.t b/t/100basic.t index 1518a76..0028ca3 100755 --- a/t/100basic.t +++ b/t/100basic.t @@ -4,7 +4,7 @@ cd $(dirname $0) jira="../jira" . env.sh -PLAN 94 +PLAN 98 # reset login RUNS $jira logout @@ -567,11 +567,15 @@ labels: better-label, more-label description: | blocks EOF - + +############################################################################### +## List 102 closed issues, should be more than 100 (max page size), verify pagination +############################################################################### +RUNS $jira ls -q "project = 'BASIC' AND status = 'Done'" --limit 102 +IS $(wc -l <$OSHT_STDOUT) -eq 102 ############################################################################### -## List 150 closed issues, should be more than 100 +## List 1 issue, verify we dont get full page ############################################################################### - -RUNS $jira ls --project BASIC --status Closed --limit 150 -IS $(printf $0 | wc -l) -eq 150 +RUNS $jira ls -q "project = 'BASIC' AND status = 'Done'" --limit 1 +IS $(wc -l <$OSHT_STDOUT) -eq 1