2020-12-27 06:34:19 +03:00
// Copyright 2020 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 (
"context"
"fmt"
"os"
"path/filepath"
"strconv"
2021-11-16 18:25:33 +03:00
base "code.gitea.io/gitea/modules/migration"
2020-12-27 06:34:19 +03:00
"gopkg.in/yaml.v2"
)
// RepositoryRestorer implements an Downloader from the local directory
type RepositoryRestorer struct {
2021-01-21 22:33:58 +03:00
base . NullDownloader
2022-01-26 12:45:51 +03:00
ctx context . Context
baseDir string
repoOwner string
repoName string
validation bool
2020-12-27 06:34:19 +03:00
}
// NewRepositoryRestorer creates a repository restorer which could restore repository from a dumped folder
2022-01-26 12:45:51 +03:00
func NewRepositoryRestorer ( ctx context . Context , baseDir , owner , repoName string , validation bool ) ( * RepositoryRestorer , error ) {
2020-12-27 06:34:19 +03:00
baseDir , err := filepath . Abs ( baseDir )
if err != nil {
return nil , err
}
return & RepositoryRestorer {
2022-01-26 12:45:51 +03:00
ctx : ctx ,
baseDir : baseDir ,
repoOwner : owner ,
repoName : repoName ,
validation : validation ,
2020-12-27 06:34:19 +03:00
} , nil
}
func ( r * RepositoryRestorer ) commentDir ( ) string {
return filepath . Join ( r . baseDir , "comments" )
}
func ( r * RepositoryRestorer ) reviewDir ( ) string {
return filepath . Join ( r . baseDir , "reviews" )
}
// SetContext set context
func ( r * RepositoryRestorer ) SetContext ( ctx context . Context ) {
r . ctx = ctx
}
2021-02-22 06:57:41 +03:00
func ( r * RepositoryRestorer ) getRepoOptions ( ) ( map [ string ] string , error ) {
2020-12-27 06:34:19 +03:00
p := filepath . Join ( r . baseDir , "repo.yml" )
2021-09-22 08:38:34 +03:00
bs , err := os . ReadFile ( p )
2020-12-27 06:34:19 +03:00
if err != nil {
return nil , err
}
2022-01-20 20:46:10 +03:00
opts := make ( map [ string ] string )
2020-12-27 06:34:19 +03:00
err = yaml . Unmarshal ( bs , & opts )
if err != nil {
return nil , err
}
2021-02-22 06:57:41 +03:00
return opts , nil
}
// GetRepoInfo returns a repository information
func ( r * RepositoryRestorer ) GetRepoInfo ( ) ( * base . Repository , error ) {
opts , err := r . getRepoOptions ( )
if err != nil {
return nil , err
}
2020-12-27 06:34:19 +03:00
isPrivate , _ := strconv . ParseBool ( opts [ "is_private" ] )
return & base . Repository {
Owner : r . repoOwner ,
Name : r . repoName ,
IsPrivate : isPrivate ,
Description : opts [ "description" ] ,
OriginalURL : opts [ "original_url" ] ,
2021-06-04 16:14:20 +03:00
CloneURL : filepath . Join ( r . baseDir , "git" ) ,
2020-12-27 06:34:19 +03:00
DefaultBranch : opts [ "default_branch" ] ,
} , nil
}
// GetTopics return github topics
func ( r * RepositoryRestorer ) GetTopics ( ) ( [ ] string , error ) {
p := filepath . Join ( r . baseDir , "topic.yml" )
2022-01-20 20:46:10 +03:00
topics := struct {
2020-12-27 06:34:19 +03:00
Topics [ ] string ` yaml:"topics" `
} { }
2021-09-22 08:38:34 +03:00
bs , err := os . ReadFile ( p )
2020-12-27 06:34:19 +03:00
if err != nil {
2022-01-25 05:44:12 +03:00
if os . IsNotExist ( err ) {
return nil , nil
}
2020-12-27 06:34:19 +03:00
return nil , err
}
err = yaml . Unmarshal ( bs , & topics )
if err != nil {
return nil , err
}
return topics . Topics , nil
}
// GetMilestones returns milestones
func ( r * RepositoryRestorer ) GetMilestones ( ) ( [ ] * base . Milestone , error ) {
2022-01-20 20:46:10 +03:00
milestones := make ( [ ] * base . Milestone , 0 , 10 )
2020-12-27 06:34:19 +03:00
p := filepath . Join ( r . baseDir , "milestone.yml" )
2022-01-26 12:45:51 +03:00
err := base . Load ( p , & milestones , r . validation )
2020-12-27 06:34:19 +03:00
if err != nil {
if os . IsNotExist ( err ) {
return nil , nil
}
return nil , err
}
return milestones , nil
}
// GetReleases returns releases
func ( r * RepositoryRestorer ) GetReleases ( ) ( [ ] * base . Release , error ) {
2022-01-20 20:46:10 +03:00
releases := make ( [ ] * base . Release , 0 , 10 )
2020-12-27 06:34:19 +03:00
p := filepath . Join ( r . baseDir , "release.yml" )
_ , err := os . Stat ( p )
if err != nil {
if os . IsNotExist ( err ) {
return nil , nil
}
return nil , err
}
2021-09-22 08:38:34 +03:00
bs , err := os . ReadFile ( p )
2020-12-27 06:34:19 +03:00
if err != nil {
return nil , err
}
err = yaml . Unmarshal ( bs , & releases )
if err != nil {
return nil , err
}
for _ , rel := range releases {
for _ , asset := range rel . Assets {
2021-06-04 16:14:20 +03:00
if asset . DownloadURL != nil {
* asset . DownloadURL = "file://" + filepath . Join ( r . baseDir , * asset . DownloadURL )
}
2020-12-27 06:34:19 +03:00
}
}
return releases , nil
}
// GetLabels returns labels
func ( r * RepositoryRestorer ) GetLabels ( ) ( [ ] * base . Label , error ) {
2022-01-20 20:46:10 +03:00
labels := make ( [ ] * base . Label , 0 , 10 )
2020-12-27 06:34:19 +03:00
p := filepath . Join ( r . baseDir , "label.yml" )
_ , err := os . Stat ( p )
if err != nil {
if os . IsNotExist ( err ) {
return nil , nil
}
return nil , err
}
2021-09-22 08:38:34 +03:00
bs , err := os . ReadFile ( p )
2020-12-27 06:34:19 +03:00
if err != nil {
return nil , err
}
err = yaml . Unmarshal ( bs , & labels )
if err != nil {
return nil , err
}
return labels , nil
}
// GetIssues returns issues according start and limit
func ( r * RepositoryRestorer ) GetIssues ( page , perPage int ) ( [ ] * base . Issue , bool , error ) {
2022-01-20 20:46:10 +03:00
issues := make ( [ ] * base . Issue , 0 , 10 )
2020-12-27 06:34:19 +03:00
p := filepath . Join ( r . baseDir , "issue.yml" )
2022-01-26 12:45:51 +03:00
err := base . Load ( p , & issues , r . validation )
2020-12-27 06:34:19 +03:00
if err != nil {
if os . IsNotExist ( err ) {
return nil , true , nil
}
return nil , false , err
}
2021-08-22 01:47:45 +03:00
for _ , issue := range issues {
issue . Context = base . BasicIssueContext ( issue . Number )
}
2020-12-27 06:34:19 +03:00
return issues , true , nil
}
// GetComments returns comments according issueNumber
2021-06-30 10:23:49 +03:00
func ( r * RepositoryRestorer ) GetComments ( opts base . GetCommentOptions ) ( [ ] * base . Comment , bool , error ) {
2022-01-20 20:46:10 +03:00
comments := make ( [ ] * base . Comment , 0 , 10 )
2021-08-22 01:47:45 +03:00
p := filepath . Join ( r . commentDir ( ) , fmt . Sprintf ( "%d.yml" , opts . Context . ForeignID ( ) ) )
2020-12-27 06:34:19 +03:00
_ , err := os . Stat ( p )
if err != nil {
if os . IsNotExist ( err ) {
2021-06-30 10:23:49 +03:00
return nil , false , nil
2020-12-27 06:34:19 +03:00
}
2021-06-30 10:23:49 +03:00
return nil , false , err
2020-12-27 06:34:19 +03:00
}
2021-09-22 08:38:34 +03:00
bs , err := os . ReadFile ( p )
2020-12-27 06:34:19 +03:00
if err != nil {
2021-06-30 10:23:49 +03:00
return nil , false , err
2020-12-27 06:34:19 +03:00
}
err = yaml . Unmarshal ( bs , & comments )
if err != nil {
2021-06-30 10:23:49 +03:00
return nil , false , err
2020-12-27 06:34:19 +03:00
}
2021-06-30 10:23:49 +03:00
return comments , false , nil
2020-12-27 06:34:19 +03:00
}
// GetPullRequests returns pull requests according page and perPage
func ( r * RepositoryRestorer ) GetPullRequests ( page , perPage int ) ( [ ] * base . PullRequest , bool , error ) {
2022-01-20 20:46:10 +03:00
pulls := make ( [ ] * base . PullRequest , 0 , 10 )
2020-12-27 06:34:19 +03:00
p := filepath . Join ( r . baseDir , "pull_request.yml" )
_ , err := os . Stat ( p )
if err != nil {
if os . IsNotExist ( err ) {
return nil , true , nil
}
return nil , false , err
}
2021-09-22 08:38:34 +03:00
bs , err := os . ReadFile ( p )
2020-12-27 06:34:19 +03:00
if err != nil {
return nil , false , err
}
err = yaml . Unmarshal ( bs , & pulls )
if err != nil {
return nil , false , err
}
for _ , pr := range pulls {
pr . PatchURL = "file://" + filepath . Join ( r . baseDir , pr . PatchURL )
2021-08-22 01:47:45 +03:00
pr . Context = base . BasicIssueContext ( pr . Number )
2020-12-27 06:34:19 +03:00
}
return pulls , true , nil
}
// GetReviews returns pull requests review
2021-08-22 01:47:45 +03:00
func ( r * RepositoryRestorer ) GetReviews ( context base . IssueContext ) ( [ ] * base . Review , error ) {
2022-01-20 20:46:10 +03:00
reviews := make ( [ ] * base . Review , 0 , 10 )
2021-08-22 01:47:45 +03:00
p := filepath . Join ( r . reviewDir ( ) , fmt . Sprintf ( "%d.yml" , context . ForeignID ( ) ) )
2020-12-27 06:34:19 +03:00
_ , err := os . Stat ( p )
if err != nil {
if os . IsNotExist ( err ) {
return nil , nil
}
return nil , err
}
2021-09-22 08:38:34 +03:00
bs , err := os . ReadFile ( p )
2020-12-27 06:34:19 +03:00
if err != nil {
return nil , err
}
err = yaml . Unmarshal ( bs , & reviews )
if err != nil {
return nil , err
}
return reviews , nil
}