From 5ca326af83b90531d4d0c502bb1beabbe1b48c55 Mon Sep 17 00:00:00 2001 From: Amine Hilaly Date: Tue, 13 Aug 2019 19:51:14 +0200 Subject: bridge/core: add context.Context to ImportAll and ExportAll signatures bridge/core: add ImportResult objects to stream import events bridge/core: launchpad support asynchronous import bridge/github: cancellable export and import functions bridge/gitlab: cancellable export and import functions commands: bridge pull/push gracefull kill bridge/github: fix github import bridge/github: use simple context for imports bridge/core: name parameters in interfaces github/core: Add EventError to export and import events types bridge/gitlab: add context support in gitlab requests functions bridge/gitlab: remove imported events count from importer logic bridge/github: remove imported events count from importer logic bridge/github: add context support in query and muration requets bridge/github: fix bug duplicate editions after multiple calls bridge/core: import import and export events String methods bridge/gitlab: fix error handling in note import events commands/bridge: Add statistics about imports and exports bridge/gitlab: properly handle context cancellation bridge/github: improve error handling bridge: break iterators on context cancel or timeout bridge: add context timeout support bridge: improve event formating and error handling commands: handle interrupt and switch cases bridge/github: add export mutation timeouts bridge: fix race condition bug in the github and gitlab importers bridge/github: improve context error handling --- bridge/core/bridge.go | 15 +++--- bridge/core/export.go | 24 ++++++--- bridge/core/import.go | 128 ++++++++++++++++++++++++++++++++++++++++++++++ bridge/core/interfaces.go | 5 +- 4 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 bridge/core/import.go (limited to 'bridge/core') diff --git a/bridge/core/bridge.go b/bridge/core/bridge.go index 645dac3d..9161b418 100644 --- a/bridge/core/bridge.go +++ b/bridge/core/bridge.go @@ -2,6 +2,7 @@ package core import ( + "context" "fmt" "reflect" "regexp" @@ -289,26 +290,26 @@ func (b *Bridge) ensureInit() error { return nil } -func (b *Bridge) ImportAll(since time.Time) error { +func (b *Bridge) ImportAll(ctx context.Context, since time.Time) (<-chan ImportResult, error) { importer := b.getImporter() if importer == nil { - return ErrImportNotSupported + return nil, ErrImportNotSupported } err := b.ensureConfig() if err != nil { - return err + return nil, err } err = b.ensureInit() if err != nil { - return err + return nil, err } - return importer.ImportAll(b.repo, since) + return importer.ImportAll(ctx, b.repo, since) } -func (b *Bridge) ExportAll(since time.Time) (<-chan ExportResult, error) { +func (b *Bridge) ExportAll(ctx context.Context, since time.Time) (<-chan ExportResult, error) { exporter := b.getExporter() if exporter == nil { return nil, ErrExportNotSupported @@ -324,5 +325,5 @@ func (b *Bridge) ExportAll(since time.Time) (<-chan ExportResult, error) { return nil, err } - return exporter.ExportAll(b.repo, since) + return exporter.ExportAll(ctx, b.repo, since) } diff --git a/bridge/core/export.go b/bridge/core/export.go index 09566b62..55cf5a60 100644 --- a/bridge/core/export.go +++ b/bridge/core/export.go @@ -17,6 +17,7 @@ const ( ExportEventTitleEdition ExportEventLabelChange ExportEventNothing + ExportEventError ) // ExportResult is an event that is emitted during the export process, to @@ -32,19 +33,28 @@ type ExportResult struct { func (er ExportResult) String() string { switch er.Event { case ExportEventBug: - return "new issue" + return fmt.Sprintf("new issue: %s", er.ID) case ExportEventComment: - return "new comment" + return fmt.Sprintf("new comment: %s", er.ID) case ExportEventCommentEdition: - return "updated comment" + return fmt.Sprintf("updated comment: %s", er.ID) case ExportEventStatusChange: - return "changed status" + return fmt.Sprintf("changed status: %s", er.ID) case ExportEventTitleEdition: - return "changed title" + return fmt.Sprintf("changed title: %s", er.ID) case ExportEventLabelChange: - return "changed label" + return fmt.Sprintf("changed label: %s", er.ID) case ExportEventNothing: - return fmt.Sprintf("no event: %v", er.Reason) + if er.ID != "" { + return fmt.Sprintf("ignoring export event %s: %s", er.ID, er.Reason) + } + return fmt.Sprintf("ignoring export event: %s", er.Reason) + case ExportEventError: + if er.ID != "" { + return fmt.Sprintf("export error at %s: %s", er.ID, er.Err.Error()) + } + return fmt.Sprintf("export error: %s", er.Err.Error()) + default: panic("unknown export result") } diff --git a/bridge/core/import.go b/bridge/core/import.go new file mode 100644 index 00000000..0961e00b --- /dev/null +++ b/bridge/core/import.go @@ -0,0 +1,128 @@ +package core + +import ( + "fmt" + + "github.com/MichaelMure/git-bug/entity" +) + +type ImportEvent int + +const ( + _ ImportEvent = iota + ImportEventBug + ImportEventComment + ImportEventCommentEdition + ImportEventStatusChange + ImportEventTitleEdition + ImportEventLabelChange + ImportEventIdentity + ImportEventNothing + ImportEventError +) + +// ImportResult is an event that is emitted during the import process, to +// allow calling code to report on what is happening, collect metrics or +// display meaningful errors if something went wrong. +type ImportResult struct { + Err error + Event ImportEvent + ID entity.Id + Reason string +} + +func (er ImportResult) String() string { + switch er.Event { + case ImportEventBug: + return fmt.Sprintf("new issue: %s", er.ID) + case ImportEventComment: + return fmt.Sprintf("new comment: %s", er.ID) + case ImportEventCommentEdition: + return fmt.Sprintf("updated comment: %s", er.ID) + case ImportEventStatusChange: + return fmt.Sprintf("changed status: %s", er.ID) + case ImportEventTitleEdition: + return fmt.Sprintf("changed title: %s", er.ID) + case ImportEventLabelChange: + return fmt.Sprintf("changed label: %s", er.ID) + case ImportEventIdentity: + return fmt.Sprintf("new identity: %s", er.ID) + case ImportEventNothing: + if er.ID != "" { + return fmt.Sprintf("ignoring import event %s: %s", er.ID, er.Reason) + } + return fmt.Sprintf("ignoring event: %s", er.Reason) + case ImportEventError: + if er.ID != "" { + return fmt.Sprintf("import error at id %s: %s", er.ID, er.Err.Error()) + } + return fmt.Sprintf("import error: %s", er.Err.Error()) + default: + panic("unknown import result") + } +} + +func NewImportError(err error, id entity.Id) ImportResult { + return ImportResult{ + Err: err, + ID: id, + Event: ImportEventError, + } +} + +func NewImportNothing(id entity.Id, reason string) ImportResult { + return ImportResult{ + ID: id, + Reason: reason, + Event: ImportEventNothing, + } +} + +func NewImportBug(id entity.Id) ImportResult { + return ImportResult{ + ID: id, + Event: ImportEventBug, + } +} + +func NewImportComment(id entity.Id) ImportResult { + return ImportResult{ + ID: id, + Event: ImportEventComment, + } +} + +func NewImportCommentEdition(id entity.Id) ImportResult { + return ImportResult{ + ID: id, + Event: ImportEventCommentEdition, + } +} + +func NewImportStatusChange(id entity.Id) ImportResult { + return ImportResult{ + ID: id, + Event: ImportEventStatusChange, + } +} + +func NewImportLabelChange(id entity.Id) ImportResult { + return ImportResult{ + ID: id, + Event: ImportEventLabelChange, + } +} + +func NewImportTitleEdition(id entity.Id) ImportResult { + return ImportResult{ + ID: id, + Event: ImportEventTitleEdition, + } +} + +func NewImportIdentity(id entity.Id) ImportResult { + return ImportResult{ + ID: id, + Event: ImportEventIdentity, + } +} diff --git a/bridge/core/interfaces.go b/bridge/core/interfaces.go index 76d66fb4..047f3880 100644 --- a/bridge/core/interfaces.go +++ b/bridge/core/interfaces.go @@ -1,6 +1,7 @@ package core import ( + "context" "time" "github.com/MichaelMure/git-bug/cache" @@ -29,10 +30,10 @@ type BridgeImpl interface { type Importer interface { Init(conf Configuration) error - ImportAll(repo *cache.RepoCache, since time.Time) error + ImportAll(ctx context.Context, repo *cache.RepoCache, since time.Time) (<-chan ImportResult, error) } type Exporter interface { Init(conf Configuration) error - ExportAll(repo *cache.RepoCache, since time.Time) (<-chan ExportResult, error) + ExportAll(ctx context.Context, repo *cache.RepoCache, since time.Time) (<-chan ExportResult, error) } -- cgit