Skip to content

Commit 42ea002

Browse files
authored
Add migration from GitBucket (#16767)
This PR adds [GitBucket](https://gitbucket.github.io/) as migration source. Supported: - Milestones - Issues - Pull Requests - Comments - Reviews - Labels There is no public usable instance so no integration tests added.
1 parent d2163df commit 42ea002

File tree

8 files changed

+365
-106
lines changed

8 files changed

+365
-106
lines changed

modules/convert/utils.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ func ToGitServiceType(value string) structs.GitServiceType {
3535
return structs.GogsService
3636
case "onedev":
3737
return structs.OneDevService
38+
case "gitbucket":
39+
return structs.GitBucketService
3840
default:
3941
return structs.PlainGitService
4042
}

modules/migrations/gitbucket.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"context"
9+
"net/url"
10+
"strings"
11+
12+
"code.gitea.io/gitea/modules/migrations/base"
13+
"code.gitea.io/gitea/modules/structs"
14+
)
15+
16+
var (
17+
_ base.Downloader = &GitBucketDownloader{}
18+
_ base.DownloaderFactory = &GitBucketDownloaderFactory{}
19+
)
20+
21+
func init() {
22+
RegisterDownloaderFactory(&GitBucketDownloaderFactory{})
23+
}
24+
25+
// GitBucketDownloaderFactory defines a GitBucket downloader factory
26+
type GitBucketDownloaderFactory struct {
27+
}
28+
29+
// New returns a Downloader related to this factory according MigrateOptions
30+
func (f *GitBucketDownloaderFactory) New(ctx context.Context, opts base.MigrateOptions) (base.Downloader, error) {
31+
u, err := url.Parse(opts.CloneAddr)
32+
if err != nil {
33+
return nil, err
34+
}
35+
36+
baseURL := u.Scheme + "://" + u.Host
37+
fields := strings.Split(u.Path, "/")
38+
oldOwner := fields[1]
39+
oldName := strings.TrimSuffix(fields[2], ".git")
40+
41+
return NewGitBucketDownloader(ctx, baseURL, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, oldOwner, oldName), nil
42+
}
43+
44+
// GitServiceType returns the type of git service
45+
func (f *GitBucketDownloaderFactory) GitServiceType() structs.GitServiceType {
46+
return structs.GitBucketService
47+
}
48+
49+
// GitBucketDownloader implements a Downloader interface to get repository information
50+
// from GitBucket via GithubDownloader
51+
type GitBucketDownloader struct {
52+
*GithubDownloaderV3
53+
}
54+
55+
// NewGitBucketDownloader creates a GitBucket downloader
56+
func NewGitBucketDownloader(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GitBucketDownloader {
57+
githubDownloader := NewGithubDownloaderV3(ctx, baseURL, userName, password, token, repoOwner, repoName)
58+
githubDownloader.SkipReactions = true
59+
return &GitBucketDownloader{
60+
githubDownloader,
61+
}
62+
}
63+
64+
// SupportGetRepoComments return true if it supports get repo comments
65+
func (g *GitBucketDownloader) SupportGetRepoComments() bool {
66+
return false
67+
}
68+
69+
// GetReviews is not supported
70+
func (g *GitBucketDownloader) GetReviews(context base.IssueContext) ([]*base.Review, error) {
71+
return nil, &base.ErrNotSupported{Entity: "Reviews"}
72+
}

modules/migrations/github.go

Lines changed: 110 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,16 @@ func (f *GithubDownloaderV3Factory) GitServiceType() structs.GitServiceType {
6868
// from github via APIv3
6969
type GithubDownloaderV3 struct {
7070
base.NullDownloader
71-
ctx context.Context
72-
clients []*github.Client
73-
repoOwner string
74-
repoName string
75-
userName string
76-
password string
77-
rates []*github.Rate
78-
curClientIdx int
79-
maxPerPage int
71+
ctx context.Context
72+
clients []*github.Client
73+
repoOwner string
74+
repoName string
75+
userName string
76+
password string
77+
rates []*github.Rate
78+
curClientIdx int
79+
maxPerPage int
80+
SkipReactions bool
8081
}
8182

8283
// NewGithubDownloaderV3 creates a github Downloader via github v3 API
@@ -428,25 +429,27 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool,
428429

429430
// get reactions
430431
var reactions []*base.Reaction
431-
for i := 1; ; i++ {
432-
g.waitAndPickClient()
433-
res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, issue.GetNumber(), &github.ListOptions{
434-
Page: i,
435-
PerPage: perPage,
436-
})
437-
if err != nil {
438-
return nil, false, err
439-
}
440-
g.setRate(&resp.Rate)
441-
if len(res) == 0 {
442-
break
443-
}
444-
for _, reaction := range res {
445-
reactions = append(reactions, &base.Reaction{
446-
UserID: reaction.User.GetID(),
447-
UserName: reaction.User.GetLogin(),
448-
Content: reaction.GetContent(),
432+
if !g.SkipReactions {
433+
for i := 1; ; i++ {
434+
g.waitAndPickClient()
435+
res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, issue.GetNumber(), &github.ListOptions{
436+
Page: i,
437+
PerPage: perPage,
449438
})
439+
if err != nil {
440+
return nil, false, err
441+
}
442+
g.setRate(&resp.Rate)
443+
if len(res) == 0 {
444+
break
445+
}
446+
for _, reaction := range res {
447+
reactions = append(reactions, &base.Reaction{
448+
UserID: reaction.User.GetID(),
449+
UserName: reaction.User.GetLogin(),
450+
Content: reaction.GetContent(),
451+
})
452+
}
450453
}
451454
}
452455

@@ -516,25 +519,27 @@ func (g *GithubDownloaderV3) getComments(issueContext base.IssueContext) ([]*bas
516519
for _, comment := range comments {
517520
// get reactions
518521
var reactions []*base.Reaction
519-
for i := 1; ; i++ {
520-
g.waitAndPickClient()
521-
res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{
522-
Page: i,
523-
PerPage: g.maxPerPage,
524-
})
525-
if err != nil {
526-
return nil, err
527-
}
528-
g.setRate(&resp.Rate)
529-
if len(res) == 0 {
530-
break
531-
}
532-
for _, reaction := range res {
533-
reactions = append(reactions, &base.Reaction{
534-
UserID: reaction.User.GetID(),
535-
UserName: reaction.User.GetLogin(),
536-
Content: reaction.GetContent(),
522+
if !g.SkipReactions {
523+
for i := 1; ; i++ {
524+
g.waitAndPickClient()
525+
res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{
526+
Page: i,
527+
PerPage: g.maxPerPage,
537528
})
529+
if err != nil {
530+
return nil, err
531+
}
532+
g.setRate(&resp.Rate)
533+
if len(res) == 0 {
534+
break
535+
}
536+
for _, reaction := range res {
537+
reactions = append(reactions, &base.Reaction{
538+
UserID: reaction.User.GetID(),
539+
UserName: reaction.User.GetLogin(),
540+
Content: reaction.GetContent(),
541+
})
542+
}
538543
}
539544
}
540545

@@ -588,25 +593,27 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment,
588593
for _, comment := range comments {
589594
// get reactions
590595
var reactions []*base.Reaction
591-
for i := 1; ; i++ {
592-
g.waitAndPickClient()
593-
res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{
594-
Page: i,
595-
PerPage: g.maxPerPage,
596-
})
597-
if err != nil {
598-
return nil, false, err
599-
}
600-
g.setRate(&resp.Rate)
601-
if len(res) == 0 {
602-
break
603-
}
604-
for _, reaction := range res {
605-
reactions = append(reactions, &base.Reaction{
606-
UserID: reaction.User.GetID(),
607-
UserName: reaction.User.GetLogin(),
608-
Content: reaction.GetContent(),
596+
if !g.SkipReactions {
597+
for i := 1; ; i++ {
598+
g.waitAndPickClient()
599+
res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{
600+
Page: i,
601+
PerPage: g.maxPerPage,
609602
})
603+
if err != nil {
604+
return nil, false, err
605+
}
606+
g.setRate(&resp.Rate)
607+
if len(res) == 0 {
608+
break
609+
}
610+
for _, reaction := range res {
611+
reactions = append(reactions, &base.Reaction{
612+
UserID: reaction.User.GetID(),
613+
UserName: reaction.User.GetLogin(),
614+
Content: reaction.GetContent(),
615+
})
616+
}
610617
}
611618
}
612619
idx := strings.LastIndex(*comment.IssueURL, "/")
@@ -656,25 +663,27 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq
656663

657664
// get reactions
658665
var reactions []*base.Reaction
659-
for i := 1; ; i++ {
660-
g.waitAndPickClient()
661-
res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, pr.GetNumber(), &github.ListOptions{
662-
Page: i,
663-
PerPage: perPage,
664-
})
665-
if err != nil {
666-
return nil, false, err
667-
}
668-
g.setRate(&resp.Rate)
669-
if len(res) == 0 {
670-
break
671-
}
672-
for _, reaction := range res {
673-
reactions = append(reactions, &base.Reaction{
674-
UserID: reaction.User.GetID(),
675-
UserName: reaction.User.GetLogin(),
676-
Content: reaction.GetContent(),
666+
if !g.SkipReactions {
667+
for i := 1; ; i++ {
668+
g.waitAndPickClient()
669+
res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, pr.GetNumber(), &github.ListOptions{
670+
Page: i,
671+
PerPage: perPage,
677672
})
673+
if err != nil {
674+
return nil, false, err
675+
}
676+
g.setRate(&resp.Rate)
677+
if len(res) == 0 {
678+
break
679+
}
680+
for _, reaction := range res {
681+
reactions = append(reactions, &base.Reaction{
682+
UserID: reaction.User.GetID(),
683+
UserName: reaction.User.GetLogin(),
684+
Content: reaction.GetContent(),
685+
})
686+
}
678687
}
679688
}
680689

@@ -737,25 +746,27 @@ func (g *GithubDownloaderV3) convertGithubReviewComments(cs []*github.PullReques
737746
for _, c := range cs {
738747
// get reactions
739748
var reactions []*base.Reaction
740-
for i := 1; ; i++ {
741-
g.waitAndPickClient()
742-
res, resp, err := g.getClient().Reactions.ListPullRequestCommentReactions(g.ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListOptions{
743-
Page: i,
744-
PerPage: g.maxPerPage,
745-
})
746-
if err != nil {
747-
return nil, err
748-
}
749-
g.setRate(&resp.Rate)
750-
if len(res) == 0 {
751-
break
752-
}
753-
for _, reaction := range res {
754-
reactions = append(reactions, &base.Reaction{
755-
UserID: reaction.User.GetID(),
756-
UserName: reaction.User.GetLogin(),
757-
Content: reaction.GetContent(),
749+
if !g.SkipReactions {
750+
for i := 1; ; i++ {
751+
g.waitAndPickClient()
752+
res, resp, err := g.getClient().Reactions.ListPullRequestCommentReactions(g.ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListOptions{
753+
Page: i,
754+
PerPage: g.maxPerPage,
758755
})
756+
if err != nil {
757+
return nil, err
758+
}
759+
g.setRate(&resp.Rate)
760+
if len(res) == 0 {
761+
break
762+
}
763+
for _, reaction := range res {
764+
reactions = append(reactions, &base.Reaction{
765+
UserID: reaction.User.GetID(),
766+
UserName: reaction.User.GetLogin(),
767+
Content: reaction.GetContent(),
768+
})
769+
}
759770
}
760771
}
761772

modules/structs/repo.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,14 @@ type GitServiceType int
242242

243243
// enumerate all GitServiceType
244244
const (
245-
NotMigrated GitServiceType = iota // 0 not migrated from external sites
246-
PlainGitService // 1 plain git service
247-
GithubService // 2 github.com
248-
GiteaService // 3 gitea service
249-
GitlabService // 4 gitlab service
250-
GogsService // 5 gogs service
251-
OneDevService // 6 onedev service
245+
NotMigrated GitServiceType = iota // 0 not migrated from external sites
246+
PlainGitService // 1 plain git service
247+
GithubService // 2 github.com
248+
GiteaService // 3 gitea service
249+
GitlabService // 4 gitlab service
250+
GogsService // 5 gogs service
251+
OneDevService // 6 onedev service
252+
GitBucketService // 7 gitbucket service
252253
)
253254

254255
// Name represents the service type's name
@@ -270,6 +271,8 @@ func (gt GitServiceType) Title() string {
270271
return "Gogs"
271272
case OneDevService:
272273
return "OneDev"
274+
case GitBucketService:
275+
return "GitBucket"
273276
case PlainGitService:
274277
return "Git"
275278
}
@@ -326,5 +329,6 @@ var (
326329
GiteaService,
327330
GogsService,
328331
OneDevService,
332+
GitBucketService,
329333
}
330334
)

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,7 @@ migrate.gitlab.description = Migrate data from gitlab.com or other GitLab instan
911911
migrate.gitea.description = Migrate data from gitea.com or other Gitea instances.
912912
migrate.gogs.description = Migrate data from notabug.org or other Gogs instances.
913913
migrate.onedev.description = Migrate data from code.onedev.io or other OneDev instances.
914+
migrate.gitbucket.description = Migrating data from GitBucket instances.
914915
migrate.migrating_git = Migrating Git Data
915916
migrate.migrating_topics = Migrating Topics
916917
migrate.migrating_milestones = Migrating Milestones

public/img/svg/gitea-gitbucket.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)