diff options
Diffstat (limited to 'bridge')
-rw-r--r-- | bridge/core/bridge.go | 6 | ||||
-rw-r--r-- | bridge/core/export.go | 11 | ||||
-rw-r--r-- | bridge/core/import.go | 14 | ||||
-rw-r--r-- | bridge/github/config.go | 6 | ||||
-rw-r--r-- | bridge/github/export.go | 52 | ||||
-rw-r--r-- | bridge/github/export_test.go | 10 | ||||
-rw-r--r-- | bridge/github/import.go | 108 | ||||
-rw-r--r-- | bridge/github/import_test.go | 2 | ||||
-rw-r--r-- | bridge/gitlab/config.go | 6 | ||||
-rw-r--r-- | bridge/gitlab/export.go | 31 | ||||
-rw-r--r-- | bridge/gitlab/export_test.go | 10 | ||||
-rw-r--r-- | bridge/gitlab/gitlab.go | 8 | ||||
-rw-r--r-- | bridge/gitlab/import.go | 43 | ||||
-rw-r--r-- | bridge/gitlab/import_test.go | 2 | ||||
-rw-r--r-- | bridge/launchpad/config.go | 6 | ||||
-rw-r--r-- | bridge/launchpad/import.go | 26 |
16 files changed, 171 insertions, 170 deletions
diff --git a/bridge/core/bridge.go b/bridge/core/bridge.go index e419ed77..a3133b9c 100644 --- a/bridge/core/bridge.go +++ b/bridge/core/bridge.go @@ -20,8 +20,8 @@ var ErrImportNotSupported = errors.New("import is not supported") var ErrExportNotSupported = errors.New("export is not supported") const ( - KeyTarget = "target" - KeyOrigin = "origin" + ConfigKeyTarget = "target" + MetaKeyOrigin = "origin" bridgeConfigKeyPrefix = "git-bug.bridge" ) @@ -102,7 +102,7 @@ func LoadBridge(repo *cache.RepoCache, name string) (*Bridge, error) { return nil, err } - target := conf[KeyTarget] + target := conf[ConfigKeyTarget] bridge, err := NewBridge(repo, target, name) if err != nil { return nil, err diff --git a/bridge/core/export.go b/bridge/core/export.go index 558b3d78..0f45404c 100644 --- a/bridge/core/export.go +++ b/bridge/core/export.go @@ -10,13 +10,24 @@ type ExportEvent int const ( _ ExportEvent = iota + + // Bug has been exported on the remote tracker ExportEventBug + // Comment has been exported on the remote tracker ExportEventComment + // Comment has been edited on the remote tracker ExportEventCommentEdition + // Bug's status has been changed on on the remote tracker ExportEventStatusChange + // Bug's title has been changed on the remote tracker ExportEventTitleEdition + // Bug's labels have been changed on the remote tracker ExportEventLabelChange + + // Nothing changed on the bug ExportEventNothing + + // Error happened during export ExportEventError ) diff --git a/bridge/core/import.go b/bridge/core/import.go index cff30f61..e4771d2c 100644 --- a/bridge/core/import.go +++ b/bridge/core/import.go @@ -10,14 +10,26 @@ type ImportEvent int const ( _ ImportEvent = iota + + // Bug has been created ImportEventBug + // Comment has been created ImportEventComment + // Comment has been edited ImportEventCommentEdition + // Bug's status has changed ImportEventStatusChange + // Bug's title has changed ImportEventTitleEdition + // Bug's labels changed ImportEventLabelChange - ImportEventIdentity + // Nothing happened on a Bug ImportEventNothing + + // Identity has been created + ImportEventIdentity + + // Error happened during import ImportEventError ) diff --git a/bridge/github/config.go b/bridge/github/config.go index 16abfa09..434a2c63 100644 --- a/bridge/github/config.go +++ b/bridge/github/config.go @@ -114,7 +114,7 @@ func (g *Github) Configure(repo repository.RepoCommon, params core.BridgeParams) return nil, fmt.Errorf("project doesn't exist or authentication token has an incorrect scope") } - conf[core.KeyTarget] = target + conf[core.ConfigKeyTarget] = target conf[keyToken] = token conf[keyOwner] = owner conf[keyProject] = project @@ -128,8 +128,8 @@ func (g *Github) Configure(repo repository.RepoCommon, params core.BridgeParams) } func (*Github) ValidateConfig(conf core.Configuration) error { - if v, ok := conf[core.KeyTarget]; !ok { - return fmt.Errorf("missing %s key", core.KeyTarget) + if v, ok := conf[core.ConfigKeyTarget]; !ok { + return fmt.Errorf("missing %s key", core.ConfigKeyTarget) } else if v != target { return fmt.Errorf("unexpected target name: %v", v) } diff --git a/bridge/github/export.go b/bridge/github/export.go index a79256fc..2fb92636 100644 --- a/bridge/github/export.go +++ b/bridge/github/export.go @@ -148,8 +148,6 @@ func (ge *githubExporter) ExportAll(ctx context.Context, repo *cache.RepoCache, if snapshot.HasAnyActor(allIdentitiesIds...) { // try to export the bug and it associated events ge.exportBug(ctx, b, since, out) - } else { - out <- core.NewExportNothing(id, "not an actor") } } } @@ -161,6 +159,7 @@ func (ge *githubExporter) ExportAll(ctx context.Context, repo *cache.RepoCache, // exportBug publish bugs and related events func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, since time.Time, out chan<- core.ExportResult) { snapshot := b.Snapshot() + var bugUpdated bool var bugGithubID string var bugGithubURL string @@ -174,16 +173,16 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc author := snapshot.Author // skip bug if origin is not allowed - origin, ok := snapshot.GetCreateMetadata(keyOrigin) + origin, ok := snapshot.GetCreateMetadata(core.MetaKeyOrigin) if ok && origin != target { out <- core.NewExportNothing(b.Id(), fmt.Sprintf("issue tagged with origin: %s", origin)) return } // get github bug ID - githubID, ok := snapshot.GetCreateMetadata(keyGithubId) + githubID, ok := snapshot.GetCreateMetadata(metaKeyGithubId) if ok { - githubURL, ok := snapshot.GetCreateMetadata(keyGithubUrl) + githubURL, ok := snapshot.GetCreateMetadata(metaKeyGithubUrl) if !ok { // if we find github ID, github URL must be found too err := fmt.Errorf("incomplete Github metadata: expected to find issue URL") @@ -198,13 +197,12 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc return } - // ignore issue comming from other repositories + // ignore issue coming from other repositories if owner != ge.conf[keyOwner] && project != ge.conf[keyProject] { out <- core.NewExportNothing(b.Id(), fmt.Sprintf("skipping issue from url:%s", githubURL)) return } - out <- core.NewExportNothing(b.Id(), "bug already exported") // will be used to mark operation related to a bug as exported bugGithubID = githubID bugGithubURL = githubURL @@ -258,26 +256,22 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc // ignore operations already existing in github (due to import or export) // cache the ID of already exported or imported issues and events from Github - if id, ok := op.GetMetadata(keyGithubId); ok { + if id, ok := op.GetMetadata(metaKeyGithubId); ok { ge.cachedOperationIDs[op.Id()] = id - out <- core.NewExportNothing(op.Id(), "already exported operation") continue } opAuthor := op.GetAuthor() client, err := ge.getIdentityClient(opAuthor.Id()) if err != nil { - out <- core.NewExportNothing(op.Id(), "missing operation author token") continue } var id, url string - switch op.(type) { + switch op := op.(type) { case *bug.AddCommentOperation: - opr := op.(*bug.AddCommentOperation) - // send operation to github - id, url, err = addCommentGithubIssue(ctx, client, bugGithubID, opr.Message) + id, url, err = addCommentGithubIssue(ctx, client, bugGithubID, op.Message) if err != nil { err := errors.Wrap(err, "adding comment") out <- core.NewExportError(err, b.Id()) @@ -290,14 +284,11 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc ge.cachedOperationIDs[op.Id()] = id case *bug.EditCommentOperation: - - opr := op.(*bug.EditCommentOperation) - // Since github doesn't consider the issue body as a comment - if opr.Target == createOp.Id() { + if op.Target == createOp.Id() { // case bug creation operation: we need to edit the Github issue - if err := updateGithubIssueBody(ctx, client, bugGithubID, opr.Message); err != nil { + if err := updateGithubIssueBody(ctx, client, bugGithubID, op.Message); err != nil { err := errors.Wrap(err, "editing issue") out <- core.NewExportError(err, b.Id()) return @@ -311,12 +302,12 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc } else { // case comment edition operation: we need to edit the Github comment - commentID, ok := ge.cachedOperationIDs[opr.Target] + commentID, ok := ge.cachedOperationIDs[op.Target] if !ok { panic("unexpected error: comment id not found") } - eid, eurl, err := editCommentGithubIssue(ctx, client, commentID, opr.Message) + eid, eurl, err := editCommentGithubIssue(ctx, client, commentID, op.Message) if err != nil { err := errors.Wrap(err, "editing comment") out <- core.NewExportError(err, b.Id()) @@ -331,8 +322,7 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc } case *bug.SetStatusOperation: - opr := op.(*bug.SetStatusOperation) - if err := updateGithubIssueStatus(ctx, client, bugGithubID, opr.Status); err != nil { + if err := updateGithubIssueStatus(ctx, client, bugGithubID, op.Status); err != nil { err := errors.Wrap(err, "editing status") out <- core.NewExportError(err, b.Id()) return @@ -344,8 +334,7 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc url = bugGithubURL case *bug.SetTitleOperation: - opr := op.(*bug.SetTitleOperation) - if err := updateGithubIssueTitle(ctx, client, bugGithubID, opr.Title); err != nil { + if err := updateGithubIssueTitle(ctx, client, bugGithubID, op.Title); err != nil { err := errors.Wrap(err, "editing title") out <- core.NewExportError(err, b.Id()) return @@ -357,8 +346,7 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc url = bugGithubURL case *bug.LabelChangeOperation: - opr := op.(*bug.LabelChangeOperation) - if err := ge.updateGithubIssueLabels(ctx, client, bugGithubID, opr.Added, opr.Removed); err != nil { + if err := ge.updateGithubIssueLabels(ctx, client, bugGithubID, op.Added, op.Removed); err != nil { err := errors.Wrap(err, "updating labels") out <- core.NewExportError(err, b.Id()) return @@ -386,6 +374,12 @@ func (ge *githubExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc out <- core.NewExportError(err, b.Id()) return } + + bugUpdated = true + } + + if !bugUpdated { + out <- core.NewExportNothing(b.Id(), "nothing has been exported") } } @@ -437,8 +431,8 @@ func markOperationAsExported(b *cache.BugCache, target entity.Id, githubID, gith _, err := b.SetMetadata( target, map[string]string{ - keyGithubId: githubID, - keyGithubUrl: githubURL, + metaKeyGithubId: githubID, + metaKeyGithubUrl: githubURL, }, ) diff --git a/bridge/github/export_test.go b/bridge/github/export_test.go index e39ace01..dba72f3f 100644 --- a/bridge/github/export_test.go +++ b/bridge/github/export_test.go @@ -233,27 +233,27 @@ func TestPushPull(t *testing.T) { for _, op := range tt.bug.Snapshot().Operations { // Check if the originals operations (*not* SetMetadata) are tagged properly if _, ok := op.(*bug.SetMetadataOperation); !ok { - _, haveIDMetadata := op.GetMetadata(keyGithubId) + _, haveIDMetadata := op.GetMetadata(metaKeyGithubId) require.True(t, haveIDMetadata) - _, haveURLMetada := op.GetMetadata(keyGithubUrl) + _, haveURLMetada := op.GetMetadata(metaKeyGithubUrl) require.True(t, haveURLMetada) } } // get bug github ID - bugGithubID, ok := tt.bug.Snapshot().GetCreateMetadata(keyGithubId) + bugGithubID, ok := tt.bug.Snapshot().GetCreateMetadata(metaKeyGithubId) require.True(t, ok) // retrieve bug from backendTwo - importedBug, err := backendTwo.ResolveBugCreateMetadata(keyGithubId, bugGithubID) + importedBug, err := backendTwo.ResolveBugCreateMetadata(metaKeyGithubId, bugGithubID) require.NoError(t, err) // verify bug have same number of original operations require.Len(t, importedBug.Snapshot().Operations, tt.numOrOp) // verify bugs are taged with origin=github - issueOrigin, ok := importedBug.Snapshot().GetCreateMetadata(keyOrigin) + issueOrigin, ok := importedBug.Snapshot().GetCreateMetadata(core.MetaKeyOrigin) require.True(t, ok) require.Equal(t, issueOrigin, target) diff --git a/bridge/github/import.go b/bridge/github/import.go index 7c4deb50..86444057 100644 --- a/bridge/github/import.go +++ b/bridge/github/import.go @@ -15,10 +15,9 @@ import ( ) const ( - keyOrigin = "origin" - keyGithubId = "github-id" - keyGithubUrl = "github-url" - keyGithubLogin = "github-login" + metaKeyGithubId = "github-id" + metaKeyGithubUrl = "github-url" + metaKeyGithubLogin = "github-login" ) // githubImporter implement the Importer interface @@ -61,15 +60,18 @@ func (gi *githubImporter) ImportAll(ctx context.Context, repo *cache.RepoCache, // loop over timeline items for gi.iterator.NextTimelineItem() { item := gi.iterator.TimelineItemValue() - if err := gi.ensureTimelineItem(repo, b, item); err != nil { - err := fmt.Errorf("timeline item creation: %v", err) + err := gi.ensureTimelineItem(repo, b, item) + if err != nil { + err = fmt.Errorf("timeline item creation: %v", err) out <- core.NewImportError(err, "") return } } - // commit bug state - if err := b.CommitAsNeeded(); err != nil { + if !b.NeedCommit() { + out <- core.NewImportNothing(b.Id(), "no imported operation") + } else if err := b.Commit(); err != nil { + // commit bug state err = fmt.Errorf("bug commit: %v", err) out <- core.NewImportError(err, "") return @@ -92,7 +94,7 @@ func (gi *githubImporter) ensureIssue(repo *cache.RepoCache, issue issueTimeline } // resolve bug - b, err := repo.ResolveBugCreateMetadata(keyGithubUrl, issue.Url.String()) + b, err := repo.ResolveBugCreateMetadata(metaKeyGithubUrl, issue.Url.String()) if err != nil && err != bug.ErrBugNotExist { return nil, err } @@ -119,9 +121,9 @@ func (gi *githubImporter) ensureIssue(repo *cache.RepoCache, issue issueTimeline cleanText, nil, map[string]string{ - keyOrigin: target, - keyGithubId: parseId(issue.Id), - keyGithubUrl: issue.Url.String(), + core.MetaKeyOrigin: target, + metaKeyGithubId: parseId(issue.Id), + metaKeyGithubUrl: issue.Url.String(), }) if err != nil { return nil, err @@ -129,16 +131,12 @@ func (gi *githubImporter) ensureIssue(repo *cache.RepoCache, issue issueTimeline // importing a new bug gi.out <- core.NewImportBug(b.Id()) - } else { - gi.out <- core.NewImportNothing("", "bug already imported") } - } else { // create bug from given issueEdits for i, edit := range issueEdits { if i == 0 && b != nil { // The first edit in the github result is the issue creation itself, we already have that - gi.out <- core.NewImportNothing("", "bug already imported") continue } @@ -157,23 +155,22 @@ func (gi *githubImporter) ensureIssue(repo *cache.RepoCache, issue issueTimeline cleanText, nil, map[string]string{ - keyOrigin: target, - keyGithubId: parseId(issue.Id), - keyGithubUrl: issue.Url.String(), + core.MetaKeyOrigin: target, + metaKeyGithubId: parseId(issue.Id), + metaKeyGithubUrl: issue.Url.String(), }, ) if err != nil { return nil, err } - // importing a new bug gi.out <- core.NewImportBug(b.Id()) continue } // other edits will be added as CommentEdit operations - target, err := b.ResolveOperationWithMetadata(keyGithubId, parseId(issue.Id)) + target, err := b.ResolveOperationWithMetadata(metaKeyGithubId, parseId(issue.Id)) if err != nil { return nil, err } @@ -203,13 +200,12 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug if err != nil { return fmt.Errorf("timeline comment creation: %v", err) } + return nil case "LabeledEvent": id := parseId(item.LabeledEvent.Id) - _, err := b.ResolveOperationWithMetadata(keyGithubId, id) + _, err := b.ResolveOperationWithMetadata(metaKeyGithubId, id) if err == nil { - reason := fmt.Sprintf("operation already imported: %v", item.Typename) - gi.out <- core.NewImportNothing("", reason) return nil } @@ -227,7 +223,7 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug string(item.LabeledEvent.Label.Name), }, nil, - map[string]string{keyGithubId: id}, + map[string]string{metaKeyGithubId: id}, ) if err != nil { return err @@ -238,10 +234,8 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug case "UnlabeledEvent": id := parseId(item.UnlabeledEvent.Id) - _, err := b.ResolveOperationWithMetadata(keyGithubId, id) + _, err := b.ResolveOperationWithMetadata(metaKeyGithubId, id) if err == nil { - reason := fmt.Sprintf("operation already imported: %v", item.Typename) - gi.out <- core.NewImportNothing("", reason) return nil } if err != cache.ErrNoMatchingOp { @@ -259,7 +253,7 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug []string{ string(item.UnlabeledEvent.Label.Name), }, - map[string]string{keyGithubId: id}, + map[string]string{metaKeyGithubId: id}, ) if err != nil { return err @@ -270,13 +264,11 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug case "ClosedEvent": id := parseId(item.ClosedEvent.Id) - _, err := b.ResolveOperationWithMetadata(keyGithubId, id) + _, err := b.ResolveOperationWithMetadata(metaKeyGithubId, id) if err != cache.ErrNoMatchingOp { return err } if err == nil { - reason := fmt.Sprintf("operation already imported: %v", item.Typename) - gi.out <- core.NewImportNothing("", reason) return nil } author, err := gi.ensurePerson(repo, item.ClosedEvent.Actor) @@ -286,7 +278,7 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug op, err := b.CloseRaw( author, item.ClosedEvent.CreatedAt.Unix(), - map[string]string{keyGithubId: id}, + map[string]string{metaKeyGithubId: id}, ) if err != nil { @@ -298,13 +290,11 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug case "ReopenedEvent": id := parseId(item.ReopenedEvent.Id) - _, err := b.ResolveOperationWithMetadata(keyGithubId, id) + _, err := b.ResolveOperationWithMetadata(metaKeyGithubId, id) if err != cache.ErrNoMatchingOp { return err } if err == nil { - reason := fmt.Sprintf("operation already imported: %v", item.Typename) - gi.out <- core.NewImportNothing("", reason) return nil } author, err := gi.ensurePerson(repo, item.ReopenedEvent.Actor) @@ -314,7 +304,7 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug op, err := b.OpenRaw( author, item.ReopenedEvent.CreatedAt.Unix(), - map[string]string{keyGithubId: id}, + map[string]string{metaKeyGithubId: id}, ) if err != nil { @@ -326,13 +316,11 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug case "RenamedTitleEvent": id := parseId(item.RenamedTitleEvent.Id) - _, err := b.ResolveOperationWithMetadata(keyGithubId, id) + _, err := b.ResolveOperationWithMetadata(metaKeyGithubId, id) if err != cache.ErrNoMatchingOp { return err } if err == nil { - reason := fmt.Sprintf("operation already imported: %v", item.Typename) - gi.out <- core.NewImportNothing("", reason) return nil } author, err := gi.ensurePerson(repo, item.RenamedTitleEvent.Actor) @@ -343,7 +331,7 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug author, item.RenamedTitleEvent.CreatedAt.Unix(), string(item.RenamedTitleEvent.CurrentTitle), - map[string]string{keyGithubId: id}, + map[string]string{metaKeyGithubId: id}, ) if err != nil { return err @@ -351,10 +339,6 @@ func (gi *githubImporter) ensureTimelineItem(repo *cache.RepoCache, b *cache.Bug gi.out <- core.NewImportTitleEdition(op.Id()) return nil - - default: - reason := fmt.Sprintf("ignoring timeline type: %v", item.Typename) - gi.out <- core.NewImportNothing("", reason) } return nil @@ -367,10 +351,8 @@ func (gi *githubImporter) ensureTimelineComment(repo *cache.RepoCache, b *cache. return err } - targetOpID, err := b.ResolveOperationWithMetadata(keyGithubId, parseId(item.Id)) - if err == nil { - gi.out <- core.NewImportNothing("", "comment already imported") - } else if err != cache.ErrNoMatchingOp { + targetOpID, err := b.ResolveOperationWithMetadata(metaKeyGithubId, parseId(item.Id)) + if err != nil && err != cache.ErrNoMatchingOp { // real error return err } @@ -390,8 +372,8 @@ func (gi *githubImporter) ensureTimelineComment(repo *cache.RepoCache, b *cache. cleanText, nil, map[string]string{ - keyGithubId: parseId(item.Id), - keyGithubUrl: parseId(item.Url.String()), + metaKeyGithubId: parseId(item.Id), + metaKeyGithubUrl: parseId(item.Url.String()), }, ) if err != nil { @@ -399,13 +381,13 @@ func (gi *githubImporter) ensureTimelineComment(repo *cache.RepoCache, b *cache. } gi.out <- core.NewImportComment(op.Id()) + return nil } } else { for i, edit := range edits { if i == 0 && targetOpID != "" { // The first edit in the github result is the comment creation itself, we already have that - gi.out <- core.NewImportNothing("", "comment already imported") continue } @@ -428,13 +410,14 @@ func (gi *githubImporter) ensureTimelineComment(repo *cache.RepoCache, b *cache. cleanText, nil, map[string]string{ - keyGithubId: parseId(item.Id), - keyGithubUrl: item.Url.String(), + metaKeyGithubId: parseId(item.Id), + metaKeyGithubUrl: item.Url.String(), }, ) if err != nil { return err } + gi.out <- core.NewImportComment(op.Id()) // set target for the nexr edit now that the comment is created targetOpID = op.Id() @@ -451,9 +434,8 @@ func (gi *githubImporter) ensureTimelineComment(repo *cache.RepoCache, b *cache. } func (gi *githubImporter) ensureCommentEdit(repo *cache.RepoCache, b *cache.BugCache, target entity.Id, edit userContentEdit) error { - _, err := b.ResolveOperationWithMetadata(keyGithubId, parseId(edit.Id)) + _, err := b.ResolveOperationWithMetadata(metaKeyGithubId, parseId(edit.Id)) if err == nil { - gi.out <- core.NewImportNothing(b.Id(), "edition already imported") return nil } if err != cache.ErrNoMatchingOp { @@ -469,7 +451,7 @@ func (gi *githubImporter) ensureCommentEdit(repo *cache.RepoCache, b *cache.BugC switch { case edit.DeletedAt != nil: // comment deletion, not supported yet - gi.out <- core.NewImportNothing(b.Id(), "comment deletion is not supported yet") + return nil case edit.DeletedAt == nil: @@ -485,7 +467,7 @@ func (gi *githubImporter) ensureCommentEdit(repo *cache.RepoCache, b *cache.BugC target, cleanText, map[string]string{ - keyGithubId: parseId(edit.Id), + metaKeyGithubId: parseId(edit.Id), }, ) @@ -494,8 +476,8 @@ func (gi *githubImporter) ensureCommentEdit(repo *cache.RepoCache, b *cache.BugC } gi.out <- core.NewImportCommentEdition(op.Id()) + return nil } - return nil } @@ -508,7 +490,7 @@ func (gi *githubImporter) ensurePerson(repo *cache.RepoCache, actor *actor) (*ca } // Look first in the cache - i, err := repo.ResolveIdentityImmutableMetadata(keyGithubLogin, string(actor.Login)) + i, err := repo.ResolveIdentityImmutableMetadata(metaKeyGithubLogin, string(actor.Login)) if err == nil { return i, nil } @@ -543,7 +525,7 @@ func (gi *githubImporter) ensurePerson(repo *cache.RepoCache, actor *actor) (*ca string(actor.Login), string(actor.AvatarUrl), map[string]string{ - keyGithubLogin: string(actor.Login), + metaKeyGithubLogin: string(actor.Login), }, ) @@ -557,7 +539,7 @@ func (gi *githubImporter) ensurePerson(repo *cache.RepoCache, actor *actor) (*ca func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*cache.IdentityCache, error) { // Look first in the cache - i, err := repo.ResolveIdentityImmutableMetadata(keyGithubLogin, "ghost") + i, err := repo.ResolveIdentityImmutableMetadata(metaKeyGithubLogin, "ghost") if err == nil { return i, nil } @@ -592,7 +574,7 @@ func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*cache.IdentityCache, string(q.User.Login), string(q.User.AvatarUrl), map[string]string{ - keyGithubLogin: string(q.User.Login), + metaKeyGithubLogin: string(q.User.Login), }, ) } diff --git a/bridge/github/import_test.go b/bridge/github/import_test.go index 41bcb58d..f1558831 100644 --- a/bridge/github/import_test.go +++ b/bridge/github/import_test.go @@ -163,7 +163,7 @@ func Test_Importer(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - b, err := backend.ResolveBugCreateMetadata(keyGithubUrl, tt.url) + b, err := backend.ResolveBugCreateMetadata(metaKeyGithubUrl, tt.url) require.NoError(t, err) ops := b.Snapshot().Operations diff --git a/bridge/gitlab/config.go b/bridge/gitlab/config.go index a673af8c..f2e667a8 100644 --- a/bridge/gitlab/config.go +++ b/bridge/gitlab/config.go @@ -80,7 +80,7 @@ func (g *Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams) conf[keyProjectID] = strconv.Itoa(id) conf[keyToken] = token - conf[core.KeyTarget] = target + conf[core.ConfigKeyTarget] = target err = g.ValidateConfig(conf) if err != nil { @@ -91,8 +91,8 @@ func (g *Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams) } func (g *Gitlab) ValidateConfig(conf core.Configuration) error { - if v, ok := conf[core.KeyTarget]; !ok { - return fmt.Errorf("missing %s key", core.KeyTarget) + if v, ok := conf[core.ConfigKeyTarget]; !ok { + return fmt.Errorf("missing %s key", core.ConfigKeyTarget) } else if v != target { return fmt.Errorf("unexpected target name: %v", v) } diff --git a/bridge/gitlab/export.go b/bridge/gitlab/export.go index 251d720a..7c00e39d 100644 --- a/bridge/gitlab/export.go +++ b/bridge/gitlab/export.go @@ -117,8 +117,6 @@ func (ge *gitlabExporter) ExportAll(ctx context.Context, repo *cache.RepoCache, if snapshot.HasAnyActor(allIdentitiesIds...) { // try to export the bug and it associated events ge.exportBug(ctx, b, since, out) - } else { - out <- core.NewExportNothing(id, "not an actor") } } } @@ -131,6 +129,7 @@ func (ge *gitlabExporter) ExportAll(ctx context.Context, repo *cache.RepoCache, func (ge *gitlabExporter) exportBug(ctx context.Context, b *cache.BugCache, since time.Time, out chan<- core.ExportResult) { snapshot := b.Snapshot() + var bugUpdated bool var err error var bugGitlabID int var bugGitlabIDString string @@ -141,7 +140,7 @@ func (ge *gitlabExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc // from Gitlab) and we do not have the token of the bug author, there is nothing we can do. // skip bug if origin is not allowed - origin, ok := snapshot.GetCreateMetadata(core.KeyOrigin) + origin, ok := snapshot.GetCreateMetadata(core.MetaKeyOrigin) if ok && origin != target { out <- core.NewExportNothing(b.Id(), fmt.Sprintf("issue tagged with origin: %s", origin)) return @@ -152,9 +151,9 @@ func (ge *gitlabExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc author := snapshot.Author // get gitlab bug ID - gitlabID, ok := snapshot.GetCreateMetadata(keyGitlabId) + gitlabID, ok := snapshot.GetCreateMetadata(metaKeyGitlabId) if ok { - projectID, ok := snapshot.GetCreateMetadata(keyGitlabProject) + projectID, ok := snapshot.GetCreateMetadata(metaKeyGitlabProject) if !ok { err := fmt.Errorf("expected to find gitlab project id") out <- core.NewExportError(err, b.Id()) @@ -166,8 +165,6 @@ func (ge *gitlabExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc return } - out <- core.NewExportNothing(b.Id(), "bug already exported") - // will be used to mark operation related to a bug as exported bugGitlabIDString = gitlabID bugGitlabID, err = strconv.Atoi(bugGitlabIDString) @@ -199,9 +196,9 @@ func (ge *gitlabExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc _, err = b.SetMetadata( createOp.Id(), map[string]string{ - keyGitlabId: idString, - keyGitlabUrl: url, - keyGitlabProject: ge.repositoryID, + metaKeyGitlabId: idString, + metaKeyGitlabUrl: url, + metaKeyGitlabProject: ge.repositoryID, }, ) if err != nil { @@ -235,16 +232,14 @@ func (ge *gitlabExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc // ignore operations already existing in gitlab (due to import or export) // cache the ID of already exported or imported issues and events from Gitlab - if id, ok := op.GetMetadata(keyGitlabId); ok { + if id, ok := op.GetMetadata(metaKeyGitlabId); ok { ge.cachedOperationIDs[op.Id().String()] = id - out <- core.NewExportNothing(op.Id(), "already exported operation") continue } opAuthor := op.GetAuthor() client, err := ge.getIdentityClient(opAuthor.Id()) if err != nil { - out <- core.NewExportNothing(op.Id(), "missing operation author token") continue } @@ -371,6 +366,12 @@ func (ge *gitlabExporter) exportBug(ctx context.Context, b *cache.BugCache, sinc out <- core.NewExportError(err, b.Id()) return } + + bugUpdated = true + } + + if !bugUpdated { + out <- core.NewExportNothing(b.Id(), "nothing has been exported") } } @@ -378,8 +379,8 @@ func markOperationAsExported(b *cache.BugCache, target entity.Id, gitlabID, gitl _, err := b.SetMetadata( target, map[string]string{ - keyGitlabId: gitlabID, - keyGitlabUrl: gitlabURL, + metaKeyGitlabId: gitlabID, + metaKeyGitlabUrl: gitlabURL, }, ) diff --git a/bridge/gitlab/export_test.go b/bridge/gitlab/export_test.go index 3d3f406f..26b47bfb 100644 --- a/bridge/gitlab/export_test.go +++ b/bridge/gitlab/export_test.go @@ -236,27 +236,27 @@ func TestPushPull(t *testing.T) { for _, op := range tt.bug.Snapshot().Operations { // Check if the originals operations (*not* SetMetadata) are tagged properly if _, ok := op.(*bug.SetMetadataOperation); !ok { - _, haveIDMetadata := op.GetMetadata(keyGitlabId) + _, haveIDMetadata := op.GetMetadata(metaKeyGitlabId) require.True(t, haveIDMetadata) - _, haveURLMetada := op.GetMetadata(keyGitlabUrl) + _, haveURLMetada := op.GetMetadata(metaKeyGitlabUrl) require.True(t, haveURLMetada) } } // get bug gitlab ID - bugGitlabID, ok := tt.bug.Snapshot().GetCreateMetadata(keyGitlabId) + bugGitlabID, ok := tt.bug.Snapshot().GetCreateMetadata(metaKeyGitlabId) require.True(t, ok) // retrieve bug from backendTwo - importedBug, err := backendTwo.ResolveBugCreateMetadata(keyGitlabId, bugGitlabID) + importedBug, err := backendTwo.ResolveBugCreateMetadata(metaKeyGitlabId, bugGitlabID) require.NoError(t, err) // verify bug have same number of original operations require.Len(t, importedBug.Snapshot().Operations, tt.numOpImp) // verify bugs are taged with origin=gitlab - issueOrigin, ok := importedBug.Snapshot().GetCreateMetadata(core.KeyOrigin) + issueOrigin, ok := importedBug.Snapshot().GetCreateMetadata(core.MetaKeyOrigin) require.True(t, ok) require.Equal(t, issueOrigin, target) diff --git a/bridge/gitlab/gitlab.go b/bridge/gitlab/gitlab.go index 05721bfe..d976d813 100644 --- a/bridge/gitlab/gitlab.go +++ b/bridge/gitlab/gitlab.go @@ -12,10 +12,10 @@ import ( const ( target = "gitlab" - keyGitlabId = "gitlab-id" - keyGitlabUrl = "gitlab-url" - keyGitlabLogin = "gitlab-login" - keyGitlabProject = "gitlab-project-id" + metaKeyGitlabId = "gitlab-id" + metaKeyGitlabUrl = "gitlab-url" + metaKeyGitlabLogin = "gitlab-login" + metaKeyGitlabProject = "gitlab-project-id" keyProjectID = "project-id" keyToken = "token" diff --git a/bridge/gitlab/import.go b/bridge/gitlab/import.go index e2015773..92e9952e 100644 --- a/bridge/gitlab/import.go +++ b/bridge/gitlab/import.go @@ -73,8 +73,10 @@ func (gi *gitlabImporter) ImportAll(ctx context.Context, repo *cache.RepoCache, } } - // commit bug state - if err := b.CommitAsNeeded(); err != nil { + if !b.NeedCommit() { + out <- core.NewImportNothing(b.Id(), "no imported operation") + } else if err := b.Commit(); err != nil { + // commit bug state err := fmt.Errorf("bug commit: %v", err) out <- core.NewImportError(err, "") return @@ -97,9 +99,8 @@ func (gi *gitlabImporter) ensureIssue(repo *cache.RepoCache, issue *gitlab.Issue } // resolve bug - b, err := repo.ResolveBugCreateMetadata(keyGitlabUrl, issue.WebURL) + b, err := repo.ResolveBugCreateMetadata(metaKeyGitlabUrl, issue.WebURL) if err == nil { - gi.out <- core.NewImportNothing("", "bug already imported") return b, nil } if err != bug.ErrBugNotExist { @@ -120,10 +121,10 @@ func (gi *gitlabImporter) ensureIssue(repo *cache.RepoCache, issue *gitlab.Issue cleanText, nil, map[string]string{ - core.KeyOrigin: target, - keyGitlabId: parseID(issue.IID), - keyGitlabUrl: issue.WebURL, - keyGitlabProject: gi.conf[keyProjectID], + core.MetaKeyOrigin: target, + metaKeyGitlabId: parseID(issue.IID), + metaKeyGitlabUrl: issue.WebURL, + metaKeyGitlabProject: gi.conf[keyProjectID], }, ) @@ -140,7 +141,7 @@ func (gi *gitlabImporter) ensureIssue(repo *cache.RepoCache, issue *gitlab.Issue func (gi *gitlabImporter) ensureNote(repo *cache.RepoCache, b *cache.BugCache, note *gitlab.Note) error { gitlabID := parseID(note.ID) - id, errResolve := b.ResolveOperationWithMetadata(keyGitlabId, gitlabID) + id, errResolve := b.ResolveOperationWithMetadata(metaKeyGitlabId, gitlabID) if errResolve != nil && errResolve != cache.ErrNoMatchingOp { return errResolve } @@ -162,7 +163,7 @@ func (gi *gitlabImporter) ensureNote(repo *cache.RepoCache, b *cache.BugCache, n author, note.CreatedAt.Unix(), map[string]string{ - keyGitlabId: gitlabID, + metaKeyGitlabId: gitlabID, }, ) if err != nil { @@ -180,7 +181,7 @@ func (gi *gitlabImporter) ensureNote(repo *cache.RepoCache, b *cache.BugCache, n author, note.CreatedAt.Unix(), map[string]string{ - keyGitlabId: gitlabID, + metaKeyGitlabId: gitlabID, }, ) if err != nil { @@ -204,7 +205,7 @@ func (gi *gitlabImporter) ensureNote(repo *cache.RepoCache, b *cache.BugCache, n firstComment.Id(), issue.Description, map[string]string{ - keyGitlabId: gitlabID, + metaKeyGitlabId: gitlabID, }, ) if err != nil { @@ -230,7 +231,7 @@ func (gi *gitlabImporter) ensureNote(repo *cache.RepoCache, b *cache.BugCache, n cleanText, nil, map[string]string{ - keyGitlabId: gitlabID, + metaKeyGitlabId: gitlabID, }, ) if err != nil { @@ -278,7 +279,7 @@ func (gi *gitlabImporter) ensureNote(repo *cache.RepoCache, b *cache.BugCache, n note.CreatedAt.Unix(), body, map[string]string{ - keyGitlabId: gitlabID, + metaKeyGitlabId: gitlabID, }, ) if err != nil { @@ -299,8 +300,6 @@ func (gi *gitlabImporter) ensureNote(repo *cache.RepoCache, b *cache.BugCache, n NOTE_MENTIONED_IN_ISSUE, NOTE_MENTIONED_IN_MERGE_REQUEST: - reason := fmt.Sprintf("unsupported note type: %s", noteType.String()) - gi.out <- core.NewImportNothing("", reason) return nil default: @@ -311,7 +310,7 @@ func (gi *gitlabImporter) ensureNote(repo *cache.RepoCache, b *cache.BugCache, n } func (gi *gitlabImporter) ensureLabelEvent(repo *cache.RepoCache, b *cache.BugCache, labelEvent *gitlab.LabelEvent) error { - _, err := b.ResolveOperationWithMetadata(keyGitlabId, parseID(labelEvent.ID)) + _, err := b.ResolveOperationWithMetadata(metaKeyGitlabId, parseID(labelEvent.ID)) if err != cache.ErrNoMatchingOp { return err } @@ -330,7 +329,7 @@ func (gi *gitlabImporter) ensureLabelEvent(repo *cache.RepoCache, b *cache.BugCa []string{labelEvent.Label.Name}, nil, map[string]string{ - keyGitlabId: parseID(labelEvent.ID), + metaKeyGitlabId: parseID(labelEvent.ID), }, ) @@ -341,7 +340,7 @@ func (gi *gitlabImporter) ensureLabelEvent(repo *cache.RepoCache, b *cache.BugCa nil, []string{labelEvent.Label.Name}, map[string]string{ - keyGitlabId: parseID(labelEvent.ID), + metaKeyGitlabId: parseID(labelEvent.ID), }, ) @@ -354,7 +353,7 @@ func (gi *gitlabImporter) ensureLabelEvent(repo *cache.RepoCache, b *cache.BugCa func (gi *gitlabImporter) ensurePerson(repo *cache.RepoCache, id int) (*cache.IdentityCache, error) { // Look first in the cache - i, err := repo.ResolveIdentityImmutableMetadata(keyGitlabId, strconv.Itoa(id)) + i, err := repo.ResolveIdentityImmutableMetadata(metaKeyGitlabId, strconv.Itoa(id)) if err == nil { return i, nil } @@ -376,8 +375,8 @@ func (gi *gitlabImporter) ensurePerson(repo *cache.RepoCache, id int) (*cache.Id user.AvatarURL, map[string]string{ // because Gitlab - keyGitlabId: strconv.Itoa(id), - keyGitlabLogin: user.Username, + metaKeyGitlabId: strconv.Itoa(id), + metaKeyGitlabLogin: user.Username, }, ) if err != nil { diff --git a/bridge/gitlab/import_test.go b/bridge/gitlab/import_test.go index a6fd8524..8e596349 100644 --- a/bridge/gitlab/import_test.go +++ b/bridge/gitlab/import_test.go @@ -116,7 +116,7 @@ func TestImport(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - b, err := backend.ResolveBugCreateMetadata(keyGitlabUrl, tt.url) + b, err := backend.ResolveBugCreateMetadata(metaKeyGitlabUrl, tt.url) require.NoError(t, err) ops := b.Snapshot().Operations diff --git a/bridge/launchpad/config.go b/bridge/launchpad/config.go index 6669d0fa..be81c0ac 100644 --- a/bridge/launchpad/config.go +++ b/bridge/launchpad/config.go @@ -62,7 +62,7 @@ func (l *Launchpad) Configure(repo repository.RepoCommon, params core.BridgePara } conf[keyProject] = project - conf[core.KeyTarget] = target + conf[core.ConfigKeyTarget] = target err = l.ValidateConfig(conf) if err != nil { @@ -77,8 +77,8 @@ func (*Launchpad) ValidateConfig(conf core.Configuration) error { return fmt.Errorf("missing %s key", keyProject) } - if _, ok := conf[core.KeyTarget]; !ok { - return fmt.Errorf("missing %s key", core.KeyTarget) + if _, ok := conf[core.ConfigKeyTarget]; !ok { + return fmt.Errorf("missing %s key", core.ConfigKeyTarget) } return nil diff --git a/bridge/launchpad/import.go b/bridge/launchpad/import.go index 7f50d898..59fc5c5f 100644 --- a/bridge/launchpad/import.go +++ b/bridge/launchpad/import.go @@ -20,12 +20,14 @@ func (li *launchpadImporter) Init(conf core.Configuration) error { return nil } -const keyLaunchpadID = "launchpad-id" -const keyLaunchpadLogin = "launchpad-login" +const ( + metaKeyLaunchpadID = "launchpad-id" + metaKeyLaunchpadLogin = "launchpad-login" +) func (li *launchpadImporter) ensurePerson(repo *cache.RepoCache, owner LPPerson) (*cache.IdentityCache, error) { // Look first in the cache - i, err := repo.ResolveIdentityImmutableMetadata(keyLaunchpadLogin, owner.Login) + i, err := repo.ResolveIdentityImmutableMetadata(metaKeyLaunchpadLogin, owner.Login) if err == nil { return i, nil } @@ -39,7 +41,7 @@ func (li *launchpadImporter) ensurePerson(repo *cache.RepoCache, owner LPPerson) owner.Login, "", map[string]string{ - keyLaunchpadLogin: owner.Login, + metaKeyLaunchpadLogin: owner.Login, }, ) } @@ -65,7 +67,7 @@ func (li *launchpadImporter) ImportAll(ctx context.Context, repo *cache.RepoCach return default: lpBugID := fmt.Sprintf("%d", lpBug.ID) - b, err := repo.ResolveBugCreateMetadata(keyLaunchpadID, lpBugID) + b, err := repo.ResolveBugCreateMetadata(metaKeyLaunchpadID, lpBugID) if err != nil && err != bug.ErrBugNotExist { out <- core.NewImportError(err, entity.Id(lpBugID)) return @@ -86,7 +88,8 @@ func (li *launchpadImporter) ImportAll(ctx context.Context, repo *cache.RepoCach lpBug.Description, nil, map[string]string{ - keyLaunchpadID: lpBugID, + core.MetaKeyOrigin: target, + metaKeyLaunchpadID: lpBugID, }, ) if err != nil { @@ -100,15 +103,13 @@ func (li *launchpadImporter) ImportAll(ctx context.Context, repo *cache.RepoCach /* Handle messages */ if len(lpBug.Messages) == 0 { - err := fmt.Sprintf("bug doesn't have any comments") - out <- core.NewImportNothing(entity.Id(lpBugID), err) return } // The Launchpad API returns the bug description as the first // comment, so skip it. for _, lpMessage := range lpBug.Messages[1:] { - _, err := b.ResolveOperationWithMetadata(keyLaunchpadID, lpMessage.ID) + _, err := b.ResolveOperationWithMetadata(metaKeyLaunchpadID, lpMessage.ID) if err != nil && err != cache.ErrNoMatchingOp { out <- core.NewImportError(err, entity.Id(lpMessage.ID)) return @@ -136,7 +137,7 @@ func (li *launchpadImporter) ImportAll(ctx context.Context, repo *cache.RepoCach lpMessage.Content, nil, map[string]string{ - keyLaunchpadID: lpMessage.ID, + metaKeyLaunchpadID: lpMessage.ID, }) if err != nil { out <- core.NewImportError(err, op.Id()) @@ -146,8 +147,9 @@ func (li *launchpadImporter) ImportAll(ctx context.Context, repo *cache.RepoCach out <- core.NewImportComment(op.Id()) } - err = b.CommitAsNeeded() - if err != nil { + if !b.NeedCommit() { + out <- core.NewImportNothing(b.Id(), "no imported operation") + } else if err := b.Commit(); err != nil { out <- core.NewImportError(err, "") return } |