A tool to migrate GitHub Repositories to Gitea including all issues
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
gitea-github-migrator/migrations/job.go

114 lines
3.0 KiB

package migrations
import (
"fmt"
"strings"
"code.gitea.io/sdk/gitea"
"github.com/google/go-github/github"
)
// Job manages all migrations of a "migartion job"
type Job struct {
Repositories []string
Options *Options
Client *gitea.Client
GHClient *github.Client
migratories map[string]*Migratory
}
// JobReport represents the current status of a Job
type JobReport struct {
Pending []string `json:"pending"`
Running map[string]*MigratoryStatus `json:"running"`
Finished map[string]*MigratoryStatus `json:"finished"`
Failed map[string]string `json:"failed"`
}
// NewJob returns an instance of initialized instance of Job
func NewJob(options *Options, client *gitea.Client, githubClient *github.Client, repos ...string) *Job {
return &Job{Repositories: repos, Options: options, Client: client, GHClient: githubClient}
}
// StatusReport generates a JobReport indicating which state the job is
func (job *Job) StatusReport() *JobReport {
report := &JobReport{
Pending: make([]string, 0),
Finished: make(map[string]*MigratoryStatus),
Running: make(map[string]*MigratoryStatus),
Failed: make(map[string]string),
}
for _, repo := range job.Repositories {
if migratory, ok := job.migratories[repo]; ok {
switch migratory.Status.Stage {
case Finished:
report.Finished[repo] = migratory.Status
case Importing:
case Migrating:
report.Running[repo] = migratory.Status
case Failed:
report.Failed[repo] = migratory.Status.FatalError.Error()
default:
report.Pending = append(report.Pending, repo)
fmt.Printf("unknown status %d\n", migratory.Status.Stage)
}
} else {
report.Pending = append(report.Pending, repo)
}
}
return report
}
// StartMigration migrates all repos from Repositories
func (job *Job) StartMigration() chan error {
errs := make(chan error, len(job.Repositories))
var pendingRepos = len(job.Repositories)
autoclose := func() {
pendingRepos--
if pendingRepos <= 0 {
close(errs)
}
}
job.migratories = make(map[string]*Migratory, pendingRepos)
for _, repo := range job.Repositories {
mig, err := job.initFetchMigratory(repo)
job.migratories[repo] = &mig.Migratory
if err != nil {
mig.Status = &MigratoryStatus{
Stage: Failed,
FatalError: err,
}
errs <- err
autoclose()
continue
}
go func() {
err := mig.MigrateFromGitHub()
errs <- err
autoclose()
}()
}
return errs
}
func (job *Job) initFetchMigratory(repo string) (*FetchMigratory, error) {
res := strings.Split(repo, "/")
if len(res) != 2 {
return nil, fmt.Errorf("invalid repo name: %s", repo)
}
return &FetchMigratory{
Migratory: Migratory{
Client: job.Client,
Options: *job.Options,
},
RepoName: res[1],
RepoOwner: res[0],
GHClient: job.GHClient,
}, nil
}
// Finished indicates if the job is finished or not
func (job *Job) Finished() bool {
return (len(job.StatusReport().Failed) + len(job.StatusReport().Finished)) >= len(job.Repositories)
}