Skip to content

Commit 81c833d

Browse files
6543lunnyzeripath
authored
Add support to migrate from gogs (#14342)
Add support to migrate gogs: * issues * comments * labels * milestones * wiki Co-authored-by: Lunny Xiao <[email protected]> Co-authored-by: Andrew Thornton <[email protected]>
1 parent b5570d3 commit 81c833d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2782
-353
lines changed

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ require (
4646
github.com/gobwas/glob v0.2.3
4747
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
4848
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
49+
github.com/gogs/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355
4950
github.com/google/go-github/v32 v32.1.0
5051
github.com/google/uuid v1.1.2
5152
github.com/gorilla/context v1.1.1
@@ -128,3 +129,5 @@ require (
128129
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.2.4
129130

130131
replace github.com/microcosm-cc/bluemonday => github.com/lunny/bluemonday v1.0.5-0.20201227154428-ca34796141e8
132+
133+
replace github.com/gogs/go-gogs-client => github.com/6543-forks/go-gogs-client v0.0.0-20210116182316-f2f8bc0ea9cc

go.sum

+4-55
Large diffs are not rendered by default.

modules/migrations/base/downloader.go

+1-211
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package base
77

88
import (
99
"context"
10-
"time"
1110

1211
"code.gitea.io/gitea/modules/structs"
1312
)
@@ -24,220 +23,11 @@ type Downloader interface {
2423
GetComments(issueNumber int64) ([]*Comment, error)
2524
GetPullRequests(page, perPage int) ([]*PullRequest, bool, error)
2625
GetReviews(pullRequestNumber int64) ([]*Review, error)
26+
FormatCloneURL(opts MigrateOptions, remoteAddr string) (string, error)
2727
}
2828

2929
// DownloaderFactory defines an interface to match a downloader implementation and create a downloader
3030
type DownloaderFactory interface {
3131
New(ctx context.Context, opts MigrateOptions) (Downloader, error)
3232
GitServiceType() structs.GitServiceType
3333
}
34-
35-
var (
36-
_ Downloader = &RetryDownloader{}
37-
)
38-
39-
// RetryDownloader retry the downloads
40-
type RetryDownloader struct {
41-
Downloader
42-
ctx context.Context
43-
RetryTimes int // the total execute times
44-
RetryDelay int // time to delay seconds
45-
}
46-
47-
// NewRetryDownloader creates a retry downloader
48-
func NewRetryDownloader(ctx context.Context, downloader Downloader, retryTimes, retryDelay int) *RetryDownloader {
49-
return &RetryDownloader{
50-
Downloader: downloader,
51-
ctx: ctx,
52-
RetryTimes: retryTimes,
53-
RetryDelay: retryDelay,
54-
}
55-
}
56-
57-
// SetContext set context
58-
func (d *RetryDownloader) SetContext(ctx context.Context) {
59-
d.ctx = ctx
60-
d.Downloader.SetContext(ctx)
61-
}
62-
63-
// GetRepoInfo returns a repository information with retry
64-
func (d *RetryDownloader) GetRepoInfo() (*Repository, error) {
65-
var (
66-
times = d.RetryTimes
67-
repo *Repository
68-
err error
69-
)
70-
for ; times > 0; times-- {
71-
if repo, err = d.Downloader.GetRepoInfo(); err == nil {
72-
return repo, nil
73-
}
74-
select {
75-
case <-d.ctx.Done():
76-
return nil, d.ctx.Err()
77-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
78-
}
79-
}
80-
return nil, err
81-
}
82-
83-
// GetTopics returns a repository's topics with retry
84-
func (d *RetryDownloader) GetTopics() ([]string, error) {
85-
var (
86-
times = d.RetryTimes
87-
topics []string
88-
err error
89-
)
90-
for ; times > 0; times-- {
91-
if topics, err = d.Downloader.GetTopics(); err == nil {
92-
return topics, nil
93-
}
94-
select {
95-
case <-d.ctx.Done():
96-
return nil, d.ctx.Err()
97-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
98-
}
99-
}
100-
return nil, err
101-
}
102-
103-
// GetMilestones returns a repository's milestones with retry
104-
func (d *RetryDownloader) GetMilestones() ([]*Milestone, error) {
105-
var (
106-
times = d.RetryTimes
107-
milestones []*Milestone
108-
err error
109-
)
110-
for ; times > 0; times-- {
111-
if milestones, err = d.Downloader.GetMilestones(); err == nil {
112-
return milestones, nil
113-
}
114-
select {
115-
case <-d.ctx.Done():
116-
return nil, d.ctx.Err()
117-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
118-
}
119-
}
120-
return nil, err
121-
}
122-
123-
// GetReleases returns a repository's releases with retry
124-
func (d *RetryDownloader) GetReleases() ([]*Release, error) {
125-
var (
126-
times = d.RetryTimes
127-
releases []*Release
128-
err error
129-
)
130-
for ; times > 0; times-- {
131-
if releases, err = d.Downloader.GetReleases(); err == nil {
132-
return releases, nil
133-
}
134-
select {
135-
case <-d.ctx.Done():
136-
return nil, d.ctx.Err()
137-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
138-
}
139-
}
140-
return nil, err
141-
}
142-
143-
// GetLabels returns a repository's labels with retry
144-
func (d *RetryDownloader) GetLabels() ([]*Label, error) {
145-
var (
146-
times = d.RetryTimes
147-
labels []*Label
148-
err error
149-
)
150-
for ; times > 0; times-- {
151-
if labels, err = d.Downloader.GetLabels(); err == nil {
152-
return labels, nil
153-
}
154-
select {
155-
case <-d.ctx.Done():
156-
return nil, d.ctx.Err()
157-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
158-
}
159-
}
160-
return nil, err
161-
}
162-
163-
// GetIssues returns a repository's issues with retry
164-
func (d *RetryDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) {
165-
var (
166-
times = d.RetryTimes
167-
issues []*Issue
168-
isEnd bool
169-
err error
170-
)
171-
for ; times > 0; times-- {
172-
if issues, isEnd, err = d.Downloader.GetIssues(page, perPage); err == nil {
173-
return issues, isEnd, nil
174-
}
175-
select {
176-
case <-d.ctx.Done():
177-
return nil, false, d.ctx.Err()
178-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
179-
}
180-
}
181-
return nil, false, err
182-
}
183-
184-
// GetComments returns a repository's comments with retry
185-
func (d *RetryDownloader) GetComments(issueNumber int64) ([]*Comment, error) {
186-
var (
187-
times = d.RetryTimes
188-
comments []*Comment
189-
err error
190-
)
191-
for ; times > 0; times-- {
192-
if comments, err = d.Downloader.GetComments(issueNumber); err == nil {
193-
return comments, nil
194-
}
195-
select {
196-
case <-d.ctx.Done():
197-
return nil, d.ctx.Err()
198-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
199-
}
200-
}
201-
return nil, err
202-
}
203-
204-
// GetPullRequests returns a repository's pull requests with retry
205-
func (d *RetryDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bool, error) {
206-
var (
207-
times = d.RetryTimes
208-
prs []*PullRequest
209-
err error
210-
isEnd bool
211-
)
212-
for ; times > 0; times-- {
213-
if prs, isEnd, err = d.Downloader.GetPullRequests(page, perPage); err == nil {
214-
return prs, isEnd, nil
215-
}
216-
select {
217-
case <-d.ctx.Done():
218-
return nil, false, d.ctx.Err()
219-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
220-
}
221-
}
222-
return nil, false, err
223-
}
224-
225-
// GetReviews returns pull requests reviews
226-
func (d *RetryDownloader) GetReviews(pullRequestNumber int64) ([]*Review, error) {
227-
var (
228-
times = d.RetryTimes
229-
reviews []*Review
230-
err error
231-
)
232-
for ; times > 0; times-- {
233-
if reviews, err = d.Downloader.GetReviews(pullRequestNumber); err == nil {
234-
return reviews, nil
235-
}
236-
select {
237-
case <-d.ctx.Done():
238-
return nil, d.ctx.Err()
239-
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
240-
}
241-
}
242-
return nil, err
243-
}

modules/migrations/base/error.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 base
6+
7+
import "fmt"
8+
9+
// ErrNotSupported represents status if a downloader do not supported something.
10+
type ErrNotSupported struct {
11+
Entity string
12+
}
13+
14+
// IsErrNotSupported checks if an error is an ErrNotSupported
15+
func IsErrNotSupported(err error) bool {
16+
_, ok := err.(ErrNotSupported)
17+
return ok
18+
}
19+
20+
// Error return error message
21+
func (err ErrNotSupported) Error() string {
22+
if len(err.Entity) != 0 {
23+
return fmt.Sprintf("'%s' not supported", err.Entity)
24+
}
25+
return "not supported"
26+
}

modules/migrations/base/milestone.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ type Milestone struct {
1515
Created time.Time
1616
Updated *time.Time
1717
Closed *time.Time
18-
State string
18+
State string // open, closed
1919
}
+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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 base
6+
7+
import (
8+
"context"
9+
"net/url"
10+
)
11+
12+
// NullDownloader implements a blank downloader
13+
type NullDownloader struct {
14+
}
15+
16+
var (
17+
_ Downloader = &NullDownloader{}
18+
)
19+
20+
// SetContext set context
21+
func (n NullDownloader) SetContext(_ context.Context) {}
22+
23+
// GetRepoInfo returns a repository information
24+
func (n NullDownloader) GetRepoInfo() (*Repository, error) {
25+
return nil, &ErrNotSupported{Entity: "RepoInfo"}
26+
}
27+
28+
// GetTopics return repository topics
29+
func (n NullDownloader) GetTopics() ([]string, error) {
30+
return nil, &ErrNotSupported{Entity: "Topics"}
31+
}
32+
33+
// GetMilestones returns milestones
34+
func (n NullDownloader) GetMilestones() ([]*Milestone, error) {
35+
return nil, &ErrNotSupported{Entity: "Milestones"}
36+
}
37+
38+
// GetReleases returns releases
39+
func (n NullDownloader) GetReleases() ([]*Release, error) {
40+
return nil, &ErrNotSupported{Entity: "Releases"}
41+
}
42+
43+
// GetLabels returns labels
44+
func (n NullDownloader) GetLabels() ([]*Label, error) {
45+
return nil, &ErrNotSupported{Entity: "Labels"}
46+
}
47+
48+
// GetIssues returns issues according start and limit
49+
func (n NullDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) {
50+
return nil, false, &ErrNotSupported{Entity: "Issues"}
51+
}
52+
53+
// GetComments returns comments according issueNumber
54+
func (n NullDownloader) GetComments(issueNumber int64) ([]*Comment, error) {
55+
return nil, &ErrNotSupported{Entity: "Comments"}
56+
}
57+
58+
// GetPullRequests returns pull requests according page and perPage
59+
func (n NullDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bool, error) {
60+
return nil, false, &ErrNotSupported{Entity: "PullRequests"}
61+
}
62+
63+
// GetReviews returns pull requests review
64+
func (n NullDownloader) GetReviews(pullRequestNumber int64) ([]*Review, error) {
65+
return nil, &ErrNotSupported{Entity: "Reviews"}
66+
}
67+
68+
// FormatCloneURL add authentification into remote URLs
69+
func (n NullDownloader) FormatCloneURL(opts MigrateOptions, remoteAddr string) (string, error) {
70+
if len(opts.AuthToken) > 0 || len(opts.AuthUsername) > 0 {
71+
u, err := url.Parse(remoteAddr)
72+
if err != nil {
73+
return "", err
74+
}
75+
u.User = url.UserPassword(opts.AuthUsername, opts.AuthPassword)
76+
if len(opts.AuthToken) > 0 {
77+
u.User = url.UserPassword("oauth2", opts.AuthToken)
78+
}
79+
return u.String(), nil
80+
}
81+
return remoteAddr, nil
82+
}

0 commit comments

Comments
 (0)