aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--models/fixtures/foreign_reference.yml1
-rw-r--r--models/foreignreference/error.go43
-rw-r--r--models/foreignreference/foreignreference.go32
-rw-r--r--models/issue.go59
-rw-r--r--models/issue_test.go34
-rw-r--r--models/migrate.go7
-rw-r--r--models/migrate_test.go12
-rw-r--r--models/migrations/migrations.go2
-rw-r--r--models/migrations/v211.go26
-rw-r--r--modules/migration/comment.go7
-rw-r--r--modules/migration/downloader.go15
-rw-r--r--modules/migration/issue.go58
-rw-r--r--modules/migration/null_downloader.go11
-rw-r--r--modules/migration/pullrequest.go7
-rw-r--r--modules/migration/retry_downloader.go8
-rw-r--r--modules/migration/review.go6
-rw-r--r--services/migrations/codebase.go38
-rw-r--r--services/migrations/codebase_test.go6
-rw-r--r--services/migrations/gitbucket.go5
-rw-r--r--services/migrations/gitea_downloader.go54
-rw-r--r--services/migrations/gitea_downloader_test.go6
-rw-r--r--services/migrations/gitea_uploader.go8
-rw-r--r--services/migrations/github.go62
-rw-r--r--services/migrations/github_test.go12
-rw-r--r--services/migrations/gitlab.go72
-rw-r--r--services/migrations/gitlab_test.go24
-rw-r--r--services/migrations/gogs.go32
-rw-r--r--services/migrations/gogs_test.go4
-rw-r--r--services/migrations/migrate.go15
-rw-r--r--services/migrations/onedev.go68
-rw-r--r--services/migrations/onedev_test.go36
-rw-r--r--services/migrations/restore.go13
32 files changed, 451 insertions, 332 deletions
diff --git a/models/fixtures/foreign_reference.yml b/models/fixtures/foreign_reference.yml
new file mode 100644
index 0000000000..ca780a73aa
--- /dev/null
+++ b/models/fixtures/foreign_reference.yml
@@ -0,0 +1 @@
+[] # empty
diff --git a/models/foreignreference/error.go b/models/foreignreference/error.go
new file mode 100644
index 0000000000..d783a08730
--- /dev/null
+++ b/models/foreignreference/error.go
@@ -0,0 +1,43 @@
+// Copyright 2022 Gitea. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package foreignreference
+
+import (
+ "fmt"
+)
+
+// ErrLocalIndexNotExist represents a "LocalIndexNotExist" kind of error.
+type ErrLocalIndexNotExist struct {
+ RepoID int64
+ ForeignIndex int64
+ Type string
+}
+
+// ErrLocalIndexNotExist checks if an error is a ErrLocalIndexNotExist.
+func IsErrLocalIndexNotExist(err error) bool {
+ _, ok := err.(ErrLocalIndexNotExist)
+ return ok
+}
+
+func (err ErrLocalIndexNotExist) Error() string {
+ return fmt.Sprintf("repository %d has no LocalIndex for ForeignIndex %d of type %s", err.RepoID, err.ForeignIndex, err.Type)
+}
+
+// ErrForeignIndexNotExist represents a "ForeignIndexNotExist" kind of error.
+type ErrForeignIndexNotExist struct {
+ RepoID int64
+ LocalIndex int64
+ Type string
+}
+
+// ErrForeignIndexNotExist checks if an error is a ErrForeignIndexNotExist.
+func IsErrForeignIndexNotExist(err error) bool {
+ _, ok := err.(ErrForeignIndexNotExist)
+ return ok
+}
+
+func (err ErrForeignIndexNotExist) Error() string {
+ return fmt.Sprintf("repository %d has no ForeignIndex for LocalIndex %d of type %s", err.RepoID, err.LocalIndex, err.Type)
+}
diff --git a/models/foreignreference/foreignreference.go b/models/foreignreference/foreignreference.go
new file mode 100644
index 0000000000..cc657a0fbe
--- /dev/null
+++ b/models/foreignreference/foreignreference.go
@@ -0,0 +1,32 @@
+// Copyright 2022 Gitea. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package foreignreference
+
+import (
+ "code.gitea.io/gitea/models/db"
+)
+
+// Type* are valid values for the Type field of ForeignReference
+const (
+ TypeIssue = "issue"
+ TypePullRequest = "pull_request"
+ TypeComment = "comment"
+ TypeReview = "review"
+ TypeReviewComment = "review_comment"
+ TypeRelease = "release"
+)
+
+// ForeignReference represents external references
+type ForeignReference struct {
+ // RepoID is the first column in all indices. now we only need 2 indices: (repo, local) and (repo, foreign, type)
+ RepoID int64 `xorm:"UNIQUE(repo_foreign_type) INDEX(repo_local)" `
+ LocalIndex int64 `xorm:"INDEX(repo_local)"` // the resource key inside Gitea, it can be IssueIndex, or some model ID.
+ ForeignIndex string `xorm:"INDEX UNIQUE(repo_foreign_type)"`
+ Type string `xorm:"VARCHAR(16) INDEX UNIQUE(repo_foreign_type)"`
+}
+
+func init() {
+ db.RegisterModel(new(ForeignReference))
+}
diff --git a/models/issue.go b/models/issue.go
index fd59ac0a4b..ed94195ed1 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -15,6 +15,7 @@ import (
admin_model "code.gitea.io/gitea/models/admin"
"code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/foreignreference"
"code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
@@ -67,11 +68,12 @@ type Issue struct {
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
- Attachments []*repo_model.Attachment `xorm:"-"`
- Comments []*Comment `xorm:"-"`
- Reactions ReactionList `xorm:"-"`
- TotalTrackedTime int64 `xorm:"-"`
- Assignees []*user_model.User `xorm:"-"`
+ Attachments []*repo_model.Attachment `xorm:"-"`
+ Comments []*Comment `xorm:"-"`
+ Reactions ReactionList `xorm:"-"`
+ TotalTrackedTime int64 `xorm:"-"`
+ Assignees []*user_model.User `xorm:"-"`
+ ForeignReference *foreignreference.ForeignReference `xorm:"-"`
// IsLocked limits commenting abilities to users on an issue
// with write access
@@ -271,6 +273,29 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) {
return nil
}
+func (issue *Issue) loadForeignReference(ctx context.Context) (err error) {
+ if issue.ForeignReference != nil {
+ return nil
+ }
+ reference := &foreignreference.ForeignReference{
+ RepoID: issue.RepoID,
+ LocalIndex: issue.Index,
+ Type: foreignreference.TypeIssue,
+ }
+ has, err := db.GetEngine(ctx).Get(reference)
+ if err != nil {
+ return err
+ } else if !has {
+ return foreignreference.ErrForeignIndexNotExist{
+ RepoID: issue.RepoID,
+ LocalIndex: issue.Index,
+ Type: foreignreference.TypeIssue,
+ }
+ }
+ issue.ForeignReference = reference
+ return nil
+}
+
func (issue *Issue) loadMilestone(e db.Engine) (err error) {
if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
@@ -332,6 +357,10 @@ func (issue *Issue) loadAttributes(ctx context.Context) (err error) {
}
}
+ if err = issue.loadForeignReference(ctx); err != nil && !foreignreference.IsErrForeignIndexNotExist(err) {
+ return err
+ }
+
return issue.loadReactions(ctx)
}
@@ -1110,6 +1139,26 @@ func GetIssueByIndex(repoID, index int64) (*Issue, error) {
return issue, nil
}
+// GetIssueByForeignIndex returns raw issue by foreign ID
+func GetIssueByForeignIndex(ctx context.Context, repoID, foreignIndex int64) (*Issue, error) {
+ reference := &foreignreference.ForeignReference{
+ RepoID: repoID,
+ ForeignIndex: strconv.FormatInt(foreignIndex, 10),
+ Type: foreignreference.TypeIssue,
+ }
+ has, err := db.GetEngine(ctx).Get(reference)
+ if err != nil {
+ return nil, err
+ } else if !has {
+ return nil, foreignreference.ErrLocalIndexNotExist{
+ RepoID: repoID,
+ ForeignIndex: foreignIndex,
+ Type: foreignreference.TypeIssue,
+ }
+ }
+ return GetIssueByIndex(repoID, reference.LocalIndex)
+}
+
// GetIssueWithAttrsByIndex returns issue by index in a repository.
func GetIssueWithAttrsByIndex(repoID, index int64) (*Issue, error) {
issue, err := GetIssueByIndex(repoID, index)
diff --git a/models/issue_test.go b/models/issue_test.go
index 7cc0aa61b0..9afbce67c1 100644
--- a/models/issue_test.go
+++ b/models/issue_test.go
@@ -8,11 +8,13 @@ import (
"context"
"fmt"
"sort"
+ "strconv"
"sync"
"testing"
"time"
"code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/foreignreference"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -534,3 +536,35 @@ func TestCorrectIssueStats(t *testing.T) {
assert.NoError(t, err)
assert.EqualValues(t, issueStats.OpenCount, issueAmount)
}
+
+func TestIssueForeignReference(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+ issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 4}).(*Issue)
+ assert.NotEqualValues(t, issue.Index, issue.ID) // make sure they are different to avoid false positive
+
+ // it is fine for an issue to not have a foreign reference
+ err := issue.LoadAttributes()
+ assert.NoError(t, err)
+ assert.Nil(t, issue.ForeignReference)
+
+ var foreignIndex int64 = 12345
+ _, err = GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex)
+ assert.True(t, foreignreference.IsErrLocalIndexNotExist(err))
+
+ _, err = db.GetEngine(db.DefaultContext).Insert(&foreignreference.ForeignReference{
+ LocalIndex: issue.Index,
+ ForeignIndex: strconv.FormatInt(foreignIndex, 10),
+ RepoID: issue.RepoID,
+ Type: foreignreference.TypeIssue,
+ })
+ assert.NoError(t, err)
+
+ err = issue.LoadAttributes()
+ assert.NoError(t, err)
+
+ assert.EqualValues(t, issue.ForeignReference.ForeignIndex, strconv.FormatInt(foreignIndex, 10))
+
+ found, err := GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex)
+ assert.NoError(t, err)
+ assert.EqualValues(t, found.Index, issue.Index)
+}
diff --git a/models/migrate.go b/models/migrate.go
index bbfba1fa1e..2470fd4336 100644
--- a/models/migrate.go
+++ b/models/migrate.go
@@ -83,6 +83,13 @@ func insertIssue(ctx context.Context, issue *Issue) error {
}
}
+ if issue.ForeignReference != nil {
+ issue.ForeignReference.LocalIndex = issue.Index
+ if _, err := sess.Insert(issue.ForeignReference); err != nil {
+ return err
+ }
+ }
+
return nil
}
diff --git a/models/migrate_test.go b/models/migrate_test.go
index d85dcbfeef..f4af7ffe37 100644
--- a/models/migrate_test.go
+++ b/models/migrate_test.go
@@ -5,8 +5,10 @@
package models
import (
+ "strconv"
"testing"
+ "code.gitea.io/gitea/models/foreignreference"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -45,6 +47,7 @@ func assertCreateIssues(t *testing.T, isPull bool) {
UserID: owner.ID,
}
+ foreignIndex := int64(12345)
title := "issuetitle1"
is := &Issue{
RepoID: repo.ID,
@@ -58,11 +61,20 @@ func assertCreateIssues(t *testing.T, isPull bool) {
IsClosed: true,
Labels: []*Label{label},
Reactions: []*Reaction{reaction},
+ ForeignReference: &foreignreference.ForeignReference{
+ ForeignIndex: strconv.FormatInt(foreignIndex, 10),
+ RepoID: repo.ID,
+ Type: foreignreference.TypeIssue,
+ },
}
err := InsertIssues(is)
assert.NoError(t, err)
i := unittest.AssertExistsAndLoadBean(t, &Issue{Title: title}).(*Issue)
+ assert.Nil(t, i.ForeignReference)
+ err = i.LoadAttributes()
+ assert.NoError(t, err)
+ assert.EqualValues(t, strconv.FormatInt(foreignIndex, 10), i.ForeignReference.ForeignIndex)
unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: owner.ID, IssueID: i.ID})
}
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 31b172a68d..5ed358822b 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -373,6 +373,8 @@ var migrations = []Migration{
NewMigration("Increase WebAuthentication CredentialID size to 410 - NO-OPED", increaseCredentialIDTo410),
// v210 -> v211
NewMigration("v208 was completely broken - remigrate", remigrateU2FCredentials),
+ // v211 -> v212
+ NewMigration("Create ForeignReference table", createForeignReferenceTable),
}
// GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/v211.go b/models/migrations/v211.go
new file mode 100644
index 0000000000..26ccfd2037
--- /dev/null
+++ b/models/migrations/v211.go
@@ -0,0 +1,26 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+ "fmt"
+
+ "xorm.io/xorm"
+)
+
+func createForeignReferenceTable(x *xorm.Engine) error {
+ type ForeignReference struct {
+ // RepoID is the first column in all indices. now we only need 2 indices: (repo, local) and (repo, foreign, type)
+ RepoID int64 `xorm:"UNIQUE(repo_foreign_type) INDEX(repo_local)" `
+ LocalIndex int64 `xorm:"INDEX(repo_local)"` // the resource key inside Gitea, it can be IssueIndex, or some model ID.
+ ForeignIndex string `xorm:"INDEX UNIQUE(repo_foreign_type)"`
+ Type string `xorm:"VARCHAR(16) INDEX UNIQUE(repo_foreign_type)"`
+ }
+
+ if err := x.Sync2(new(ForeignReference)); err != nil {
+ return fmt.Errorf("Sync2: %v", err)
+ }
+ return nil
+}
diff --git a/modules/migration/comment.go b/modules/migration/comment.go
index f364ffc93a..0447689b74 100644
--- a/modules/migration/comment.go
+++ b/modules/migration/comment.go
@@ -7,6 +7,13 @@ package migration
import "time"
+// Commentable can be commented upon
+type Commentable interface {
+ GetLocalIndex() int64
+ GetForeignIndex() int64
+ GetContext() DownloaderContext
+}
+
// Comment is a standard comment information
type Comment struct {
IssueIndex int64 `yaml:"issue_index"`
diff --git a/modules/migration/downloader.go b/modules/migration/downloader.go
index 90e149fb1a..7759c96056 100644
--- a/modules/migration/downloader.go
+++ b/modules/migration/downloader.go
@@ -11,13 +11,6 @@ import (
"code.gitea.io/gitea/modules/structs"
)
-// GetCommentOptions represents an options for get comment
-type GetCommentOptions struct {
- Context IssueContext
- Page int
- PageSize int
-}
-
// Downloader downloads the site repo information
type Downloader interface {
SetContext(context.Context)
@@ -27,10 +20,11 @@ type Downloader interface {
GetReleases() ([]*Release, error)
GetLabels() ([]*Label, error)
GetIssues(page, perPage int) ([]*Issue, bool, error)
- GetComments(opts GetCommentOptions) ([]*Comment, bool, error)
+ GetComments(commentable Commentable) ([]*Comment, bool, error)
+ GetAllComments(page, perPage int) ([]*Comment, bool, error)
SupportGetRepoComments() bool
GetPullRequests(page, perPage int) ([]*PullRequest, bool, error)
- GetReviews(pullRequestContext IssueContext) ([]*Review, error)
+ GetReviews(reviewable Reviewable) ([]*Review, error)
FormatCloneURL(opts MigrateOptions, remoteAddr string) (string, error)
}
@@ -39,3 +33,6 @@ type DownloaderFactory interface {
New(ctx context.Context, opts MigrateOptions) (Downloader, error)
GitServiceType() structs.GitServiceType
}
+
+// DownloaderContext has opaque information only relevant to a given downloader
+type DownloaderContext interface{}
diff --git a/modules/migration/issue.go b/modules/migration/issue.go
index 984f07d8c9..78f648dd2d 100644
--- a/modules/migration/issue.go
+++ b/modules/migration/issue.go
@@ -7,44 +7,26 @@ package migration
import "time"
-// IssueContext is used to map between local and foreign issue/PR ids.
-type IssueContext interface {
- LocalID() int64
- ForeignID() int64
-}
-
-// BasicIssueContext is a 1:1 mapping between local and foreign ids.
-type BasicIssueContext int64
-
-// LocalID gets the local id.
-func (c BasicIssueContext) LocalID() int64 {
- return int64(c)
-}
-
-// ForeignID gets the foreign id.
-func (c BasicIssueContext) ForeignID() int64 {
- return int64(c)
-}
-
// Issue is a standard issue information
type Issue struct {
- Number int64 `json:"number"`
- PosterID int64 `yaml:"poster_id" json:"poster_id"`
- PosterName string `yaml:"poster_name" json:"poster_name"`
- PosterEmail string `yaml:"poster_email" json:"poster_email"`
- Title string `json:"title"`
- Content string `json:"content"`
- Ref string `json:"ref"`
- Milestone string `json:"milestone"`
- State string `json:"state"` // closed, open
- IsLocked bool `yaml:"is_locked" json:"is_locked"`
- Created time.Time `json:"created"`
- Updated time.Time `json:"updated"`
- Closed *time.Time `json:"closed"`
- Labels []*Label `json:"labels"`
- Reactions []*Reaction `json:"reactions"`
- Assignees []string `json:"assignees"`
- Context IssueContext `yaml:"-"`
+ Number int64 `json:"number"`
+ PosterID int64 `yaml:"poster_id" json:"poster_id"`
+ PosterName string `yaml:"poster_name" json:"poster_name"`
+ PosterEmail string `yaml:"poster_email" json:"poster_email"`
+ Title string `json:"title"`
+ Content string `json:"content"`
+ Ref string `json:"ref"`
+ Milestone string `json:"milestone"`
+ State string `json:"state"` // closed, open
+ IsLocked bool `yaml:"is_locked" json:"is_locked"`
+ Created time.Time `json:"created"`
+ Updated time.Time `json:"updated"`
+ Closed *time.Time `json:"closed"`
+ Labels []*Label `json:"labels"`
+ Reactions []*Reaction `json:"reactions"`
+ Assignees []string `json:"assignees"`
+ ForeignIndex int64 `json:"foreign_id"`
+ Context DownloaderContext `yaml:"-"`
}
// GetExternalName ExternalUserMigrated interface
@@ -52,3 +34,7 @@ func (i *Issue) GetExternalName() string { return i.PosterName }
// GetExternalID ExternalUserMigrated interface
func (i *Issue) GetExternalID() int64 { return i.PosterID }
+
+func (i *Issue) GetLocalIndex() int64 { return i.Number }
+func (i *Issue) GetForeignIndex() int64 { return i.ForeignIndex }
+func (i *Issue) GetContext() DownloaderContext { return i.Context }
diff --git a/modules/migration/null_downloader.go b/modules/migration/null_downloader.go
index 6192870873..32da720f16 100644
--- a/modules/migration/null_downloader.go
+++ b/modules/migration/null_downloader.go
@@ -47,18 +47,23 @@ func (n NullDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) {
return nil, false, &ErrNotSupported{Entity: "Issues"}
}
-// GetComments returns comments according the options
-func (n NullDownloader) GetComments(GetCommentOptions) ([]*Comment, bool, error) {
+// GetComments returns comments of an issue or PR
+func (n NullDownloader) GetComments(commentable Commentable) ([]*Comment, bool, error) {
return nil, false, &ErrNotSupported{Entity: "Comments"}
}
+// GetAllComments returns paginated comments
+func (n NullDownloader) GetAllComments(page, perPage int) ([]*Comment, bool, error) {
+ return nil, false, &ErrNotSupported{Entity: "AllComments"}
+}
+
// GetPullRequests returns pull requests according page and perPage
func (n NullDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bool, error) {
return nil, false, &ErrNotSupported{Entity: "PullRequests"}
}
// GetReviews returns pull requests review
-func (n NullDownloader) GetReviews(pullRequestContext IssueContext) ([]*Review, error) {
+func (n NullDownloader) GetReviews(reviewable Reviewable) ([]*Review, error) {
return nil, &ErrNotSupported{Entity: "Reviews"}
}
diff --git a/modules/migration/pullrequest.go b/modules/migration/pullrequest.go
index 7a681940a7..eaa0dd45e2 100644
--- a/modules/migration/pullrequest.go
+++ b/modules/migration/pullrequest.go
@@ -35,9 +35,14 @@ type PullRequest struct {
Assignees []string
IsLocked bool `yaml:"is_locked"`
Reactions []*Reaction
- Context IssueContext `yaml:"-"`
+ ForeignIndex int64
+ Context DownloaderContext `yaml:"-"`
}
+func (p *PullRequest) GetLocalIndex() int64 { return p.Number }
+func (p *PullRequest) GetForeignIndex() int64 { return p.ForeignIndex }
+func (p *PullRequest) GetContext() DownloaderContext { return p.Context }
+
// IsForkPullRequest returns true if the pull request from a forked repository but not the same repository
func (p *PullRequest) IsForkPullRequest() bool {
return p.Head.RepoPath() != p.Base.RepoPath()
diff --git a/modules/migration/retry_downloader.go b/modules/migration/retry_downloader.go
index 1095a26891..2e40c102be 100644
--- a/modules/migration/retry_downloader.go
+++ b/modules/migration/retry_downloader.go
@@ -148,7 +148,7 @@ func (d *RetryDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) {
}
// GetComments returns a repository's comments with retry
-func (d *RetryDownloader) GetComments(opts GetCommentOptions) ([]*Comment, bool, error) {
+func (d *RetryDownloader) GetComments(commentable Commentable) ([]*Comment, bool, error) {
var (
comments []*Comment
isEnd bool
@@ -156,7 +156,7 @@ func (d *RetryDownloader) GetComments(opts GetCommentOptions) ([]*Comment, bool,
)
err = d.retry(func() error {
- comments, isEnd, err = d.Downloader.GetComments(opts)
+ comments, isEnd, err = d.Downloader.GetComments(commentable)
return err
})
@@ -180,14 +180,14 @@ func (d *RetryDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bo
}
// GetReviews returns pull requests reviews
-func (d *RetryDownloader) GetReviews(pullRequestContext IssueContext) ([]*Review, error) {
+func (d *RetryDownloader) GetReviews(reviewable Reviewable) ([]*Review, error) {
var (
reviews []*Review
err error
)
err = d.retry(func() error {
- reviews, err = d.Downloader.GetReviews(pullRequestContext)
+ reviews, err = d.Downloader.GetReviews(reviewable)
return err
})
diff --git a/modules/migration/review.go b/modules/migration/review.go
index 85795385e9..e4db33d98f 100644
--- a/modules/migration/review.go
+++ b/modules/migration/review.go
@@ -6,6 +6,12 @@ package migration
import "time"
+// Reviewable can be reviewed
+type Reviewable interface {
+ GetLocalIndex() int64
+ GetForeignIndex() int64
+}
+
// enumerate all review states
const (
ReviewStatePending = "PENDING"
diff --git a/services/migrations/codebase.go b/services/migrations/codebase.go
index be0b5d4004..bb74c0a49d 100644
--- a/services/migrations/codebase.go
+++ b/services/migrations/codebase.go
@@ -266,17 +266,7 @@ func (d *CodebaseDownloader) GetLabels() ([]*base.Label, error) {
}
type codebaseIssueContext struct {
- foreignID int64
- localID int64
- Comments []*base.Comment
-}
-
-func (c codebaseIssueContext) LocalID() int64 {
- return c.localID
-}
-
-func (c codebaseIssueContext) ForeignID() int64 {
- return c.foreignID
+ Comments []*base.Comment
}
// GetIssues returns issues, limits are not supported
@@ -402,10 +392,9 @@ func (d *CodebaseDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool,
Labels: []*base.Label{
{Name: issue.Type.Name},
},
+ ForeignIndex: issue.TicketID.Value,
Context: codebaseIssueContext{
- foreignID: issue.TicketID.Value,
- localID: issue.TicketID.Value,
- Comments: comments[1:],
+ Comments: comments[1:],
},
})
@@ -418,10 +407,10 @@ func (d *CodebaseDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool,
}
// GetComments returns comments
-func (d *CodebaseDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Comment, bool, error) {
- context, ok := opts.Context.(codebaseIssueContext)
+func (d *CodebaseDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) {
+ context, ok := commentable.GetContext().(codebaseIssueContext)
if !ok {
- return nil, false, fmt.Errorf("unexpected comment context: %+v", opts.Context)
+ return nil, false, fmt.Errorf("unexpected context: %+v", commentable.GetContext())
}
return context.Comments, true, nil
@@ -570,10 +559,9 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq
SHA: d.getHeadCommit(rawMergeRequest.TargetRef),
RepoName: d.repoName,
},
+ ForeignIndex: rawMergeRequest.ID.Value,
Context: codebaseIssueContext{
- foreignID: rawMergeRequest.ID.Value,
- localID: number,
- Comments: comments[1:],
+ Comments: comments[1:],
},
})
}
@@ -581,16 +569,6 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq
return pullRequests, true, nil
}
-// GetReviews returns pull requests reviews
-func (d *CodebaseDownloader) GetReviews(context base.IssueContext) ([]*base.Review, error) {
- return []*base.Review{}, nil
-}
-
-// GetTopics return repository topics
-func (d *CodebaseDownloader) GetTopics() ([]string, error) {
- return []string{}, nil
-}
-
func (d *CodebaseDownloader) tryGetUser(userID int64) *codebaseUser {
if len(d.userMap) == 0 {
var rawUsers struct {
diff --git a/services/migrations/codebase_test.go b/services/migrations/codebase_test.go
index ef39b9f146..cb70a2bf75 100644
--- a/services/migrations/codebase_test.go
+++ b/services/migrations/codebase_test.go
@@ -108,9 +108,7 @@ func TestCodebaseDownloadRepo(t *testing.T) {
},
}, issues)
- comments, _, err := downloader.GetComments(base.GetCommentOptions{
- Context: issues[0].Context,
- })
+ comments, _, err := downloader.GetComments(issues[0])
assert.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
@@ -148,7 +146,7 @@ func TestCodebaseDownloadRepo(t *testing.T) {
},
}, prs)
- rvs, err := downloader.GetReviews(prs[0].Context)
+ rvs, err := downloader.GetReviews(prs[0])
assert.NoError(t, err)
assert.Empty(t, rvs)
}
diff --git a/services/migrations/gitbucket.go b/services/migrations/gitbucket.go
index c4fb0df93a..92b6cac738 100644
--- a/services/migrations/gitbucket.go
+++ b/services/migrations/gitbucket.go
@@ -64,8 +64,3 @@ func NewGitBucketDownloader(ctx context.Context, baseURL, userName, password, to
func (g *GitBucketDownloader) SupportGetRepoComments() bool {
return false
}
-
-// GetReviews is not supported
-func (g *GitBucketDownloader) GetReviews(context base.IssueContext) ([]*base.Review, error) {
- return nil, &base.ErrNotSupported{Entity: "Reviews"}
-}
diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go
index be3c6c1202..3c02e112ca 100644
--- a/services/migrations/gitea_downloader.go
+++ b/services/migrations/gitea_downloader.go
@@ -415,22 +415,22 @@ func (g *GiteaDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, err
}
allIssues = append(allIssues, &base.Issue{
- Title: issue.Title,
- Number: issue.Index,
- PosterID: issue.Poster.ID,
- PosterName: issue.Poster.UserName,
- PosterEmail: issue.Poster.Email,
- Content: issue.Body,
- Milestone: milestone,
- State: string(issue.State),
- Created: issue.Created,
- Updated: issue.Updated,
- Closed: issue.Closed,
- Reactions: reactions,
- Labels: labels,
- Assignees: assignees,
- IsLocked: issue.IsLocked,
- Context: base.BasicIssueContext(issue.Index),
+ Title: issue.Title,
+ Number: issue.Index,
+ PosterID: issue.Poster.ID,
+ PosterName: issue.Poster.UserName,
+ PosterEmail: issue.Poster.Email,
+ Content: issue.Body,
+ Milestone: milestone,
+ State: string(issue.State),
+ Created: issue.Created,
+ Updated: issue.Updated,
+ Closed: issue.Closed,
+ Reactions: reactions,
+ Labels: labels,
+ Assignees: assignees,
+ IsLocked: issue.IsLocked,
+ ForeignIndex: issue.Index,
})
}
@@ -442,7 +442,7 @@ func (g *GiteaDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, err
}
// GetComments returns comments according issueNumber
-func (g *GiteaDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Comment, bool, error) {
+func (g *GiteaDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) {
allComments := make([]*base.Comment, 0, g.maxPerPage)
for i := 1; ; i++ {
@@ -453,26 +453,26 @@ func (g *GiteaDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Comm
default:
}
- comments, _, err := g.client.ListIssueComments(g.repoOwner, g.repoName, opts.Context.ForeignID(), gitea_sdk.ListIssueCommentOptions{ListOptions: gitea_sdk.ListOptions{
+ comments, _, err := g.client.ListIssueComments(g.repoOwner, g.repoName, commentable.GetForeignIndex(), gitea_sdk.ListIssueCommentOptions{ListOptions: gitea_sdk.ListOptions{
PageSize: g.maxPerPage,
Page: i,
}})
if err != nil {
- return nil, false, fmt.Errorf("error while listing comments for issue #%d. Error: %v", opts.Context.ForeignID(), err)
+ return nil, false, fmt.Errorf("error while listing comments for issue #%d. Error: %v", commentable.GetForeignIndex(), err)
}
for _, comment := range comments {
reactions, err := g.getCommentReactions(comment.ID)
if err != nil {
- log.Warn("Unable to load comment reactions during migrating issue #%d for comment %d to %s/%s. Error: %v", opts.Context.ForeignID(), comment.ID, g.repoOwner, g.repoName, err)
+ log.Warn("Unable to load comment reactions during migrating issue #%d for comment %d to %s/%s. Error: %v", commentable.GetForeignIndex(), comment.ID, g.repoOwner, g.repoName, err)
if err2 := admin_model.CreateRepositoryNotice(
- fmt.Sprintf("Unable to load reactions during migrating issue #%d for comment %d to %s/%s. Error: %v", opts.Context.ForeignID(), comment.ID, g.repoOwner, g.repoName, err)); err2 != nil {
+ fmt.Sprintf("Unable to load reactions during migrating issue #%d for comment %d to %s/%s. Error: %v", commentable.GetForeignIndex(), comment.ID, g.repoOwner, g.repoName, err)); err2 != nil {
log.Error("create repository notice failed: ", err2)
}
}
allComments = append(allComments, &base.Comment{
- IssueIndex: opts.Context.LocalID(),
+ IssueIndex: commentable.GetLocalIndex(),
Index: comment.ID,
PosterID: comment.Poster.ID,
PosterName: comment.Poster.UserName,
@@ -602,7 +602,7 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques
RepoName: g.repoName,
OwnerName: g.repoOwner,
},
- Context: base.BasicIssueContext(pr.Index),
+ ForeignIndex: pr.Index,
})
}
@@ -614,7 +614,7 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques
}
// GetReviews returns pull requests review
-func (g *GiteaDownloader) GetReviews(context base.IssueContext) ([]*base.Review, error) {
+func (g *GiteaDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) {
if err := g.client.CheckServerVersionConstraint(">=1.12"); err != nil {
log.Info("GiteaDownloader: instance to old, skip GetReviews")
return nil, nil
@@ -630,7 +630,7 @@ func (g *GiteaDownloader) GetReviews(context base.IssueContext) ([]*base.Review,
default:
}
- prl, _, err := g.client.ListPullReviews(g.repoOwner, g.repoName, context.ForeignID(), gitea_sdk.ListPullReviewsOptions{ListOptions: gitea_sdk.ListOptions{
+ prl, _, err := g.client.ListPullReviews(g.repoOwner, g.repoName, reviewable.GetForeignIndex(), gitea_sdk.ListPullReviewsOptions{ListOptions: gitea_sdk.ListOptions{
Page: i,
PageSize: g.maxPerPage,
}})
@@ -640,7 +640,7 @@ func (g *GiteaDownloader) GetReviews(context base.IssueContext) ([]*base.Review,
for _, pr := range prl {
- rcl, _, err := g.client.ListPullReviewComments(g.repoOwner, g.repoName, context.ForeignID(), pr.ID)
+ rcl, _, err := g.client.ListPullReviewComments(g.repoOwner, g.repoName, reviewable.GetForeignIndex(), pr.ID)
if err != nil {
return nil, err
}
@@ -666,7 +666,7 @@ func (g *GiteaDownloader) GetReviews(context base.IssueContext) ([]*base.Review,
allReviews = append(allReviews, &base.Review{
ID: pr.ID,
- IssueIndex: context.LocalID(),
+ IssueIndex: reviewable.GetLocalIndex(),
ReviewerID: pr.Reviewer.ID,
ReviewerName: pr.Reviewer.UserName,
Official: pr.Official,
diff --git a/services/migrations/gitea_downloader_test.go b/services/migrations/gitea_downloader_test.go
index 2c70dc4213..dc6903e854 100644
--- a/services/migrations/gitea_downloader_test.go
+++ b/services/migrations/gitea_downloader_test.go
@@ -198,9 +198,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
},
}, issues)
- comments, _, err := downloader.GetComments(base.GetCommentOptions{
- Context: base.BasicIssueContext(4),
- })
+ comments, _, err := downloader.GetComments(&base.Issue{Number: 4, ForeignIndex: 4})
assert.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
@@ -265,7 +263,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
PatchURL: "https://gitea.com/gitea/test_repo/pulls/12.patch",
}, prs[1])
- reviews, err := downloader.GetReviews(base.BasicIssueContext(7))
+ reviews, err := downloader.GetReviews(&base.Issue{Number: 7, ForeignIndex: 7})
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go
index 21c2dc8f8e..2faa0a1f2a 100644
--- a/services/migrations/gitea_uploader.go
+++ b/services/migrations/gitea_uploader.go
@@ -11,11 +11,13 @@ import (
"io"
"os"
"path/filepath"
+ "strconv"
"strings"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/foreignreference"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
@@ -373,6 +375,12 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
Labels: labels,
CreatedUnix: timeutil.TimeStamp(issue.Created.Unix()),
UpdatedUnix: timeutil.TimeStamp(issue.Updated.Unix()),
+ ForeignReference: &foreignreference.ForeignReference{
+ LocalIndex: issue.GetLocalIndex(),
+ ForeignIndex: strconv.FormatInt(issue.GetForeignIndex(), 10),
+ RepoID: g.repo.ID,
+ Type: foreignreference.TypeIssue,
+ },
}
if err := g.remapUser(issue, &is); err != nil {
diff --git a/services/migrations/github.go b/services/migrations/github.go
index f86ba94393..faf0cf0794 100644
--- a/services/migrations/github.go
+++ b/services/migrations/github.go
@@ -446,22 +446,22 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool,
}
allIssues = append(allIssues, &base.Issue{
- Title: *issue.Title,
- Number: int64(*issue.Number),
- PosterID: issue.GetUser().GetID(),
- PosterName: issue.GetUser().GetLogin(),
- PosterEmail: issue.GetUser().GetEmail(),
- Content: issue.GetBody(),
- Milestone: issue.GetMilestone().GetTitle(),
- State: issue.GetState(),
- Created: issue.GetCreatedAt(),
- Updated: issue.GetUpdatedAt(),
- Labels: labels,
- Reactions: reactions,
- Closed: issue.ClosedAt,
- IsLocked: issue.GetLocked(),
- Assignees: assignees,
- Context: base.BasicIssueContext(*issue.Number),
+ Title: *issue.Title,
+ Number: int64(*issue.Number),
+ PosterID: issue.GetUser().GetID(),
+ PosterName: issue.GetUser().GetLogin(),
+ PosterEmail: issue.GetUser().GetEmail(),
+ Content: issue.GetBody(),
+ Milestone: issue.GetMilestone().GetTitle(),
+ State: issue.GetState(),
+ Created: issue.GetCreatedAt(),
+ Updated: issue.GetUpdatedAt(),
+ Labels: labels,
+ Reactions: reactions,
+ Closed: issue.ClosedAt,
+ IsLocked: issue.GetLocked(),
+ Assignees: assignees,
+ ForeignIndex: int64(*issue.Number),
})
}
@@ -474,16 +474,12 @@ func (g *GithubDownloaderV3) SupportGetRepoComments() bool {
}
// GetComments returns comments according issueNumber
-func (g *GithubDownloaderV3) GetComments(opts base.GetCommentOptions) ([]*base.Comment, bool, error) {
- if opts.Context != nil {
- comments, err := g.getComments(opts.Context)
- return comments, false, err
- }
-
- return g.GetAllComments(opts.Page, opts.PageSize)
+func (g *GithubDownloaderV3) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) {
+ comments, err := g.getComments(commentable)
+ return comments, false, err
}
-func (g *GithubDownloaderV3) getComments(issueContext base.IssueContext) ([]*base.Comment, error) {
+func (g *GithubDownloaderV3) getComments(commentable base.Commentable) ([]*base.Comment, error) {
var (
allComments = make([]*base.Comment, 0, g.maxPerPage)
created = "created"
@@ -498,7 +494,7 @@ func (g *GithubDownloaderV3) getComments(issueContext base.IssueContext) ([]*bas
}
for {
g.waitAndPickClient()
- comments, resp, err := g.getClient().Issues.ListComments(g.ctx, g.repoOwner, g.repoName, int(issueContext.ForeignID()), opt)
+ comments, resp, err := g.getClient().Issues.ListComments(g.ctx, g.repoOwner, g.repoName, int(commentable.GetForeignIndex()), opt)
if err != nil {
return nil, fmt.Errorf("error while listing repos: %v", err)
}
@@ -531,7 +527,7 @@ func (g *GithubDownloaderV3) getComments(issueContext base.IssueContext) ([]*bas
}
allComments = append(allComments, &base.Comment{
- IssueIndex: issueContext.LocalID(),
+ IssueIndex: commentable.GetLocalIndex(),
Index: comment.GetID(),
PosterID: comment.GetUser().GetID(),
PosterName: comment.GetUser().GetLogin(),
@@ -709,9 +705,9 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq
RepoName: pr.GetBase().GetRepo().GetName(),
OwnerName: pr.GetBase().GetUser().GetLogin(),
},
- PatchURL: pr.GetPatchURL(),
- Reactions: reactions,
- Context: base.BasicIssueContext(*pr.Number),
+ PatchURL: pr.GetPatchURL(),
+ Reactions: reactions,
+ ForeignIndex: int64(*pr.Number),
})
}
@@ -777,28 +773,28 @@ func (g *GithubDownloaderV3) convertGithubReviewComments(cs []*github.PullReques
}
// GetReviews returns pull requests review
-func (g *GithubDownloaderV3) GetReviews(context base.IssueContext) ([]*base.Review, error) {
+func (g *GithubDownloaderV3) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) {
allReviews := make([]*base.Review, 0, g.maxPerPage)
opt := &github.ListOptions{
PerPage: g.maxPerPage,
}
for {
g.waitAndPickClient()
- reviews, resp, err := g.getClient().PullRequests.ListReviews(g.ctx, g.repoOwner, g.repoName, int(context.ForeignID()), opt)
+ reviews, resp, err := g.getClient().PullRequests.ListReviews(g.ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), opt)
if err != nil {
return nil, fmt.Errorf("error while listing repos: %v", err)
}
g.setRate(&resp.Rate)
for _, review := range reviews {
r := convertGithubReview(review)
- r.IssueIndex = context.LocalID()
+ r.IssueIndex = reviewable.GetLocalIndex()
// retrieve all review comments
opt2 := &github.ListOptions{
PerPage: g.maxPerPage,
}
for {
g.waitAndPickClient()
- reviewComments, resp, err := g.getClient().PullRequests.ListReviewComments(g.ctx, g.repoOwner, g.repoName, int(context.ForeignID()), review.GetID(), opt2)
+ reviewComments, resp, err := g.getClient().PullRequests.ListReviewComments(g.ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), review.GetID(), opt2)
if err != nil {
return nil, fmt.Errorf("error while listing repos: %v", err)
}
diff --git a/services/migrations/github_test.go b/services/migrations/github_test.go
index 7540037d92..90c1fcaef5 100644
--- a/services/migrations/github_test.go
+++ b/services/migrations/github_test.go
@@ -215,9 +215,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
}, issues)
// downloader.GetComments()
- comments, _, err := downloader.GetComments(base.GetCommentOptions{
- Context: base.BasicIssueContext(2),
- })
+ comments, _, err := downloader.GetComments(&base.Issue{Number: 2, ForeignIndex: 2})
assert.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
@@ -286,7 +284,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
Merged: true,
MergedTime: timePtr(time.Date(2019, 11, 12, 21, 39, 27, 0, time.UTC)),
MergeCommitSHA: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
- Context: base.BasicIssueContext(3),
+ ForeignIndex: 3,
},
{
Number: 4,
@@ -333,11 +331,11 @@ func TestGitHubDownloadRepo(t *testing.T) {
Content: "+1",
},
},
- Context: base.BasicIssueContext(4),
+ ForeignIndex: 4,
},
}, prs)
- reviews, err := downloader.GetReviews(base.BasicIssueContext(3))
+ reviews, err := downloader.GetReviews(&base.PullRequest{Number: 3, ForeignIndex: 3})
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
@@ -369,7 +367,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
},
}, reviews)
- reviews, err = downloader.GetReviews(base.BasicIssueContext(4))
+ reviews, err = downloader.GetReviews(&base.PullRequest{Number: 4, ForeignIndex: 4})
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go
index c05d081e9a..d3a034e27c 100644
--- a/services/migrations/gitlab.go
+++ b/services/migrations/gitlab.go
@@ -349,19 +349,9 @@ func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) {
}
type gitlabIssueContext struct {
- foreignID int64
- localID int64
IsMergeRequest bool
}
-func (c gitlabIssueContext) LocalID() int64 {
- return c.localID
-}
-
-func (c gitlabIssueContext) ForeignID() int64 {
- return c.foreignID
-}
-
// GetIssues returns issues according start and limit
// Note: issue label description and colors are not supported by the go-gitlab library at this time
func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) {
@@ -421,24 +411,21 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
}
allIssues = append(allIssues, &base.Issue{
- Title: issue.Title,
- Number: int64(issue.IID),
- PosterID: int64(issue.Author.ID),
- PosterName: issue.Author.Username,
- Content: issue.Description,
- Milestone: milestone,
- State: issue.State,
- Created: *issue.CreatedAt,
- Labels: labels,
- Reactions: reactions,
- Closed: issue.ClosedAt,
- IsLocked: issue.DiscussionLocked,
- Updated: *issue.UpdatedAt,
- Context: gitlabIssueContext{
- foreignID: int64(issue.IID),
- localID: int64(issue.IID),
- IsMergeRequest: false,
- },
+ Title: issue.Title,
+ Number: int64(issue.IID),
+ PosterID: int64(issue.Author.ID),
+ PosterName: issue.Author.Username,
+ Content: issue.Description,
+ Milestone: milestone,
+ State: issue.State,
+ Created: *issue.CreatedAt,
+ Labels: labels,
+ Reactions: reactions,
+ Closed: issue.ClosedAt,
+ IsLocked: issue.DiscussionLocked,
+ Updated: *issue.UpdatedAt,
+ ForeignIndex: int64(issue.IID),
+ Context: gitlabIssueContext{IsMergeRequest: false},
})
// increment issueCount, to be used in GetPullRequests()
@@ -450,10 +437,10 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
// GetComments returns comments according issueNumber
// TODO: figure out how to transfer comment reactions
-func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Comment, bool, error) {
- context, ok := opts.Context.(gitlabIssueContext)
+func (g *GitlabDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) {
+ context, ok := commentable.GetContext().(gitlabIssueContext)
if !ok {
- return nil, false, fmt.Errorf("unexpected context: %+v", opts.Context)
+ return nil, false, fmt.Errorf("unexpected context: %+v", commentable.GetContext())
}
allComments := make([]*base.Comment, 0, g.maxPerPage)
@@ -465,12 +452,12 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
var resp *gitlab.Response
var err error
if !context.IsMergeRequest {
- comments, resp, err = g.client.Discussions.ListIssueDiscussions(g.repoID, int(context.ForeignID()), &gitlab.ListIssueDiscussionsOptions{
+ comments, resp, err = g.client.Discussions.ListIssueDiscussions(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListIssueDiscussionsOptions{
Page: page,
PerPage: g.maxPerPage,
}, nil, gitlab.WithContext(g.ctx))
} else {
- comments, resp, err = g.client.Discussions.ListMergeRequestDiscussions(g.repoID, int(context.ForeignID()), &gitlab.ListMergeRequestDiscussionsOptions{
+ comments, resp, err = g.client.Discussions.ListMergeRequestDiscussions(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListMergeRequestDiscussionsOptions{
Page: page,
PerPage: g.maxPerPage,
}, nil, gitlab.WithContext(g.ctx))
@@ -484,7 +471,7 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
if !comment.IndividualNote {
for _, note := range comment.Notes {
allComments = append(allComments, &base.Comment{
- IssueIndex: context.LocalID(),
+ IssueIndex: commentable.GetLocalIndex(),
Index: int64(note.ID),
PosterID: int64(note.Author.ID),
PosterName: note.Author.Username,
@@ -496,7 +483,7 @@ func (g *GitlabDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
} else {
c := comment.Notes[0]
allComments = append(allComments, &base.Comment{
- IssueIndex: context.LocalID(),
+ IssueIndex: commentable.GetLocalIndex(),
Index: int64(c.ID),
PosterID: int64(c.Author.ID),
PosterName: c.Author.Username,
@@ -619,12 +606,9 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
RepoName: g.repoName,
OwnerName: pr.Author.Username,
},
- PatchURL: pr.WebURL + ".patch",
- Context: gitlabIssueContext{
- foreignID: int64(pr.IID),
- localID: newPRNumber,
- IsMergeRequest: true,
- },
+ PatchURL: pr.WebURL + ".patch",
+ ForeignIndex: int64(pr.IID),
+ Context: gitlabIssueContext{IsMergeRequest: true},
})
}
@@ -632,8 +616,8 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
}
// GetReviews returns pull requests review
-func (g *GitlabDownloader) GetReviews(context base.IssueContext) ([]*base.Review, error) {
- approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, int(context.ForeignID()), gitlab.WithContext(g.ctx))
+func (g *GitlabDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) {
+ approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, int(reviewable.GetForeignIndex()), gitlab.WithContext(g.ctx))
if err != nil {
if resp != nil && resp.StatusCode == 404 {
log.Error(fmt.Sprintf("GitlabDownloader: while migrating a error occurred: '%s'", err.Error()))
@@ -654,7 +638,7 @@ func (g *GitlabDownloader) GetReviews(context base.IssueContext) ([]*base.Review
reviews := make([]*base.Review, 0, len(approvals.ApprovedBy))
for _, user := range approvals.ApprovedBy {
reviews = append(reviews, &base.Review{
- IssueIndex: context.LocalID(),
+ IssueIndex: reviewable.GetLocalIndex(),
ReviewerID: int64(user.User.ID),
ReviewerName: user.User.Username,
CreatedAt: createdAt,
diff --git a/services/migrations/gitlab_test.go b/services/migrations/gitlab_test.go
index ad61577653..52edb2af8f 100644
--- a/services/migrations/gitlab_test.go
+++ b/services/migrations/gitlab_test.go
@@ -214,12 +214,10 @@ func TestGitlabDownloadRepo(t *testing.T) {
},
}, issues)
- comments, _, err := downloader.GetComments(base.GetCommentOptions{
- Context: gitlabIssueContext{
- foreignID: 2,
- localID: 2,
- IsMergeRequest: false,
- },
+ comments, _, err := downloader.GetComments(&base.Issue{
+ Number: 2,
+ ForeignIndex: 2,
+ Context: gitlabIssueContext{IsMergeRequest: false},
})
assert.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
@@ -301,15 +299,12 @@ func TestGitlabDownloadRepo(t *testing.T) {
Merged: false,
MergedTime: nil,
MergeCommitSHA: "",
- Context: gitlabIssueContext{
- foreignID: 2,
- localID: 4,
- IsMergeRequest: true,
- },
+ ForeignIndex: 2,
+ Context: gitlabIssueContext{IsMergeRequest: true},
},
}, prs)
- rvs, err := downloader.GetReviews(base.BasicIssueContext(1))
+ rvs, err := downloader.GetReviews(&base.PullRequest{Number: 1, ForeignIndex: 1})
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
@@ -328,7 +323,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
},
}, rvs)
- rvs, err = downloader.GetReviews(base.BasicIssueContext(2))
+ rvs, err = downloader.GetReviews(&base.PullRequest{Number: 2, ForeignIndex: 2})
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
@@ -469,7 +464,8 @@ func TestGitlabGetReviews(t *testing.T) {
mock, review := convertTestCase(testCase)
mux.HandleFunc(fmt.Sprintf("/api/v4/projects/%d/merge_requests/%d/approvals", testCase.repoID, testCase.prID), mock)
- rvs, err := downloader.GetReviews(base.BasicIssueContext(testCase.prID))
+ id := int64(testCase.prID)
+ rvs, err := downloader.GetReviews(&base.Issue{Number: id, ForeignIndex: id})
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{&review}, rvs)
}
diff --git a/services/migrations/gogs.go b/services/migrations/gogs.go
index 0ef39484b7..a28033218e 100644
--- a/services/migrations/gogs.go
+++ b/services/migrations/gogs.go
@@ -223,10 +223,10 @@ func (g *GogsDownloader) getIssues(page int, state string) ([]*base.Issue, bool,
}
// GetComments returns comments according issueNumber
-func (g *GogsDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Comment, bool, error) {
+func (g *GogsDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) {
allComments := make([]*base.Comment, 0, 100)
- comments, err := g.client.ListIssueComments(g.repoOwner, g.repoName, opts.Context.ForeignID())
+ comments, err := g.client.ListIssueComments(g.repoOwner, g.repoName, commentable.GetForeignIndex())
if err != nil {
return nil, false, fmt.Errorf("error while listing repos: %v", err)
}
@@ -235,7 +235,7 @@ func (g *GogsDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Comme
continue
}
allComments = append(allComments, &base.Comment{
- IssueIndex: opts.Context.LocalID(),
+ IssueIndex: commentable.GetLocalIndex(),
Index: comment.ID,
PosterID: comment.Poster.ID,
PosterName: comment.Poster.Login,
@@ -288,19 +288,19 @@ func convertGogsIssue(issue *gogs.Issue) *base.Issue {
}
return &base.Issue{
- Title: issue.Title,
- Number: issue.Index,
- PosterID: issue.Poster.ID,
- PosterName: issue.Poster.Login,
- PosterEmail: issue.Poster.Email,
- Content: issue.Body,
- Milestone: milestone,
- State: string(issue.State),
- Created: issue.Created,
- Updated: issue.Updated,
- Labels: labels,
- Closed: closed,
- Context: base.BasicIssueContext(issue.Index),
+ Title: issue.Title,
+ Number: issue.Index,
+ PosterID: issue.Poster.ID,
+ PosterName: issue.Poster.Login,
+ PosterEmail: issue.Poster.Email,
+ Content: issue.Body,
+ Milestone: milestone,
+ State: string(issue.State),
+ Created: issue.Created,
+ Updated: issue.Updated,
+ Labels: labels,
+ Closed: closed,
+ ForeignIndex: issue.Index,
}
}
diff --git a/services/migrations/gogs_test.go b/services/migrations/gogs_test.go
index f9d74d3be3..501161b610 100644
--- a/services/migrations/gogs_test.go
+++ b/services/migrations/gogs_test.go
@@ -111,9 +111,7 @@ func TestGogsDownloadRepo(t *testing.T) {
}, issues)
// downloader.GetComments()
- comments, _, err := downloader.GetComments(base.GetCommentOptions{
- Context: base.BasicIssueContext(1),
- })
+ comments, _, err := downloader.GetComments(&base.Issue{Number: 1, ForeignIndex: 1})
assert.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go
index 7bca128ac5..b550be4ce7 100644
--- a/services/migrations/migrate.go
+++ b/services/migrations/migrate.go
@@ -325,9 +325,7 @@ func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts
allComments := make([]*base.Comment, 0, commentBatchSize)
for _, issue := range issues {
log.Trace("migrating issue %d's comments", issue.Number)
- comments, _, err := downloader.GetComments(base.GetCommentOptions{
- Context: issue.Context,
- })
+ comments, _, err := downloader.GetComments(issue)
if err != nil {
if !base.IsErrNotSupported(err) {
return err
@@ -383,9 +381,7 @@ func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts
allComments := make([]*base.Comment, 0, commentBatchSize)
for _, pr := range prs {
log.Trace("migrating pull request %d's comments", pr.Number)
- comments, _, err := downloader.GetComments(base.GetCommentOptions{
- Context: pr.Context,
- })
+ comments, _, err := downloader.GetComments(pr)
if err != nil {
if !base.IsErrNotSupported(err) {
return err
@@ -412,7 +408,7 @@ func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts
// migrate reviews
allReviews := make([]*base.Review, 0, reviewBatchSize)
for _, pr := range prs {
- reviews, err := downloader.GetReviews(pr.Context)
+ reviews, err := downloader.GetReviews(pr)
if err != nil {
if !base.IsErrNotSupported(err) {
return err
@@ -446,10 +442,7 @@ func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts
if opts.Comments && supportAllComments {
log.Trace("migrating comments")
for i := 1; ; i++ {
- comments, isEnd, err := downloader.GetComments(base.GetCommentOptions{
- Page: i,
- PageSize: commentBatchSize,
- })
+ comments, isEnd, err := downloader.GetAllComments(i, commentBatchSize)
if err != nil {
return err
}
diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go
index d27cbbed4f..d4b30939ce 100644
--- a/services/migrations/onedev.go
+++ b/services/migrations/onedev.go
@@ -262,19 +262,9 @@ func (d *OneDevDownloader) GetLabels() ([]*base.Label, error) {
}
type onedevIssueContext struct {
- foreignID int64
- localID int64
IsPullRequest bool
}
-func (c onedevIssueContext) LocalID() int64 {
- return c.localID
-}
-
-func (c onedevIssueContext) ForeignID() int64 {
- return c.foreignID
-}
-
// GetIssues returns issues
func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) {
rawIssues := make([]struct {
@@ -346,21 +336,18 @@ func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
}
poster := d.tryGetUser(issue.SubmitterID)
issues = append(issues, &base.Issue{
- Title: issue.Title,
- Number: issue.Number,
- PosterName: poster.Name,
- PosterEmail: poster.Email,
- Content: issue.Description,
- Milestone: d.milestoneMap[milestoneID],
- State: state,
- Created: issue.SubmitDate,
- Updated: issue.SubmitDate,
- Labels: []*base.Label{label},
- Context: onedevIssueContext{
- foreignID: issue.ID,
- localID: issue.Number,
- IsPullRequest: false,
- },
+ Title: issue.Title,
+ Number: issue.Number,
+ PosterName: poster.Name,
+ PosterEmail: poster.Email,
+ Content: issue.Description,
+ Milestone: d.milestoneMap[milestoneID],
+ State: state,
+ Created: issue.SubmitDate,
+ Updated: issue.SubmitDate,
+ Labels: []*base.Label{label},
+ ForeignIndex: issue.ID,
+ Context: onedevIssueContext{IsPullRequest: false},
})
if d.maxIssueIndex < issue.Number {
@@ -372,10 +359,10 @@ func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
}
// GetComments returns comments
-func (d *OneDevDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Comment, bool, error) {
- context, ok := opts.Context.(onedevIssueContext)
+func (d *OneDevDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) {
+ context, ok := commentable.GetContext().(onedevIssueContext)
if !ok {
- return nil, false, fmt.Errorf("unexpected comment context: %+v", opts.Context)
+ return nil, false, fmt.Errorf("unexpected context: %+v", commentable.GetContext())
}
rawComments := make([]struct {
@@ -387,9 +374,9 @@ func (d *OneDevDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
var endpoint string
if context.IsPullRequest {
- endpoint = fmt.Sprintf("/api/pull-requests/%d/comments", context.ForeignID())
+ endpoint = fmt.Sprintf("/api/pull-requests/%d/comments", commentable.GetForeignIndex())
} else {
- endpoint = fmt.Sprintf("/api/issues/%d/comments", context.ForeignID())
+ endpoint = fmt.Sprintf("/api/issues/%d/comments", commentable.GetForeignIndex())
}
err := d.callAPI(
@@ -408,9 +395,9 @@ func (d *OneDevDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
}, 0, 100)
if context.IsPullRequest {
- endpoint = fmt.Sprintf("/api/pull-requests/%d/changes", context.ForeignID())
+ endpoint = fmt.Sprintf("/api/pull-requests/%d/changes", commentable.GetForeignIndex())
} else {
- endpoint = fmt.Sprintf("/api/issues/%d/changes", context.ForeignID())
+ endpoint = fmt.Sprintf("/api/issues/%d/changes", commentable.GetForeignIndex())
}
err = d.callAPI(
@@ -429,7 +416,7 @@ func (d *OneDevDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
}
poster := d.tryGetUser(comment.UserID)
comments = append(comments, &base.Comment{
- IssueIndex: context.LocalID(),
+ IssueIndex: commentable.GetLocalIndex(),
Index: comment.ID,
PosterID: poster.ID,
PosterName: poster.Name,
@@ -454,7 +441,7 @@ func (d *OneDevDownloader) GetComments(opts base.GetCommentOptions) ([]*base.Com
poster := d.tryGetUser(change.UserID)
comments = append(comments, &base.Comment{
- IssueIndex: context.LocalID(),
+ IssueIndex: commentable.GetLocalIndex(),
PosterID: poster.ID,
PosterName: poster.Name,
PosterEmail: poster.Email,
@@ -552,11 +539,8 @@ func (d *OneDevDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
SHA: mergePreview.TargetHeadCommitHash,
RepoName: d.repoName,
},
- Context: onedevIssueContext{
- foreignID: pr.ID,
- localID: number,
- IsPullRequest: true,
- },
+ ForeignIndex: pr.ID,
+ Context: onedevIssueContext{IsPullRequest: true},
})
}
@@ -564,7 +548,7 @@ func (d *OneDevDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
}
// GetReviews returns pull requests reviews
-func (d *OneDevDownloader) GetReviews(context base.IssueContext) ([]*base.Review, error) {
+func (d *OneDevDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) {
rawReviews := make([]struct {
ID int64 `json:"id"`
UserID int64 `json:"userId"`
@@ -576,7 +560,7 @@ func (d *OneDevDownloader) GetReviews(context base.IssueContext) ([]*base.Review
}, 0, 100)
err := d.callAPI(
- fmt.Sprintf("/api/pull-requests/%d/reviews", context.ForeignID()),
+ fmt.Sprintf("/api/pull-requests/%d/reviews", reviewable.GetForeignIndex()),
nil,
&rawReviews,
)
@@ -600,7 +584,7 @@ func (d *OneDevDownloader) GetReviews(context base.IssueContext) ([]*base.Review
poster := d.tryGetUser(review.UserID)
reviews = append(reviews, &base.Review{
- IssueIndex: context.LocalID(),
+ IssueIndex: reviewable.GetLocalIndex(),
ReviewerID: poster.ID,
ReviewerName: poster.Name,
Content: content,
diff --git a/services/migrations/onedev_test.go b/services/migrations/onedev_test.go
index 59b7cae5fe..55ae7da1fc 100644
--- a/services/migrations/onedev_test.go
+++ b/services/migrations/onedev_test.go
@@ -74,11 +74,8 @@ func TestOneDevDownloadRepo(t *testing.T) {
Name: "Improvement",
},
},
- Context: onedevIssueContext{
- foreignID: 398,
- localID: 4,
- IsPullRequest: false,
- },
+ ForeignIndex: 398,
+ Context: onedevIssueContext{IsPullRequest: false},
},
{
Number: 3,
@@ -94,20 +91,15 @@ func TestOneDevDownloadRepo(t *testing.T) {
Name: "New Feature",
},
},
- Context: onedevIssueContext{
- foreignID: 397,
- localID: 3,
- IsPullRequest: false,
- },
+ ForeignIndex: 397,
+ Context: onedevIssueContext{IsPullRequest: false},
},
}, issues)
- comments, _, err := downloader.GetComments(base.GetCommentOptions{
- Context: onedevIssueContext{
- foreignID: 398,
- localID: 4,
- IsPullRequest: false,
- },
+ comments, _, err := downloader.GetComments(&base.Issue{
+ Number: 4,
+ ForeignIndex: 398,
+ Context: onedevIssueContext{IsPullRequest: false},
})
assert.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
@@ -141,18 +133,12 @@ func TestOneDevDownloadRepo(t *testing.T) {
SHA: "f32b0a9dfd09a60f616f29158f772cedd89942d2",
RepoName: "go-gitea-test_repo",
},
- Context: onedevIssueContext{
- foreignID: 186,
- localID: 5,
- IsPullRequest: true,
- },
+ ForeignIndex: 186,
+ Context: onedevIssueContext{IsPullRequest: true},
},
}, prs)
- rvs, err := downloader.GetReviews(onedevIssueContext{
- foreignID: 186,
- localID: 5,
- })
+ rvs, err := downloader.GetReviews(&base.PullRequest{Number: 5, ForeignIndex: 186})
assert.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
diff --git a/services/migrations/restore.go b/services/migrations/restore.go
index d30d90a6c4..8c9654a7e3 100644
--- a/services/migrations/restore.go
+++ b/services/migrations/restore.go
@@ -193,17 +193,13 @@ func (r *RepositoryRestorer) GetIssues(page, perPage int) ([]*base.Issue, bool,
}
return nil, false, err
}
-
- for _, issue := range issues {
- issue.Context = base.BasicIssueContext(issue.Number)
- }
return issues, true, nil
}
// GetComments returns comments according issueNumber
-func (r *RepositoryRestorer) GetComments(opts base.GetCommentOptions) ([]*base.Comment, bool, error) {
+func (r *RepositoryRestorer) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) {
comments := make([]*base.Comment, 0, 10)
- p := filepath.Join(r.commentDir(), fmt.Sprintf("%d.yml", opts.Context.ForeignID()))
+ p := filepath.Join(r.commentDir(), fmt.Sprintf("%d.yml", commentable.GetForeignIndex()))
_, err := os.Stat(p)
if err != nil {
if os.IsNotExist(err) {
@@ -247,15 +243,14 @@ func (r *RepositoryRestorer) GetPullRequests(page, perPage int) ([]*base.PullReq
}
for _, pr := range pulls {
pr.PatchURL = "file://" + filepath.Join(r.baseDir, pr.PatchURL)
- pr.Context = base.BasicIssueContext(pr.Number)
}
return pulls, true, nil
}
// GetReviews returns pull requests review
-func (r *RepositoryRestorer) GetReviews(context base.IssueContext) ([]*base.Review, error) {
+func (r *RepositoryRestorer) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) {
reviews := make([]*base.Review, 0, 10)
- p := filepath.Join(r.reviewDir(), fmt.Sprintf("%d.yml", context.ForeignID()))
+ p := filepath.Join(r.reviewDir(), fmt.Sprintf("%d.yml", reviewable.GetForeignIndex()))
_, err := os.Stat(p)
if err != nil {
if os.IsNotExist(err) {