mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-15 02:01:43 +03:00
5ca326af83
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
272 lines
4.5 KiB
Go
272 lines
4.5 KiB
Go
package gitlab
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/xanzy/go-gitlab"
|
|
)
|
|
|
|
type issueIterator struct {
|
|
page int
|
|
index int
|
|
cache []*gitlab.Issue
|
|
}
|
|
|
|
type noteIterator struct {
|
|
page int
|
|
index int
|
|
cache []*gitlab.Note
|
|
}
|
|
|
|
type labelEventIterator struct {
|
|
page int
|
|
index int
|
|
cache []*gitlab.LabelEvent
|
|
}
|
|
|
|
type iterator struct {
|
|
// gitlab api v4 client
|
|
gc *gitlab.Client
|
|
|
|
// if since is given the iterator will query only the issues
|
|
// updated after this date
|
|
since time.Time
|
|
|
|
// project id
|
|
project string
|
|
|
|
// number of issues and notes to query at once
|
|
capacity int
|
|
|
|
// shared context
|
|
ctx context.Context
|
|
|
|
// sticky error
|
|
err error
|
|
|
|
// issues iterator
|
|
issue *issueIterator
|
|
|
|
// notes iterator
|
|
note *noteIterator
|
|
|
|
// labelEvent iterator
|
|
labelEvent *labelEventIterator
|
|
}
|
|
|
|
// NewIterator create a new iterator
|
|
func NewIterator(ctx context.Context, capacity int, projectID, token string, since time.Time) *iterator {
|
|
return &iterator{
|
|
gc: buildClient(token),
|
|
project: projectID,
|
|
since: since,
|
|
capacity: capacity,
|
|
ctx: ctx,
|
|
issue: &issueIterator{
|
|
index: -1,
|
|
page: 1,
|
|
},
|
|
note: ¬eIterator{
|
|
index: -1,
|
|
page: 1,
|
|
},
|
|
labelEvent: &labelEventIterator{
|
|
index: -1,
|
|
page: 1,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Error return last encountered error
|
|
func (i *iterator) Error() error {
|
|
return i.err
|
|
}
|
|
|
|
func (i *iterator) getNextIssues() bool {
|
|
ctx, cancel := context.WithTimeout(i.ctx, defaultTimeout)
|
|
defer cancel()
|
|
|
|
issues, _, err := i.gc.Issues.ListProjectIssues(
|
|
i.project,
|
|
&gitlab.ListProjectIssuesOptions{
|
|
ListOptions: gitlab.ListOptions{
|
|
Page: i.issue.page,
|
|
PerPage: i.capacity,
|
|
},
|
|
Scope: gitlab.String("all"),
|
|
UpdatedAfter: &i.since,
|
|
Sort: gitlab.String("asc"),
|
|
},
|
|
gitlab.WithContext(ctx),
|
|
)
|
|
|
|
if err != nil {
|
|
i.err = err
|
|
return false
|
|
}
|
|
|
|
// if repository doesn't have any issues
|
|
if len(issues) == 0 {
|
|
return false
|
|
}
|
|
|
|
i.issue.cache = issues
|
|
i.issue.index = 0
|
|
i.issue.page++
|
|
i.note.index = -1
|
|
i.note.cache = nil
|
|
|
|
return true
|
|
}
|
|
|
|
func (i *iterator) NextIssue() bool {
|
|
if i.err != nil {
|
|
return false
|
|
}
|
|
|
|
if i.ctx.Err() != nil {
|
|
return false
|
|
}
|
|
|
|
// first query
|
|
if i.issue.cache == nil {
|
|
return i.getNextIssues()
|
|
}
|
|
|
|
// move cursor index
|
|
if i.issue.index < len(i.issue.cache)-1 {
|
|
i.issue.index++
|
|
return true
|
|
}
|
|
|
|
return i.getNextIssues()
|
|
}
|
|
|
|
func (i *iterator) IssueValue() *gitlab.Issue {
|
|
return i.issue.cache[i.issue.index]
|
|
}
|
|
|
|
func (i *iterator) getNextNotes() bool {
|
|
ctx, cancel := context.WithTimeout(i.ctx, defaultTimeout)
|
|
defer cancel()
|
|
|
|
notes, _, err := i.gc.Notes.ListIssueNotes(
|
|
i.project,
|
|
i.IssueValue().IID,
|
|
&gitlab.ListIssueNotesOptions{
|
|
ListOptions: gitlab.ListOptions{
|
|
Page: i.note.page,
|
|
PerPage: i.capacity,
|
|
},
|
|
Sort: gitlab.String("asc"),
|
|
OrderBy: gitlab.String("created_at"),
|
|
},
|
|
gitlab.WithContext(ctx),
|
|
)
|
|
|
|
if err != nil {
|
|
i.err = err
|
|
return false
|
|
}
|
|
|
|
if len(notes) == 0 {
|
|
i.note.index = -1
|
|
i.note.page = 1
|
|
i.note.cache = nil
|
|
return false
|
|
}
|
|
|
|
i.note.cache = notes
|
|
i.note.page++
|
|
i.note.index = 0
|
|
return true
|
|
}
|
|
|
|
func (i *iterator) NextNote() bool {
|
|
if i.err != nil {
|
|
return false
|
|
}
|
|
|
|
if i.ctx.Err() != nil {
|
|
return false
|
|
}
|
|
|
|
if len(i.note.cache) == 0 {
|
|
return i.getNextNotes()
|
|
}
|
|
|
|
// move cursor index
|
|
if i.note.index < len(i.note.cache)-1 {
|
|
i.note.index++
|
|
return true
|
|
}
|
|
|
|
return i.getNextNotes()
|
|
}
|
|
|
|
func (i *iterator) NoteValue() *gitlab.Note {
|
|
return i.note.cache[i.note.index]
|
|
}
|
|
|
|
func (i *iterator) getNextLabelEvents() bool {
|
|
ctx, cancel := context.WithTimeout(i.ctx, defaultTimeout)
|
|
defer cancel()
|
|
|
|
labelEvents, _, err := i.gc.ResourceLabelEvents.ListIssueLabelEvents(
|
|
i.project,
|
|
i.IssueValue().IID,
|
|
&gitlab.ListLabelEventsOptions{
|
|
ListOptions: gitlab.ListOptions{
|
|
Page: i.labelEvent.page,
|
|
PerPage: i.capacity,
|
|
},
|
|
},
|
|
gitlab.WithContext(ctx),
|
|
)
|
|
|
|
if err != nil {
|
|
i.err = err
|
|
return false
|
|
}
|
|
|
|
if len(labelEvents) == 0 {
|
|
i.labelEvent.page = 1
|
|
i.labelEvent.index = -1
|
|
i.labelEvent.cache = nil
|
|
return false
|
|
}
|
|
|
|
i.labelEvent.cache = labelEvents
|
|
i.labelEvent.page++
|
|
i.labelEvent.index = 0
|
|
return true
|
|
}
|
|
|
|
// because Gitlab
|
|
func (i *iterator) NextLabelEvent() bool {
|
|
if i.err != nil {
|
|
return false
|
|
}
|
|
|
|
if i.ctx.Err() != nil {
|
|
return false
|
|
}
|
|
|
|
if len(i.labelEvent.cache) == 0 {
|
|
return i.getNextLabelEvents()
|
|
}
|
|
|
|
// move cursor index
|
|
if i.labelEvent.index < len(i.labelEvent.cache)-1 {
|
|
i.labelEvent.index++
|
|
return true
|
|
}
|
|
|
|
return i.getNextLabelEvents()
|
|
}
|
|
|
|
func (i *iterator) LabelEventValue() *gitlab.LabelEvent {
|
|
return i.labelEvent.cache[i.labelEvent.index]
|
|
}
|