aboutsummaryrefslogtreecommitdiffstats
path: root/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'bridge')
-rw-r--r--bridge/jira/client.go175
-rw-r--r--bridge/jira/export.go79
-rw-r--r--bridge/jira/import.go98
3 files changed, 154 insertions, 198 deletions
diff --git a/bridge/jira/client.go b/bridge/jira/client.go
index 6ec1c9dd..15098a3c 100644
--- a/bridge/jira/client.go
+++ b/bridge/jira/client.go
@@ -315,21 +315,19 @@ type ClientTransport struct {
}
// RoundTrip overrides the default by adding the content-type header
-func (self *ClientTransport) RoundTrip(
- req *http.Request) (*http.Response, error) {
+func (ct *ClientTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Add("Content-Type", "application/json")
- if self.basicAuthString != "" {
+ if ct.basicAuthString != "" {
req.Header.Add("Authorization",
- fmt.Sprintf("Basic %s", self.basicAuthString))
+ fmt.Sprintf("Basic %s", ct.basicAuthString))
}
- return self.underlyingTransport.RoundTrip(req)
+ return ct.underlyingTransport.RoundTrip(req)
}
-func (self *ClientTransport) SetCredentials(
- username string, token string) {
+func (ct *ClientTransport) SetCredentials(username string, token string) {
credString := fmt.Sprintf("%s:%s", username, token)
- self.basicAuthString = base64.StdEncoding.EncodeToString([]byte(credString))
+ ct.basicAuthString = base64.StdEncoding.EncodeToString([]byte(credString))
}
// Client Thin wrapper around the http.Client providing jira-specific methods
@@ -490,8 +488,7 @@ func (client *Client) RefreshSessionTokenRaw(credentialsJSON []byte) error {
// Search Perform an issue a JQL search on the /search endpoint
// https://docs.atlassian.com/software/jira/docs/api/REST/8.2.6/#api/2/search
-func (client *Client) Search(jql string, maxResults int, startAt int) (
- *SearchResult, error) {
+func (client *Client) Search(jql string, maxResults int, startAt int) (*SearchResult, error) {
url := fmt.Sprintf("%s/rest/api/2/search", client.serverURL)
requestBody, err := json.Marshal(SearchRequest{
@@ -558,52 +555,51 @@ type SearchIterator struct {
}
// HasError returns true if the iterator is holding an error
-func (self *SearchIterator) HasError() bool {
- if self.Err == errDone {
+func (si *SearchIterator) HasError() bool {
+ if si.Err == errDone {
return false
}
- if self.Err == nil {
+ if si.Err == nil {
return false
}
return true
}
// HasNext returns true if there is another item available in the result set
-func (self *SearchIterator) HasNext() bool {
- return self.Err == nil && self.itemIdx < len(self.searchResult.Issues)
+func (si *SearchIterator) HasNext() bool {
+ return si.Err == nil && si.itemIdx < len(si.searchResult.Issues)
}
// Next Return the next item in the result set and advance the iterator.
// Advancing the iterator may require fetching a new page.
-func (self *SearchIterator) Next() *Issue {
- if self.Err != nil {
+func (si *SearchIterator) Next() *Issue {
+ if si.Err != nil {
return nil
}
- issue := self.searchResult.Issues[self.itemIdx]
- if self.itemIdx+1 < len(self.searchResult.Issues) {
+ issue := si.searchResult.Issues[si.itemIdx]
+ if si.itemIdx+1 < len(si.searchResult.Issues) {
// We still have an item left in the currently cached page
- self.itemIdx++
+ si.itemIdx++
} else {
- if self.searchResult.IsLastPage() {
- self.Err = errDone
+ if si.searchResult.IsLastPage() {
+ si.Err = errDone
} else {
// There are still more pages to fetch, so fetch the next page and
// cache it
- self.searchResult, self.Err = self.client.Search(
- self.jql, self.pageSize, self.searchResult.NextStartAt())
+ si.searchResult, si.Err = si.client.Search(
+ si.jql, si.pageSize, si.searchResult.NextStartAt())
// NOTE(josh): we don't deal with the error now, we just cache it.
// HasNext() will return false and the caller can check the error
// afterward.
- self.itemIdx = 0
+ si.itemIdx = 0
}
}
return &issue
}
// IterSearch return an iterator over paginated results for a JQL search
-func (client *Client) IterSearch(
- jql string, pageSize int) *SearchIterator {
+func (client *Client) IterSearch(jql string, pageSize int) *SearchIterator {
result, err := client.Search(jql, pageSize, 0)
iter := &SearchIterator{
@@ -620,9 +616,9 @@ func (client *Client) IterSearch(
// GetIssue fetches an issue object via the /issue/{IssueIdOrKey} endpoint
// https://docs.atlassian.com/software/jira/docs/api/REST/8.2.6/#api/2/issue
-func (client *Client) GetIssue(
- idOrKey string, fields []string, expand []string,
+func (client *Client) GetIssue(idOrKey string, fields []string, expand []string,
properties []string) (*Issue, error) {
+
url := fmt.Sprintf("%s/rest/api/2/issue/%s", client.serverURL, idOrKey)
request, err := http.NewRequest("GET", url, nil)
@@ -678,8 +674,7 @@ func (client *Client) GetIssue(
// GetComments returns a page of comments via the issue/{IssueIdOrKey}/comment
// endpoint
// https://docs.atlassian.com/software/jira/docs/api/REST/8.2.6/#api/2/issue-getComment
-func (client *Client) GetComments(
- idOrKey string, maxResults int, startAt int) (*CommentPage, error) {
+func (client *Client) GetComments(idOrKey string, maxResults int, startAt int) (*CommentPage, error) {
url := fmt.Sprintf(
"%s/rest/api/2/issue/%s/comment", client.serverURL, idOrKey)
@@ -742,52 +737,51 @@ type CommentIterator struct {
}
// HasError returns true if the iterator is holding an error
-func (self *CommentIterator) HasError() bool {
- if self.Err == errDone {
+func (ci *CommentIterator) HasError() bool {
+ if ci.Err == errDone {
return false
}
- if self.Err == nil {
+ if ci.Err == nil {
return false
}
return true
}
// HasNext returns true if there is another item available in the result set
-func (self *CommentIterator) HasNext() bool {
- return self.Err == nil && self.itemIdx < len(self.message.Comments)
+func (ci *CommentIterator) HasNext() bool {
+ return ci.Err == nil && ci.itemIdx < len(ci.message.Comments)
}
// Next Return the next item in the result set and advance the iterator.
// Advancing the iterator may require fetching a new page.
-func (self *CommentIterator) Next() *Comment {
- if self.Err != nil {
+func (ci *CommentIterator) Next() *Comment {
+ if ci.Err != nil {
return nil
}
- comment := self.message.Comments[self.itemIdx]
- if self.itemIdx+1 < len(self.message.Comments) {
+ comment := ci.message.Comments[ci.itemIdx]
+ if ci.itemIdx+1 < len(ci.message.Comments) {
// We still have an item left in the currently cached page
- self.itemIdx++
+ ci.itemIdx++
} else {
- if self.message.IsLastPage() {
- self.Err = errDone
+ if ci.message.IsLastPage() {
+ ci.Err = errDone
} else {
// There are still more pages to fetch, so fetch the next page and
// cache it
- self.message, self.Err = self.client.GetComments(
- self.idOrKey, self.pageSize, self.message.NextStartAt())
+ ci.message, ci.Err = ci.client.GetComments(
+ ci.idOrKey, ci.pageSize, ci.message.NextStartAt())
// NOTE(josh): we don't deal with the error now, we just cache it.
// HasNext() will return false and the caller can check the error
// afterward.
- self.itemIdx = 0
+ ci.itemIdx = 0
}
}
return &comment
}
// IterComments returns an iterator over paginated comments within an issue
-func (client *Client) IterComments(
- idOrKey string, pageSize int) *CommentIterator {
+func (client *Client) IterComments(idOrKey string, pageSize int) *CommentIterator {
message, err := client.GetComments(idOrKey, pageSize, 0)
iter := &CommentIterator{
@@ -807,8 +801,7 @@ func (client *Client) IterComments(
// /issue/{IssueIdOrKey} with (fields=*none&expand=changelog)
// (for JIRA server)
// 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) {
+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)
@@ -892,52 +885,51 @@ type ChangeLogIterator struct {
}
// HasError returns true if the iterator is holding an error
-func (self *ChangeLogIterator) HasError() bool {
- if self.Err == errDone {
+func (cli *ChangeLogIterator) HasError() bool {
+ if cli.Err == errDone {
return false
}
- if self.Err == nil {
+ if cli.Err == nil {
return false
}
return true
}
// HasNext returns true if there is another item available in the result set
-func (self *ChangeLogIterator) HasNext() bool {
- return self.Err == nil && self.itemIdx < len(self.message.Entries)
+func (cli *ChangeLogIterator) HasNext() bool {
+ return cli.Err == nil && cli.itemIdx < len(cli.message.Entries)
}
// Next Return the next item in the result set and advance the iterator.
// Advancing the iterator may require fetching a new page.
-func (self *ChangeLogIterator) Next() *ChangeLogEntry {
- if self.Err != nil {
+func (cli *ChangeLogIterator) Next() *ChangeLogEntry {
+ if cli.Err != nil {
return nil
}
- item := self.message.Entries[self.itemIdx]
- if self.itemIdx+1 < len(self.message.Entries) {
+ item := cli.message.Entries[cli.itemIdx]
+ if cli.itemIdx+1 < len(cli.message.Entries) {
// We still have an item left in the currently cached page
- self.itemIdx++
+ cli.itemIdx++
} else {
- if self.message.IsLastPage() {
- self.Err = errDone
+ if cli.message.IsLastPage() {
+ cli.Err = errDone
} else {
// There are still more pages to fetch, so fetch the next page and
// cache it
- self.message, self.Err = self.client.GetChangeLog(
- self.idOrKey, self.pageSize, self.message.NextStartAt())
+ cli.message, cli.Err = cli.client.GetChangeLog(
+ cli.idOrKey, cli.pageSize, cli.message.NextStartAt())
// NOTE(josh): we don't deal with the error now, we just cache it.
// HasNext() will return false and the caller can check the error
// afterward.
- self.itemIdx = 0
+ cli.itemIdx = 0
}
}
return &item
}
// IterChangeLog returns an iterator over entries in the changelog for an issue
-func (client *Client) IterChangeLog(
- idOrKey string, pageSize int) *ChangeLogIterator {
+func (client *Client) IterChangeLog(idOrKey string, pageSize int) *ChangeLogIterator {
message, err := client.GetChangeLog(idOrKey, pageSize, 0)
iter := &ChangeLogIterator{
@@ -994,9 +986,8 @@ func (client *Client) GetProject(projectIDOrKey string) (*Project, error) {
}
// CreateIssue creates a new JIRA issue and returns it
-func (client *Client) CreateIssue(
- projectIDOrKey, title, body string, extra map[string]interface{}) (
- *IssueCreateResult, error) {
+func (client *Client) CreateIssue(projectIDOrKey, title, body string,
+ extra map[string]interface{}) (*IssueCreateResult, error) {
url := fmt.Sprintf("%s/rest/api/2/issue", client.serverURL)
@@ -1063,8 +1054,7 @@ func (client *Client) CreateIssue(
}
// UpdateIssueTitle changes the "summary" field of a JIRA issue
-func (client *Client) UpdateIssueTitle(
- issueKeyOrID, title string) (time.Time, error) {
+func (client *Client) UpdateIssueTitle(issueKeyOrID, title string) (time.Time, error) {
url := fmt.Sprintf(
"%s/rest/api/2/issue/%s", client.serverURL, issueKeyOrID)
@@ -1078,9 +1068,9 @@ func (client *Client) UpdateIssueTitle(
}
var buffer bytes.Buffer
- fmt.Fprintf(&buffer, `{"update":{"summary":[`)
- fmt.Fprintf(&buffer, `{"set":%s}`, data)
- fmt.Fprintf(&buffer, `]}}`)
+ _, _ = fmt.Fprintf(&buffer, `{"update":{"summary":[`)
+ _, _ = fmt.Fprintf(&buffer, `{"set":%s}`, data)
+ _, _ = fmt.Fprintf(&buffer, `]}}`)
data = buffer.Bytes()
request, err := http.NewRequest("PUT", url, bytes.NewBuffer(data))
@@ -1119,8 +1109,7 @@ func (client *Client) UpdateIssueTitle(
}
// UpdateIssueBody changes the "description" field of a JIRA issue
-func (client *Client) UpdateIssueBody(
- issueKeyOrID, body string) (time.Time, error) {
+func (client *Client) UpdateIssueBody(issueKeyOrID, body string) (time.Time, error) {
url := fmt.Sprintf(
"%s/rest/api/2/issue/%s", client.serverURL, issueKeyOrID)
@@ -1133,9 +1122,9 @@ func (client *Client) UpdateIssueBody(
}
var buffer bytes.Buffer
- fmt.Fprintf(&buffer, `{"update":{"description":[`)
- fmt.Fprintf(&buffer, `{"set":%s}`, data)
- fmt.Fprintf(&buffer, `]}}`)
+ _, _ = fmt.Fprintf(&buffer, `{"update":{"description":[`)
+ _, _ = fmt.Fprintf(&buffer, `{"set":%s}`, data)
+ _, _ = fmt.Fprintf(&buffer, `]}}`)
data = buffer.Bytes()
request, err := http.NewRequest("PUT", url, bytes.NewBuffer(data))
@@ -1279,8 +1268,7 @@ func (client *Client) UpdateComment(issueKeyOrID, commentID, body string) (
}
// UpdateLabels changes labels for an issue
-func (client *Client) UpdateLabels(
- issueKeyOrID string, added, removed []bug.Label) (time.Time, error) {
+func (client *Client) UpdateLabels(issueKeyOrID string, added, removed []bug.Label) (time.Time, error) {
url := fmt.Sprintf(
"%s/rest/api/2/issue/%s/", client.serverURL, issueKeyOrID)
var responseTime time.Time
@@ -1288,23 +1276,23 @@ func (client *Client) UpdateLabels(
// NOTE(josh): Since updates are a list of heterogeneous objects let's just
// manually build the JSON text
var buffer bytes.Buffer
- fmt.Fprintf(&buffer, `{"update":{"labels":[`)
+ _, _ = fmt.Fprintf(&buffer, `{"update":{"labels":[`)
first := true
for _, label := range added {
if !first {
- fmt.Fprintf(&buffer, ",")
+ _, _ = fmt.Fprintf(&buffer, ",")
}
- fmt.Fprintf(&buffer, `{"add":"%s"}`, label)
+ _, _ = fmt.Fprintf(&buffer, `{"add":"%s"}`, label)
first = false
}
for _, label := range removed {
if !first {
- fmt.Fprintf(&buffer, ",")
+ _, _ = fmt.Fprintf(&buffer, ",")
}
- fmt.Fprintf(&buffer, `{"remove":"%s"}`, label)
+ _, _ = fmt.Fprintf(&buffer, `{"remove":"%s"}`, label)
first = false
}
- fmt.Fprintf(&buffer, "]}}")
+ _, _ = fmt.Fprintf(&buffer, "]}}")
data := buffer.Bytes()
request, err := http.NewRequest("PUT", url, bytes.NewBuffer(data))
@@ -1349,8 +1337,7 @@ func (client *Client) UpdateLabels(
}
// GetTransitions returns a list of available transitions for an issue
-func (client *Client) GetTransitions(issueKeyOrID string) (
- *TransitionList, error) {
+func (client *Client) GetTransitions(issueKeyOrID string) (*TransitionList, error) {
url := fmt.Sprintf(
"%s/rest/api/2/issue/%s/transitions", client.serverURL, issueKeyOrID)
@@ -1393,8 +1380,7 @@ func (client *Client) GetTransitions(issueKeyOrID string) (
return &message, nil
}
-func getTransitionTo(
- tlist *TransitionList, desiredStateNameOrID string) *Transition {
+func getTransitionTo(tlist *TransitionList, desiredStateNameOrID string) *Transition {
for _, transition := range tlist.Transitions {
if transition.To.ID == desiredStateNameOrID {
return &transition
@@ -1406,8 +1392,7 @@ func getTransitionTo(
}
// DoTransition changes the "status" of an issue
-func (client *Client) DoTransition(
- issueKeyOrID string, transitionID string) (time.Time, error) {
+func (client *Client) DoTransition(issueKeyOrID string, transitionID string) (time.Time, error) {
url := fmt.Sprintf(
"%s/rest/api/2/issue/%s/transitions", client.serverURL, issueKeyOrID)
var responseTime time.Time
@@ -1417,7 +1402,7 @@ func (client *Client) DoTransition(
// *compute* the necessary transitions and prompt for missing metatdata...
// but that is complex
var buffer bytes.Buffer
- fmt.Fprintf(&buffer,
+ _, _ = fmt.Fprintf(&buffer,
`{"transition":{"id":"%s"}, "resolution": {"name": "Done"}}`,
transitionID)
request, err := http.NewRequest("POST", url, bytes.NewBuffer(buffer.Bytes()))
diff --git a/bridge/jira/export.go b/bridge/jira/export.go
index f2b9d507..f329e490 100644
--- a/bridge/jira/export.go
+++ b/bridge/jira/export.go
@@ -43,47 +43,42 @@ type jiraExporter struct {
}
// Init .
-func (self *jiraExporter) Init(repo *cache.RepoCache,
- conf core.Configuration) error {
- self.conf = conf
- self.identityClient = make(map[entity.Id]*Client)
- self.cachedOperationIDs = make(map[entity.Id]string)
- self.cachedLabels = make(map[string]string)
+func (je *jiraExporter) Init(repo *cache.RepoCache, conf core.Configuration) error {
+ je.conf = conf
+ je.identityClient = make(map[entity.Id]*Client)
+ je.cachedOperationIDs = make(map[entity.Id]string)
+ je.cachedLabels = make(map[string]string)
return nil
}
// getIdentityClient return an API client configured with the credentials
// of the given identity. If no client were found it will initialize it from
// the known credentials map and cache it for next use
-func (self *jiraExporter) getIdentityClient(
- ctx context.Context, id entity.Id) (*Client, error) {
- client, ok := self.identityClient[id]
+func (je *jiraExporter) getIdentityClient(ctx context.Context, id entity.Id) (*Client, error) {
+ client, ok := je.identityClient[id]
if ok {
return client, nil
}
- client = NewClient(self.conf[keyServer], ctx)
+ client = NewClient(je.conf[keyServer], ctx)
// NOTE: as a future enhancement, the bridge would ideally be able to generate
// a separate session token for each user that we have stored credentials
// for. However we currently only support a single user.
- if id != self.userIdentity {
+ if id != je.userIdentity {
return nil, ErrMissingCredentials
}
- err := client.Login(self.conf)
+ err := client.Login(je.conf)
if err != nil {
return nil, err
}
- self.identityClient[id] = client
+ je.identityClient[id] = client
return client, nil
}
// ExportAll export all event made by the current user to Jira
-func (self *jiraExporter) ExportAll(
- ctx context.Context, repo *cache.RepoCache, since time.Time) (
- <-chan core.ExportResult, error) {
-
+func (je *jiraExporter) ExportAll(ctx context.Context, repo *cache.RepoCache, since time.Time) (<-chan core.ExportResult, error) {
out := make(chan core.ExportResult)
user, err := repo.GetUserIdentity()
@@ -93,13 +88,13 @@ func (self *jiraExporter) ExportAll(
// NOTE: this is currently only need to mock the credentials database in
// getIdentityClient.
- self.userIdentity = user.Id()
- client, err := self.getIdentityClient(ctx, user.Id())
+ je.userIdentity = user.Id()
+ client, err := je.getIdentityClient(ctx, user.Id())
if err != nil {
return nil, err
}
- self.project, err = client.GetProject(self.conf[keyProject])
+ je.project, err = client.GetProject(je.conf[keyProject])
if err != nil {
return nil, err
}
@@ -108,7 +103,7 @@ func (self *jiraExporter) ExportAll(
defer close(out)
var allIdentitiesIds []entity.Id
- for id := range self.identityClient {
+ for id := range je.identityClient {
allIdentitiesIds = append(allIdentitiesIds, id)
}
@@ -139,7 +134,7 @@ func (self *jiraExporter) ExportAll(
if snapshot.HasAnyActor(allIdentitiesIds...) {
// try to export the bug and it associated events
- err := self.exportBug(ctx, b, since, out)
+ err := je.exportBug(ctx, b, since, out)
if err != nil {
out <- core.NewExportError(errors.Wrap(err, "can't export bug"), id)
return
@@ -155,9 +150,7 @@ func (self *jiraExporter) ExportAll(
}
// exportBug publish bugs and related events
-func (self *jiraExporter) exportBug(
- ctx context.Context, b *cache.BugCache, since time.Time,
- out chan<- core.ExportResult) error {
+func (je *jiraExporter) exportBug(ctx context.Context, b *cache.BugCache, since time.Time, out chan<- core.ExportResult) error {
snapshot := b.Snapshot()
var bugJiraID string
@@ -182,7 +175,7 @@ func (self *jiraExporter) exportBug(
// skip bug if it is a jira bug but is associated with another project
// (one bridge per JIRA project)
project, ok := snapshot.GetCreateMetadata(keyJiraProject)
- if ok && !stringInSlice(project, []string{self.project.ID, self.project.Key}) {
+ if ok && !stringInSlice(project, []string{je.project.ID, je.project.Key}) {
out <- core.NewExportNothing(
b.Id(), fmt.Sprintf("issue tagged with project: %s", project))
return nil
@@ -195,7 +188,7 @@ func (self *jiraExporter) exportBug(
bugJiraID = jiraID
} else {
// check that we have credentials for operation author
- client, err := self.getIdentityClient(ctx, author.Id())
+ client, err := je.getIdentityClient(ctx, author.Id())
if err != nil {
// if bug is not yet exported and we do not have the author's credentials
// then there is nothing we can do, so just skip this bug
@@ -208,7 +201,7 @@ func (self *jiraExporter) exportBug(
// Load any custom fields required to create an issue from the git
// config file.
fields := make(map[string]interface{})
- defaultFields, hasConf := self.conf[keyCreateDefaults]
+ defaultFields, hasConf := je.conf[keyCreateDefaults]
if hasConf {
err = json.Unmarshal([]byte(defaultFields), &fields)
if err != nil {
@@ -222,7 +215,7 @@ func (self *jiraExporter) exportBug(
"id": "10001",
}
}
- bugIDField, hasConf := self.conf[keyCreateGitBug]
+ bugIDField, hasConf := je.conf[keyCreateGitBug]
if hasConf {
// If the git configuration also indicates it, we can assign the git-bug
// id to a custom field to assist in integrations
@@ -231,7 +224,7 @@ func (self *jiraExporter) exportBug(
// create bug
result, err := client.CreateIssue(
- self.project.ID, createOp.Title, createOp.Message, fields)
+ je.project.ID, createOp.Title, createOp.Message, fields)
if err != nil {
err := errors.Wrap(err, "exporting jira issue")
out <- core.NewExportError(err, b.Id())
@@ -242,7 +235,7 @@ func (self *jiraExporter) exportBug(
out <- core.NewExportBug(b.Id())
// mark bug creation operation as exported
err = markOperationAsExported(
- b, createOp.Id(), id, self.project.Key, time.Time{})
+ b, createOp.Id(), id, je.project.Key, time.Time{})
if err != nil {
err := errors.Wrap(err, "marking operation as exported")
out <- core.NewExportError(err, b.Id())
@@ -262,10 +255,10 @@ func (self *jiraExporter) exportBug(
}
// cache operation jira id
- self.cachedOperationIDs[createOp.Id()] = bugJiraID
+ je.cachedOperationIDs[createOp.Id()] = bugJiraID
// lookup the mapping from git-bug "status" to JIRA "status" id
- statusMap, err := getStatusMap(self.conf)
+ statusMap, err := getStatusMap(je.conf)
if err != nil {
return err
}
@@ -280,12 +273,12 @@ func (self *jiraExporter) exportBug(
// cache the ID of already exported or imported issues and events from
// Jira
if id, ok := op.GetMetadata(keyJiraID); ok {
- self.cachedOperationIDs[op.Id()] = id
+ je.cachedOperationIDs[op.Id()] = id
continue
}
opAuthor := op.GetAuthor()
- client, err := self.getIdentityClient(ctx, opAuthor.Id())
+ client, err := je.getIdentityClient(ctx, opAuthor.Id())
if err != nil {
out <- core.NewExportError(
fmt.Errorf("missing operation author credentials for user %.8s",
@@ -307,7 +300,7 @@ func (self *jiraExporter) exportBug(
out <- core.NewExportComment(op.Id())
// cache comment id
- self.cachedOperationIDs[op.Id()] = id
+ je.cachedOperationIDs[op.Id()] = id
case *bug.EditCommentOperation:
if opr.Target == createOp.Id() {
@@ -325,7 +318,7 @@ func (self *jiraExporter) exportBug(
// Otherwise it's an edit to an actual comment. A comment cannot be
// edited before it was created, so it must be the case that we have
// already observed and cached the AddCommentOperation.
- commentID, ok := self.cachedOperationIDs[opr.Target]
+ commentID, ok := je.cachedOperationIDs[opr.Target]
if !ok {
// Since an edit has to come after the creation, we expect we would
// have cached the creation id.
@@ -392,7 +385,7 @@ func (self *jiraExporter) exportBug(
// mark operation as exported
err = markOperationAsExported(
- b, op.Id(), id, self.project.Key, exportTime)
+ b, op.Id(), id, je.project.Key, exportTime)
if err != nil {
err := errors.Wrap(err, "marking operation as exported")
out <- core.NewExportError(err, b.Id())
@@ -412,10 +405,7 @@ func (self *jiraExporter) exportBug(
return nil
}
-func markOperationAsExported(
- b *cache.BugCache, target entity.Id, jiraID, jiraProject string,
- exportTime time.Time) error {
-
+func markOperationAsExported(b *cache.BugCache, target entity.Id, jiraID, jiraProject string, exportTime time.Time) error {
newMetadata := map[string]string{
keyJiraID: jiraID,
keyJiraProject: jiraProject,
@@ -431,10 +421,7 @@ func markOperationAsExported(
// UpdateIssueStatus attempts to change the "status" field by finding a
// transition which achieves the desired state and then performing that
// transition
-func UpdateIssueStatus(
- client *Client, issueKeyOrID string, desiredStateNameOrID string) (
- time.Time, error) {
-
+func UpdateIssueStatus(client *Client, issueKeyOrID string, desiredStateNameOrID string) (time.Time, error) {
var responseTime time.Time
tlist, err := client.GetTransitions(issueKeyOrID)
diff --git a/bridge/jira/import.go b/bridge/jira/import.go
index bc1bf428..6a755a36 100644
--- a/bridge/jira/import.go
+++ b/bridge/jira/import.go
@@ -35,31 +35,27 @@ type jiraImporter struct {
}
// Init .
-func (gi *jiraImporter) Init(repo *cache.RepoCache,
- conf core.Configuration) error {
- gi.conf = conf
+func (ji *jiraImporter) Init(repo *cache.RepoCache, conf core.Configuration) error {
+ ji.conf = conf
return nil
}
// ImportAll iterate over all the configured repository issues and ensure the
// creation of the missing issues / timeline items / edits / label events ...
-func (self *jiraImporter) ImportAll(
- ctx context.Context, repo *cache.RepoCache, since time.Time) (
- <-chan core.ImportResult, error) {
-
+func (ji *jiraImporter) ImportAll(ctx context.Context, repo *cache.RepoCache, since time.Time) (<-chan core.ImportResult, error) {
sinceStr := since.Format("2006-01-02 15:04")
- serverURL := self.conf[keyServer]
- project := self.conf[keyProject]
+ serverURL := ji.conf[keyServer]
+ project := ji.conf[keyProject]
// TODO(josh)[da52062]: Validate token and if it is expired then prompt for
// credentials and generate a new one
out := make(chan core.ImportResult)
- self.out = out
+ ji.out = out
go func() {
- defer close(self.out)
+ defer close(ji.out)
client := NewClient(serverURL, ctx)
- err := client.Login(self.conf)
+ err := client.Login(ji.conf)
if err != nil {
out <- core.NewImportError(err, "")
return
@@ -79,7 +75,7 @@ func (self *jiraImporter) ImportAll(
for searchIter =
client.IterSearch(jql, defaultPageSize); searchIter.HasNext(); {
issue := searchIter.Next()
- bug, err := self.ensureIssue(repo, *issue)
+ b, err := ji.ensureIssue(repo, *issue)
if err != nil {
err := fmt.Errorf("issue creation: %v", err)
out <- core.NewImportError(err, "")
@@ -90,7 +86,7 @@ func (self *jiraImporter) ImportAll(
for commentIter =
client.IterComments(issue.ID, defaultPageSize); commentIter.HasNext(); {
comment := commentIter.Next()
- err := self.ensureComment(repo, bug, *comment)
+ err := ji.ensureComment(repo, b, *comment)
if err != nil {
out <- core.NewImportError(err, "")
}
@@ -99,7 +95,7 @@ func (self *jiraImporter) ImportAll(
out <- core.NewImportError(commentIter.Err, "")
}
- snapshot := bug.Snapshot()
+ snapshot := b.Snapshot()
opIdx := 0
var changelogIter *ChangeLogIterator
@@ -127,10 +123,9 @@ func (self *jiraImporter) ImportAll(
}
}
if opIdx < len(snapshot.Operations) {
- err = self.ensureChange(
- repo, bug, *changelogEntry, snapshot.Operations[opIdx])
+ err = ji.ensureChange(repo, b, *changelogEntry, snapshot.Operations[opIdx])
} else {
- err = self.ensureChange(repo, bug, *changelogEntry, nil)
+ err = ji.ensureChange(repo, b, *changelogEntry, nil)
}
if err != nil {
out <- core.NewImportError(err, "")
@@ -141,9 +136,9 @@ func (self *jiraImporter) ImportAll(
out <- core.NewImportError(changelogIter.Err, "")
}
- if !bug.NeedCommit() {
- out <- core.NewImportNothing(bug.Id(), "no imported operation")
- } else if err := bug.Commit(); err != nil {
+ if !b.NeedCommit() {
+ out <- core.NewImportNothing(b.Id(), "no imported operation")
+ } else if err := b.Commit(); err != nil {
err = fmt.Errorf("bug commit: %v", err)
out <- core.NewImportError(err, "")
return
@@ -158,9 +153,7 @@ func (self *jiraImporter) ImportAll(
}
// Create a bug.Person from a JIRA user
-func (self *jiraImporter) ensurePerson(
- repo *cache.RepoCache, user User) (*cache.IdentityCache, error) {
-
+func (ji *jiraImporter) ensurePerson(repo *cache.RepoCache, user User) (*cache.IdentityCache, error) {
// Look first in the cache
i, err := repo.ResolveIdentityImmutableMetadata(
keyJiraUser, string(user.Key))
@@ -184,14 +177,13 @@ func (self *jiraImporter) ensurePerson(
return nil, err
}
- self.out <- core.NewImportIdentity(i.Id())
+ ji.out <- core.NewImportIdentity(i.Id())
return i, nil
}
// Create a bug.Bug based from a JIRA issue
-func (self *jiraImporter) ensureIssue(
- repo *cache.RepoCache, issue Issue) (*cache.BugCache, error) {
- author, err := self.ensurePerson(repo, issue.Fields.Creator)
+func (ji *jiraImporter) ensureIssue(repo *cache.RepoCache, issue Issue) (*cache.BugCache, error) {
+ author, err := ji.ensurePerson(repo, issue.Fields.Creator)
if err != nil {
return nil, err
}
@@ -220,13 +212,13 @@ func (self *jiraImporter) ensureIssue(
core.MetaKeyOrigin: target,
keyJiraID: issue.ID,
keyJiraKey: issue.Key,
- keyJiraProject: self.conf[keyProject],
+ keyJiraProject: ji.conf[keyProject],
})
if err != nil {
return nil, err
}
- self.out <- core.NewImportBug(b.Id())
+ ji.out <- core.NewImportBug(b.Id())
}
return b, nil
@@ -238,10 +230,9 @@ func getTimeDerivedID(jiraID string, timestamp MyTime) string {
}
// Create a bug.Comment from a JIRA comment
-func (self *jiraImporter) ensureComment(repo *cache.RepoCache,
- b *cache.BugCache, item Comment) error {
+func (ji *jiraImporter) ensureComment(repo *cache.RepoCache, b *cache.BugCache, item Comment) error {
// ensure person
- author, err := self.ensurePerson(repo, item.Author)
+ author, err := ji.ensurePerson(repo, item.Author)
if err != nil {
return err
}
@@ -279,7 +270,7 @@ func (self *jiraImporter) ensureComment(repo *cache.RepoCache,
return err
}
- self.out <- core.NewImportComment(op.Id())
+ ji.out <- core.NewImportComment(op.Id())
targetOpID = op.Id()
}
@@ -293,8 +284,7 @@ func (self *jiraImporter) ensureComment(repo *cache.RepoCache,
// timestamp. Note that this must be consistent with the exporter during
// export of an EditCommentOperation
derivedID := getTimeDerivedID(item.ID, item.Updated)
- _, err = b.ResolveOperationWithMetadata(
- keyJiraID, derivedID)
+ _, err = b.ResolveOperationWithMetadata(keyJiraID, derivedID)
if err == nil {
// Already imported this edition
return nil
@@ -305,7 +295,7 @@ func (self *jiraImporter) ensureComment(repo *cache.RepoCache,
}
// ensure editor identity
- editor, err := self.ensurePerson(repo, item.UpdateAuthor)
+ editor, err := ji.ensurePerson(repo, item.UpdateAuthor)
if err != nil {
return err
}
@@ -329,7 +319,7 @@ func (self *jiraImporter) ensureComment(repo *cache.RepoCache,
return err
}
- self.out <- core.NewImportCommentEdition(op.Id())
+ ji.out <- core.NewImportCommentEdition(op.Id())
return nil
}
@@ -363,9 +353,7 @@ func labelSetsMatch(jiraSet []string, gitbugSet []bug.Label) bool {
// Create a bug.Operation (or a series of operations) from a JIRA changelog
// entry
-func (self *jiraImporter) ensureChange(
- repo *cache.RepoCache, b *cache.BugCache, entry ChangeLogEntry,
- potentialOp bug.Operation) error {
+func (ji *jiraImporter) ensureChange(repo *cache.RepoCache, b *cache.BugCache, entry ChangeLogEntry, potentialOp bug.Operation) error {
// If we have an operation which is already mapped to the entire changelog
// entry then that means this changelog entry was induced by an export
@@ -383,7 +371,7 @@ func (self *jiraImporter) ensureChange(
// I don't thing git-bug has a single operation to modify an arbitrary
// number of fields in one go, so we break up the single JIRA changelog
// entry into individual field updates.
- author, err := self.ensurePerson(repo, entry.Author)
+ author, err := ji.ensurePerson(repo, entry.Author)
if err != nil {
return err
}
@@ -392,7 +380,7 @@ func (self *jiraImporter) ensureChange(
return fmt.Errorf("Received changelog entry with no item! (%s)", entry.ID)
}
- statusMap, err := getStatusMapReverse(self.conf)
+ statusMap, err := getStatusMapReverse(ji.conf)
if err != nil {
return err
}
@@ -407,13 +395,10 @@ func (self *jiraImporter) ensureChange(
case "labels":
fromLabels := removeEmpty(strings.Split(item.FromString, " "))
toLabels := removeEmpty(strings.Split(item.ToString, " "))
- removedLabels, addedLabels, _ := setSymmetricDifference(
- fromLabels, toLabels)
+ removedLabels, addedLabels, _ := setSymmetricDifference(fromLabels, toLabels)
opr, isRightType := potentialOp.(*bug.LabelChangeOperation)
- if isRightType &&
- labelSetsMatch(addedLabels, opr.Added) &&
- labelSetsMatch(removedLabels, opr.Removed) {
+ if isRightType && labelSetsMatch(addedLabels, opr.Added) && labelSetsMatch(removedLabels, opr.Removed) {
_, err := b.SetMetadata(opr.Id(), map[string]string{
keyJiraOperationID: entry.ID,
})
@@ -484,8 +469,7 @@ func (self *jiraImporter) ensureChange(
case "labels":
fromLabels := removeEmpty(strings.Split(item.FromString, " "))
toLabels := removeEmpty(strings.Split(item.ToString, " "))
- removedLabels, addedLabels, _ := setSymmetricDifference(
- fromLabels, toLabels)
+ removedLabels, addedLabels, _ := setSymmetricDifference(fromLabels, toLabels)
op, err := b.ForceChangeLabelsRaw(
author,
@@ -501,7 +485,7 @@ func (self *jiraImporter) ensureChange(
return err
}
- self.out <- core.NewImportLabelChange(op.Id())
+ ji.out <- core.NewImportLabelChange(op.Id())
case "status":
statusStr, hasMap := statusMap[item.To]
@@ -519,7 +503,7 @@ func (self *jiraImporter) ensureChange(
if err != nil {
return err
}
- self.out <- core.NewImportStatusChange(op.Id())
+ ji.out <- core.NewImportStatusChange(op.Id())
case bug.ClosedStatus.String():
op, err := b.CloseRaw(
@@ -533,10 +517,10 @@ func (self *jiraImporter) ensureChange(
if err != nil {
return err
}
- self.out <- core.NewImportStatusChange(op.Id())
+ ji.out <- core.NewImportStatusChange(op.Id())
}
} else {
- self.out <- core.NewImportError(
+ ji.out <- core.NewImportError(
fmt.Errorf(
"No git-bug status mapped for jira status %s (%s)",
item.ToString, item.To), "")
@@ -558,7 +542,7 @@ func (self *jiraImporter) ensureChange(
return err
}
- self.out <- core.NewImportTitleEdition(op.Id())
+ ji.out <- core.NewImportTitleEdition(op.Id())
case "description":
// NOTE(josh): JIRA calls it "description", which sounds more like the
@@ -576,10 +560,10 @@ func (self *jiraImporter) ensureChange(
return err
}
- self.out <- core.NewImportCommentEdition(op.Id())
+ ji.out <- core.NewImportCommentEdition(op.Id())
default:
- self.out <- core.NewImportWarning(
+ ji.out <- core.NewImportWarning(
fmt.Errorf(
"Unhandled changelog event %s", item.Field), "")
}