aboutsummaryrefslogtreecommitdiffstats
path: root/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'bridge')
-rw-r--r--bridge/bridges.go12
-rw-r--r--bridge/core/bridge.go6
-rw-r--r--bridge/core/export.go11
-rw-r--r--bridge/core/import.go14
-rw-r--r--bridge/core/token.go182
-rw-r--r--bridge/github/github.go4
-rw-r--r--bridge/github/import_query.go4
-rw-r--r--bridge/github/iterator.go101
-rw-r--r--bridge/gitlab/export_test.go5
-rw-r--r--bridge/gitlab/gitlab.go4
-rw-r--r--bridge/launchpad/launchpad.go4
11 files changed, 289 insertions, 58 deletions
diff --git a/bridge/bridges.go b/bridge/bridges.go
index dcb35af1..9bbf3941 100644
--- a/bridge/bridges.go
+++ b/bridge/bridges.go
@@ -3,13 +3,19 @@ package bridge
import (
"github.com/MichaelMure/git-bug/bridge/core"
- _ "github.com/MichaelMure/git-bug/bridge/github"
- _ "github.com/MichaelMure/git-bug/bridge/gitlab"
- _ "github.com/MichaelMure/git-bug/bridge/launchpad"
+ "github.com/MichaelMure/git-bug/bridge/github"
+ "github.com/MichaelMure/git-bug/bridge/gitlab"
+ "github.com/MichaelMure/git-bug/bridge/launchpad"
"github.com/MichaelMure/git-bug/cache"
"github.com/MichaelMure/git-bug/repository"
)
+func init() {
+ core.Register(&github.Github{})
+ core.Register(&gitlab.Gitlab{})
+ core.Register(&launchpad.Launchpad{})
+}
+
// Targets return all known bridge implementation target
func Targets() []string {
return core.Targets()
diff --git a/bridge/core/bridge.go b/bridge/core/bridge.go
index e90476eb..a3133b9c 100644
--- a/bridge/core/bridge.go
+++ b/bridge/core/bridge.go
@@ -71,6 +71,12 @@ func Targets() []string {
return result
}
+// TargetExist return true if the given target has a bridge implementation
+func TargetExist(target string) bool {
+ _, ok := bridgeImpl[target]
+ return ok
+}
+
// Instantiate a new Bridge for a repo, from the given target and name
func NewBridge(repo *cache.RepoCache, target string, name string) (*Bridge, error) {
implType, ok := bridgeImpl[target]
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/core/token.go b/bridge/core/token.go
new file mode 100644
index 00000000..2ceabca2
--- /dev/null
+++ b/bridge/core/token.go
@@ -0,0 +1,182 @@
+package core
+
+import (
+ "crypto/sha256"
+ "errors"
+ "fmt"
+ "regexp"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/MichaelMure/git-bug/entity"
+ "github.com/MichaelMure/git-bug/repository"
+)
+
+const (
+ tokenConfigKeyPrefix = "git-bug.token"
+ tokenValueKey = "value"
+ tokenTargetKey = "target"
+ tokenCreateTimeKey = "createtime"
+)
+
+var ErrTokenNotExist = errors.New("token doesn't exist")
+
+func NewErrMultipleMatchToken(matching []entity.Id) *entity.ErrMultipleMatch {
+ return entity.NewErrMultipleMatch("token", matching)
+}
+
+// Token holds an API access token data
+type Token struct {
+ Value string
+ Target string
+ CreateTime time.Time
+}
+
+// NewToken instantiate a new token
+func NewToken(value, target string) *Token {
+ return &Token{
+ Value: value,
+ Target: target,
+ CreateTime: time.Now(),
+ }
+}
+
+func (t *Token) ID() entity.Id {
+ sum := sha256.Sum256([]byte(t.Value))
+ return entity.Id(fmt.Sprintf("%x", sum))
+}
+
+// Validate ensure token important fields are valid
+func (t *Token) Validate() error {
+ if t.Value == "" {
+ return fmt.Errorf("missing value")
+ }
+ if t.Target == "" {
+ return fmt.Errorf("missing target")
+ }
+ if t.CreateTime.IsZero() || t.CreateTime.Equal(time.Time{}) {
+ return fmt.Errorf("missing creation time")
+ }
+ if !TargetExist(t.Target) {
+ return fmt.Errorf("unknown target")
+ }
+ return nil
+}
+
+// LoadToken loads a token from the repo config
+func LoadToken(repo repository.RepoCommon, id entity.Id) (*Token, error) {
+ keyPrefix := fmt.Sprintf("git-bug.token.%s.", id)
+
+ // read token config pairs
+ rawconfigs, err := repo.GlobalConfig().ReadAll(keyPrefix)
+ if err != nil {
+ // Not exactly right due to the limitation of ReadAll()
+ return nil, ErrTokenNotExist
+ }
+
+ // trim key prefix
+ configs := make(map[string]string)
+ for key, value := range rawconfigs {
+ newKey := strings.TrimPrefix(key, keyPrefix)
+ configs[newKey] = value
+ }
+
+ token := &Token{}
+
+ token.Value = configs[tokenValueKey]
+ token.Target = configs[tokenTargetKey]
+ if createTime, ok := configs[tokenCreateTimeKey]; ok {
+ if t, err := repository.ParseTimestamp(createTime); err == nil {
+ token.CreateTime = t
+ }
+ }
+
+ return token, nil
+}
+
+// LoadTokenPrefix load a token from the repo config with a prefix
+func LoadTokenPrefix(repo repository.RepoCommon, prefix string) (*Token, error) {
+ tokens, err := ListTokens(repo)
+ if err != nil {
+ return nil, err
+ }
+
+ // preallocate but empty
+ matching := make([]entity.Id, 0, 5)
+
+ for _, id := range tokens {
+ if id.HasPrefix(prefix) {
+ matching = append(matching, id)
+ }
+ }
+
+ if len(matching) > 1 {
+ return nil, NewErrMultipleMatchToken(matching)
+ }
+
+ if len(matching) == 0 {
+ return nil, ErrTokenNotExist
+ }
+
+ return LoadToken(repo, matching[0])
+}
+
+// ListTokens return a map representing the stored tokens in the repo config and global config
+// along with their type (global: true, local:false)
+func ListTokens(repo repository.RepoCommon) ([]entity.Id, error) {
+ configs, err := repo.GlobalConfig().ReadAll(tokenConfigKeyPrefix + ".")
+ if err != nil {
+ return nil, err
+ }
+
+ re, err := regexp.Compile(tokenConfigKeyPrefix + `.([^.]+)`)
+ if err != nil {
+ panic(err)
+ }
+
+ set := make(map[string]interface{})
+
+ for key := range configs {
+ res := re.FindStringSubmatch(key)
+
+ if res == nil {
+ continue
+ }
+
+ set[res[1]] = nil
+ }
+
+ result := make([]entity.Id, 0, len(set))
+ for key := range set {
+ result = append(result, entity.Id(key))
+ }
+
+ sort.Sort(entity.Alphabetical(result))
+
+ return result, nil
+}
+
+// StoreToken stores a token in the repo config
+func StoreToken(repo repository.RepoCommon, token *Token) error {
+ storeValueKey := fmt.Sprintf("git-bug.token.%s.%s", token.ID().String(), tokenValueKey)
+ err := repo.GlobalConfig().StoreString(storeValueKey, token.Value)
+ if err != nil {
+ return err
+ }
+
+ storeTargetKey := fmt.Sprintf("git-bug.token.%s.%s", token.ID().String(), tokenTargetKey)
+ err = repo.GlobalConfig().StoreString(storeTargetKey, token.Target)
+ if err != nil {
+ return err
+ }
+
+ createTimeKey := fmt.Sprintf("git-bug.token.%s.%s", token.ID().String(), tokenCreateTimeKey)
+ return repo.GlobalConfig().StoreTimestamp(createTimeKey, token.CreateTime)
+}
+
+// RemoveToken removes a token from the repo config
+func RemoveToken(repo repository.RepoCommon, id entity.Id) error {
+ keyPrefix := fmt.Sprintf("git-bug.token.%s", id)
+ return repo.GlobalConfig().RemoveAll(keyPrefix)
+}
diff --git a/bridge/github/github.go b/bridge/github/github.go
index 176bdd84..e4fb03dd 100644
--- a/bridge/github/github.go
+++ b/bridge/github/github.go
@@ -10,10 +10,6 @@ import (
"github.com/MichaelMure/git-bug/bridge/core"
)
-func init() {
- core.Register(&Github{})
-}
-
type Github struct{}
func (*Github) Target() string {
diff --git a/bridge/github/import_query.go b/bridge/github/import_query.go
index 62d3227b..f5cad299 100644
--- a/bridge/github/import_query.go
+++ b/bridge/github/import_query.go
@@ -102,13 +102,13 @@ type issueTimeline struct {
Body githubv4.String
Url githubv4.URI
- Timeline struct {
+ TimelineItems struct {
Edges []struct {
Cursor githubv4.String
Node timelineItem
}
PageInfo pageInfo
- } `graphql:"timeline(first: $timelineFirst, after: $timelineAfter)"`
+ } `graphql:"timelineItems(first: $timelineFirst, after: $timelineAfter)"`
UserContentEdits struct {
Nodes []userContentEdit
diff --git a/bridge/github/iterator.go b/bridge/github/iterator.go
index a97ed036..d1d7900f 100644
--- a/bridge/github/iterator.go
+++ b/bridge/github/iterator.go
@@ -138,9 +138,9 @@ func (i *iterator) initCommentEditQueryVariables() {
func (i *iterator) reverseTimelineEditNodes() {
node := i.timeline.query.Repository.Issues.Nodes[0]
reverseEdits(node.UserContentEdits.Nodes)
- for index, ce := range node.Timeline.Edges {
- if ce.Node.Typename == "IssueComment" && len(node.Timeline.Edges) != 0 {
- reverseEdits(node.Timeline.Edges[index].Node.IssueComment.UserContentEdits.Nodes)
+ for index, ce := range node.TimelineItems.Edges {
+ if ce.Node.Typename == "IssueComment" && len(node.TimelineItems.Edges) != 0 {
+ reverseEdits(node.TimelineItems.Edges[index].Node.IssueComment.UserContentEdits.Nodes)
}
}
}
@@ -159,7 +159,8 @@ func (i *iterator) queryIssue() bool {
return false
}
- if len(i.timeline.query.Repository.Issues.Nodes) == 0 {
+ issues := i.timeline.query.Repository.Issues.Nodes
+ if len(issues) == 0 {
return false
}
@@ -178,29 +179,35 @@ func (i *iterator) NextIssue() bool {
if i.timeline.variables["issueAfter"] == (*githubv4.String)(nil) {
nextIssue := i.queryIssue()
// prevent from infinite loop by setting a non nil cursor
- i.timeline.variables["issueAfter"] = i.timeline.query.Repository.Issues.PageInfo.EndCursor
+ issues := i.timeline.query.Repository.Issues
+ i.timeline.variables["issueAfter"] = issues.PageInfo.EndCursor
return nextIssue
}
- if !i.timeline.query.Repository.Issues.PageInfo.HasNextPage {
+ issues := i.timeline.query.Repository.Issues
+ if !issues.PageInfo.HasNextPage {
return false
}
// if we have more issues, query them
i.timeline.variables["timelineAfter"] = (*githubv4.String)(nil)
- i.timeline.variables["issueAfter"] = i.timeline.query.Repository.Issues.PageInfo.EndCursor
i.timeline.index = -1
+ timelineEndCursor := issues.Nodes[0].TimelineItems.PageInfo.EndCursor
// store cursor for future use
- i.timeline.lastEndCursor = i.timeline.query.Repository.Issues.Nodes[0].Timeline.PageInfo.EndCursor
+ i.timeline.lastEndCursor = timelineEndCursor
// query issue block
- return i.queryIssue()
+ nextIssue := i.queryIssue()
+ i.timeline.variables["issueAfter"] = issues.PageInfo.EndCursor
+
+ return nextIssue
}
// IssueValue return the actual issue value
func (i *iterator) IssueValue() issueTimeline {
- return i.timeline.query.Repository.Issues.Nodes[0]
+ issues := i.timeline.query.Repository.Issues
+ return issues.Nodes[0]
}
// NextTimelineItem return true if there is a next timeline item and increments the index by one.
@@ -214,23 +221,25 @@ func (i *iterator) NextTimelineItem() bool {
return false
}
- if len(i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges) == 0 {
+ timelineItems := i.timeline.query.Repository.Issues.Nodes[0].TimelineItems
+ // after NextIssue call it's good to check wether we have some timelineItems items or not
+ if len(timelineItems.Edges) == 0 {
return false
}
- if i.timeline.index < len(i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges)-1 {
+ if i.timeline.index < len(timelineItems.Edges)-1 {
i.timeline.index++
return true
}
- if !i.timeline.query.Repository.Issues.Nodes[0].Timeline.PageInfo.HasNextPage {
+ if !timelineItems.PageInfo.HasNextPage {
return false
}
- i.timeline.lastEndCursor = i.timeline.query.Repository.Issues.Nodes[0].Timeline.PageInfo.EndCursor
+ i.timeline.lastEndCursor = timelineItems.PageInfo.EndCursor
// more timelines, query them
- i.timeline.variables["timelineAfter"] = i.timeline.query.Repository.Issues.Nodes[0].Timeline.PageInfo.EndCursor
+ i.timeline.variables["timelineAfter"] = timelineItems.PageInfo.EndCursor
ctx, cancel := context.WithTimeout(i.ctx, defaultTimeout)
defer cancel()
@@ -240,6 +249,12 @@ func (i *iterator) NextTimelineItem() bool {
return false
}
+ timelineItems = i.timeline.query.Repository.Issues.Nodes[0].TimelineItems
+ // (in case github returns something weird) just for safety: better return a false than a panic
+ if len(timelineItems.Edges) == 0 {
+ return false
+ }
+
i.reverseTimelineEditNodes()
i.timeline.index = 0
return true
@@ -247,7 +262,8 @@ func (i *iterator) NextTimelineItem() bool {
// TimelineItemValue return the actual timeline item value
func (i *iterator) TimelineItemValue() timelineItem {
- return i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges[i.timeline.index].Node
+ timelineItems := i.timeline.query.Repository.Issues.Nodes[0].TimelineItems
+ return timelineItems.Edges[i.timeline.index].Node
}
func (i *iterator) queryIssueEdit() bool {
@@ -260,11 +276,12 @@ func (i *iterator) queryIssueEdit() bool {
return false
}
+ issueEdits := i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits
// reverse issue edits because github
- reverseEdits(i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits.Nodes)
+ reverseEdits(issueEdits.Nodes)
// this is not supposed to happen
- if len(i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits.Nodes) == 0 {
+ if len(issueEdits.Nodes) == 0 {
i.timeline.issueEdit.index = -1
return false
}
@@ -297,22 +314,24 @@ func (i *iterator) NextIssueEdit() bool {
// this mean we looped over all available issue edits in the timeline.
// now we have to use i.issueEditQuery
if i.timeline.issueEdit.index == -2 {
- if i.issueEdit.index < len(i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits.Nodes)-1 {
+ issueEdits := i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits
+ if i.issueEdit.index < len(issueEdits.Nodes)-1 {
i.issueEdit.index++
return i.nextValidIssueEdit()
}
- if !i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits.PageInfo.HasPreviousPage {
+ if !issueEdits.PageInfo.HasPreviousPage {
i.timeline.issueEdit.index = -1
i.issueEdit.index = -1
return false
}
// if there is more edits, query them
- i.issueEdit.variables["issueEditBefore"] = i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits.PageInfo.StartCursor
+ i.issueEdit.variables["issueEditBefore"] = issueEdits.PageInfo.StartCursor
return i.queryIssueEdit()
}
+ issueEdits := i.timeline.query.Repository.Issues.Nodes[0].UserContentEdits
// if there is no edit, the UserContentEdits given by github is empty. That
// means that the original message is given by the issue message.
//
@@ -323,24 +342,24 @@ func (i *iterator) NextIssueEdit() bool {
// the tricky part: for an issue older than the UserContentEdits API, github
// doesn't have the previous message version anymore and give an edition
// with .Diff == nil. We have to filter them.
- if len(i.timeline.query.Repository.Issues.Nodes[0].UserContentEdits.Nodes) == 0 {
+ if len(issueEdits.Nodes) == 0 {
return false
}
// loop over them timeline comment edits
- if i.timeline.issueEdit.index < len(i.timeline.query.Repository.Issues.Nodes[0].UserContentEdits.Nodes)-1 {
+ if i.timeline.issueEdit.index < len(issueEdits.Nodes)-1 {
i.timeline.issueEdit.index++
return i.nextValidIssueEdit()
}
- if !i.timeline.query.Repository.Issues.Nodes[0].UserContentEdits.PageInfo.HasPreviousPage {
+ if !issueEdits.PageInfo.HasPreviousPage {
i.timeline.issueEdit.index = -1
return false
}
// if there is more edits, query them
i.initIssueEditQueryVariables()
- i.issueEdit.variables["issueEditBefore"] = i.timeline.query.Repository.Issues.Nodes[0].UserContentEdits.PageInfo.StartCursor
+ i.issueEdit.variables["issueEditBefore"] = issueEdits.PageInfo.StartCursor
return i.queryIssueEdit()
}
@@ -348,11 +367,13 @@ func (i *iterator) NextIssueEdit() bool {
func (i *iterator) IssueEditValue() userContentEdit {
// if we are using issue edit query
if i.timeline.issueEdit.index == -2 {
- return i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits.Nodes[i.issueEdit.index]
+ issueEdits := i.issueEdit.query.Repository.Issues.Nodes[0].UserContentEdits
+ return issueEdits.Nodes[i.issueEdit.index]
}
+ issueEdits := i.timeline.query.Repository.Issues.Nodes[0].UserContentEdits
// else get it from timeline issue edit query
- return i.timeline.query.Repository.Issues.Nodes[0].UserContentEdits.Nodes[i.timeline.issueEdit.index]
+ return issueEdits.Nodes[i.timeline.issueEdit.index]
}
func (i *iterator) queryCommentEdit() bool {
@@ -364,13 +385,14 @@ func (i *iterator) queryCommentEdit() bool {
return false
}
+ commentEdits := i.commentEdit.query.Repository.Issues.Nodes[0].Timeline.Nodes[0].IssueComment.UserContentEdits
// this is not supposed to happen
- if len(i.commentEdit.query.Repository.Issues.Nodes[0].Timeline.Nodes[0].IssueComment.UserContentEdits.Nodes) == 0 {
+ if len(commentEdits.Nodes) == 0 {
i.timeline.commentEdit.index = -1
return false
}
- reverseEdits(i.commentEdit.query.Repository.Issues.Nodes[0].Timeline.Nodes[0].IssueComment.UserContentEdits.Nodes)
+ reverseEdits(commentEdits.Nodes)
i.commentEdit.index = 0
i.timeline.commentEdit.index = -2
@@ -398,35 +420,36 @@ func (i *iterator) NextCommentEdit() bool {
// same as NextIssueEdit
if i.timeline.commentEdit.index == -2 {
-
- if i.commentEdit.index < len(i.commentEdit.query.Repository.Issues.Nodes[0].Timeline.Nodes[0].IssueComment.UserContentEdits.Nodes)-1 {
+ commentEdits := i.commentEdit.query.Repository.Issues.Nodes[0].Timeline.Nodes[0].IssueComment.UserContentEdits
+ if i.commentEdit.index < len(commentEdits.Nodes)-1 {
i.commentEdit.index++
return i.nextValidCommentEdit()
}
- if !i.commentEdit.query.Repository.Issues.Nodes[0].Timeline.Nodes[0].IssueComment.UserContentEdits.PageInfo.HasPreviousPage {
+ if !commentEdits.PageInfo.HasPreviousPage {
i.timeline.commentEdit.index = -1
i.commentEdit.index = -1
return false
}
// if there is more comment edits, query them
- i.commentEdit.variables["commentEditBefore"] = i.commentEdit.query.Repository.Issues.Nodes[0].Timeline.Nodes[0].IssueComment.UserContentEdits.PageInfo.StartCursor
+ i.commentEdit.variables["commentEditBefore"] = commentEdits.PageInfo.StartCursor
return i.queryCommentEdit()
}
+ commentEdits := i.timeline.query.Repository.Issues.Nodes[0].TimelineItems.Edges[i.timeline.index].Node.IssueComment
// if there is no comment edits
- if len(i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges[i.timeline.index].Node.IssueComment.UserContentEdits.Nodes) == 0 {
+ if len(commentEdits.UserContentEdits.Nodes) == 0 {
return false
}
// loop over them timeline comment edits
- if i.timeline.commentEdit.index < len(i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges[i.timeline.index].Node.IssueComment.UserContentEdits.Nodes)-1 {
+ if i.timeline.commentEdit.index < len(commentEdits.UserContentEdits.Nodes)-1 {
i.timeline.commentEdit.index++
return i.nextValidCommentEdit()
}
- if !i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges[i.timeline.index].Node.IssueComment.UserContentEdits.PageInfo.HasPreviousPage {
+ if !commentEdits.UserContentEdits.PageInfo.HasPreviousPage {
i.timeline.commentEdit.index = -1
return false
}
@@ -435,10 +458,10 @@ func (i *iterator) NextCommentEdit() bool {
if i.timeline.index == 0 {
i.commentEdit.variables["timelineAfter"] = i.timeline.lastEndCursor
} else {
- i.commentEdit.variables["timelineAfter"] = i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges[i.timeline.index-1].Cursor
+ i.commentEdit.variables["timelineAfter"] = i.timeline.query.Repository.Issues.Nodes[0].TimelineItems.Edges[i.timeline.index-1].Cursor
}
- i.commentEdit.variables["commentEditBefore"] = i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges[i.timeline.index].Node.IssueComment.UserContentEdits.PageInfo.StartCursor
+ i.commentEdit.variables["commentEditBefore"] = commentEdits.UserContentEdits.PageInfo.StartCursor
return i.queryCommentEdit()
}
@@ -449,7 +472,7 @@ func (i *iterator) CommentEditValue() userContentEdit {
return i.commentEdit.query.Repository.Issues.Nodes[0].Timeline.Nodes[0].IssueComment.UserContentEdits.Nodes[i.commentEdit.index]
}
- return i.timeline.query.Repository.Issues.Nodes[0].Timeline.Edges[i.timeline.index].Node.IssueComment.UserContentEdits.Nodes[i.timeline.commentEdit.index]
+ return i.timeline.query.Repository.Issues.Nodes[0].TimelineItems.Edges[i.timeline.index].Node.IssueComment.UserContentEdits.Nodes[i.timeline.commentEdit.index]
}
func reverseEdits(edits []userContentEdit) {
diff --git a/bridge/gitlab/export_test.go b/bridge/gitlab/export_test.go
index 46c8c494..26b47bfb 100644
--- a/bridge/gitlab/export_test.go
+++ b/bridge/gitlab/export_test.go
@@ -284,8 +284,11 @@ func createRepository(ctx context.Context, name, token string) (int, error) {
},
gitlab.WithContext(ctx),
)
+ if err != nil {
+ return 0, err
+ }
- return project.ID, err
+ return project.ID, nil
}
// delete repository need a token with scope 'delete_repo'
diff --git a/bridge/gitlab/gitlab.go b/bridge/gitlab/gitlab.go
index 7e5c37cc..d976d813 100644
--- a/bridge/gitlab/gitlab.go
+++ b/bridge/gitlab/gitlab.go
@@ -23,10 +23,6 @@ const (
defaultTimeout = 60 * time.Second
)
-func init() {
- core.Register(&Gitlab{})
-}
-
type Gitlab struct{}
func (*Gitlab) Target() string {
diff --git a/bridge/launchpad/launchpad.go b/bridge/launchpad/launchpad.go
index 1fd9edc2..030d9169 100644
--- a/bridge/launchpad/launchpad.go
+++ b/bridge/launchpad/launchpad.go
@@ -5,10 +5,6 @@ import (
"github.com/MichaelMure/git-bug/bridge/core"
)
-func init() {
- core.Register(&Launchpad{})
-}
-
type Launchpad struct{}
func (*Launchpad) Target() string {