From 98bd372e604285cf79ffcf04d0fdf423200cab8f Mon Sep 17 00:00:00 2001 From: Josh Bialkowski Date: Mon, 9 Dec 2019 14:17:09 -0800 Subject: codereview #4: fixes from testing * don't prefix imported title's with jira ID * fix import new comment due to wrong variable name * fix double import of comment edition due to improper err check * fix JIRA cloud paginated changelog has a different JSON field then the embedded changelog in the JIRA server issue object * fix splitting label strings yielded an empty string as a label value --- bridge/jira/client.go | 14 +++++++++++++- bridge/jira/import.go | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/bridge/jira/client.go b/bridge/jira/client.go index adaad94d..040c988e 100644 --- a/bridge/jira/client.go +++ b/bridge/jira/client.go @@ -165,7 +165,9 @@ type ChangeLogPage struct { StartAt int `json:"startAt"` MaxResults int `json:"maxResults"` Total int `json:"total"` + IsLast bool `json:"isLast"` // Cloud-only Entries []ChangeLogEntry `json:"histories"` + Values []ChangeLogEntry `json:"values"` } // NextStartAt return the index of the first item on the next page @@ -175,6 +177,9 @@ func (self *ChangeLogPage) NextStartAt() int { // IsLastPage return true if there are no more items beyond this page func (self *ChangeLogPage) IsLastPage() bool { + // NOTE(josh): The "isLast" field is returned on JIRA cloud, but not on + // JIRA server. If we can distinguish which one we are working with, we can + // possibly rely on that instead. return self.NextStartAt() >= self.Total } @@ -804,7 +809,8 @@ func (client *Client) IterComments( // https://docs.atlassian.com/software/jira/docs/api/REST/8.2.6/#api/2/issue func (client *Client) GetChangeLog( idOrKey string, maxResults int, startAt int) (*ChangeLogPage, error) { - url := fmt.Sprintf("%s/rest/api/2/issue/%s/changelog", client.serverURL, idOrKey) + url := fmt.Sprintf( + "%s/rest/api/2/issue/%s/changelog", client.serverURL, idOrKey) request, err := http.NewRequest("GET", url, nil) if err != nil { @@ -865,6 +871,12 @@ func (client *Client) GetChangeLog( return nil, err } + // JIRA cloud returns changelog entries in the "values" list, whereas JIRA + // server returns them in the "histories" list when embedded in an issue + // object. + changelog.Entries = changelog.Values + changelog.Values = nil + return &changelog, nil } diff --git a/bridge/jira/import.go b/bridge/jira/import.go index 346aa6fd..d4156615 100644 --- a/bridge/jira/import.go +++ b/bridge/jira/import.go @@ -207,7 +207,7 @@ func (self *jiraImporter) ensureIssue( return nil, err } - title := fmt.Sprintf("[%s]: %s", issue.Key, issue.Fields.Summary) + title := issue.Fields.Summary b, _, err = repo.NewBugRaw( author, issue.Fields.Created.Unix(), @@ -278,6 +278,7 @@ func (self *jiraImporter) ensureComment(repo *cache.RepoCache, } self.out <- core.NewImportComment(op.Id()) + targetOpID = op.Id() } // If there are no updates to this comment, then we are done @@ -292,7 +293,12 @@ func (self *jiraImporter) ensureComment(repo *cache.RepoCache, derivedID := getTimeDerivedID(item.ID, item.Updated) _, err = b.ResolveOperationWithMetadata( keyJiraID, derivedID) - if err != nil && err != cache.ErrNoMatchingOp { + if err == nil { + // Already imported this edition + return nil + } + + if err != cache.ErrNoMatchingOp { return err } @@ -310,7 +316,7 @@ func (self *jiraImporter) ensureComment(repo *cache.RepoCache, op, err := b.EditCommentRaw( editor, item.Updated.Unix(), - target, + targetOpID, cleanText, map[string]string{ keyJiraID: derivedID, @@ -397,8 +403,8 @@ func (self *jiraImporter) ensureChange( for _, item := range entry.Items { switch item.Field { case "labels": - fromLabels := strings.Split(item.FromString, " ") - toLabels := strings.Split(item.ToString, " ") + fromLabels := removeEmpty(strings.Split(item.FromString, " ")) + toLabels := removeEmpty(strings.Split(item.ToString, " ")) removedLabels, addedLabels, _ := setSymmetricDifference( fromLabels, toLabels) @@ -467,14 +473,15 @@ func (self *jiraImporter) ensureChange( _, err := b.ResolveOperationWithMetadata(keyJiraOperationID, derivedID) if err == nil { continue - } else if err != cache.ErrNoMatchingOp { + } + if err != cache.ErrNoMatchingOp { return err } switch item.Field { case "labels": - fromLabels := strings.Split(item.FromString, " ") - toLabels := strings.Split(item.ToString, " ") + fromLabels := removeEmpty(strings.Split(item.FromString, " ")) + toLabels := removeEmpty(strings.Split(item.ToString, " ")) removedLabels, addedLabels, _ := setSymmetricDifference( fromLabels, toLabels) @@ -562,6 +569,9 @@ func (self *jiraImporter) ensureChange( } self.out <- core.NewImportCommentEdition(op.Id()) + + default: + fmt.Printf("Unhandled changelog event %s\n", item.Field) } // Other Examples: @@ -588,3 +598,14 @@ func getStatusMap(conf core.Configuration) (map[string]string, error) { err := json.Unmarshal([]byte(mapStr), &statusMap) return statusMap, err } + +func removeEmpty(values []string) []string { + output := make([]string, 0, len(values)) + for _, value := range values { + value = strings.TrimSpace(value) + if value != "" { + output = append(output, value) + } + } + return output +} -- cgit