mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 06:21:11 +00:00 
			
		
		
		
	- Massive replacement of changing `code.gitea.io/gitea` to `forgejo.org`. - Resolves forgejo/discussions#258 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7337 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Michael Kriese <michael.kriese@gmx.de> Reviewed-by: Beowulf <beowulf@beocode.eu> Reviewed-by: Panagiotis "Ivory" Vasilopoulos <git@n0toose.net> Co-authored-by: Gusted <postmaster@gusted.xyz> Co-committed-by: Gusted <postmaster@gusted.xyz>
		
			
				
	
	
		
			322 lines
		
	
	
	
		
			9.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			322 lines
		
	
	
	
		
			9.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright Earl Warren <contact@earl-warren.org>
 | |
| // Copyright Loïc Dachary <loic@dachary.org>
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package driver
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"time"
 | |
| 
 | |
| 	"forgejo.org/models/db"
 | |
| 	issues_model "forgejo.org/models/issues"
 | |
| 	repo_model "forgejo.org/models/repo"
 | |
| 	user_model "forgejo.org/models/user"
 | |
| 	"forgejo.org/modules/git"
 | |
| 	"forgejo.org/modules/timeutil"
 | |
| 	issue_service "forgejo.org/services/issue"
 | |
| 
 | |
| 	"code.forgejo.org/f3/gof3/v3/f3"
 | |
| 	f3_id "code.forgejo.org/f3/gof3/v3/id"
 | |
| 	f3_path "code.forgejo.org/f3/gof3/v3/path"
 | |
| 	f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
 | |
| 	"code.forgejo.org/f3/gof3/v3/tree/generic"
 | |
| 	f3_util "code.forgejo.org/f3/gof3/v3/util"
 | |
| )
 | |
| 
 | |
| var _ f3_tree.ForgeDriverInterface = &pullRequest{}
 | |
| 
 | |
| type pullRequest struct {
 | |
| 	common
 | |
| 
 | |
| 	forgejoPullRequest *issues_model.Issue
 | |
| 	headRepository     *f3.Reference
 | |
| 	baseRepository     *f3.Reference
 | |
| 	fetchFunc          f3.PullRequestFetchFunc
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) SetNative(pullRequest any) {
 | |
| 	o.forgejoPullRequest = pullRequest.(*issues_model.Issue)
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) GetNativeID() string {
 | |
| 	return fmt.Sprintf("%d", o.forgejoPullRequest.Index)
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) NewFormat() f3.Interface {
 | |
| 	node := o.GetNode()
 | |
| 	return node.GetTree().(f3_tree.TreeInterface).NewFormat(node.GetKind())
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) repositoryToReference(ctx context.Context, repository *repo_model.Repository) *f3.Reference {
 | |
| 	if repository == nil {
 | |
| 		panic("unexpected nil repository")
 | |
| 	}
 | |
| 	forge := o.getTree().GetRoot().GetChild(f3_id.NewNodeID(f3_tree.KindForge)).GetDriver().(*forge)
 | |
| 	owners := forge.getOwnersPath(ctx, fmt.Sprintf("%d", repository.OwnerID))
 | |
| 	return f3_tree.NewRepositoryReference(owners.String(), repository.OwnerID, repository.ID)
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) referenceToRepository(reference *f3.Reference) int64 {
 | |
| 	var project int64
 | |
| 	if reference.Get() == "../../repository/vcs" {
 | |
| 		project = f3_tree.GetProjectID(o.GetNode())
 | |
| 	} else {
 | |
| 		p := f3_tree.ToPath(f3_path.PathAbsolute(generic.NewElementNode, o.GetNode().GetCurrentPath().String(), reference.Get()))
 | |
| 		o.Trace("%v %v", o.GetNode().GetCurrentPath().String(), p)
 | |
| 		_, project = p.OwnerAndProjectID()
 | |
| 	}
 | |
| 	return project
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) ToFormat() f3.Interface {
 | |
| 	if o.forgejoPullRequest == nil {
 | |
| 		return o.NewFormat()
 | |
| 	}
 | |
| 
 | |
| 	var milestone *f3.Reference
 | |
| 	if o.forgejoPullRequest.Milestone != nil {
 | |
| 		milestone = f3_tree.NewIssueMilestoneReference(o.forgejoPullRequest.Milestone.ID)
 | |
| 	}
 | |
| 
 | |
| 	var mergedTime *time.Time
 | |
| 	if o.forgejoPullRequest.PullRequest.HasMerged {
 | |
| 		mergedTime = o.forgejoPullRequest.PullRequest.MergedUnix.AsTimePtr()
 | |
| 	}
 | |
| 
 | |
| 	var closedTime *time.Time
 | |
| 	if o.forgejoPullRequest.IsClosed {
 | |
| 		closedTime = o.forgejoPullRequest.ClosedUnix.AsTimePtr()
 | |
| 	}
 | |
| 
 | |
| 	makePullRequestBranch := func(repo *repo_model.Repository, branch string) f3.PullRequestBranch {
 | |
| 		r, err := git.OpenRepository(context.Background(), repo.RepoPath())
 | |
| 		if err != nil {
 | |
| 			panic(err)
 | |
| 		}
 | |
| 		defer r.Close()
 | |
| 
 | |
| 		b, err := r.GetBranch(branch)
 | |
| 		if err != nil {
 | |
| 			panic(err)
 | |
| 		}
 | |
| 
 | |
| 		c, err := b.GetCommit()
 | |
| 		if err != nil {
 | |
| 			panic(err)
 | |
| 		}
 | |
| 
 | |
| 		return f3.PullRequestBranch{
 | |
| 			Ref: branch,
 | |
| 			SHA: c.ID.String(),
 | |
| 		}
 | |
| 	}
 | |
| 	if err := o.forgejoPullRequest.PullRequest.LoadHeadRepo(db.DefaultContext); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	head := makePullRequestBranch(o.forgejoPullRequest.PullRequest.HeadRepo, o.forgejoPullRequest.PullRequest.HeadBranch)
 | |
| 	head.Repository = o.headRepository
 | |
| 	if err := o.forgejoPullRequest.PullRequest.LoadBaseRepo(db.DefaultContext); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	base := makePullRequestBranch(o.forgejoPullRequest.PullRequest.BaseRepo, o.forgejoPullRequest.PullRequest.BaseBranch)
 | |
| 	base.Repository = o.baseRepository
 | |
| 
 | |
| 	return &f3.PullRequest{
 | |
| 		Common:         f3.NewCommon(o.GetNativeID()),
 | |
| 		PosterID:       f3_tree.NewUserReference(o.forgejoPullRequest.Poster.ID),
 | |
| 		Title:          o.forgejoPullRequest.Title,
 | |
| 		Content:        o.forgejoPullRequest.Content,
 | |
| 		Milestone:      milestone,
 | |
| 		State:          string(o.forgejoPullRequest.State()),
 | |
| 		IsLocked:       o.forgejoPullRequest.IsLocked,
 | |
| 		Created:        o.forgejoPullRequest.CreatedUnix.AsTime(),
 | |
| 		Updated:        o.forgejoPullRequest.UpdatedUnix.AsTime(),
 | |
| 		Closed:         closedTime,
 | |
| 		Merged:         o.forgejoPullRequest.PullRequest.HasMerged,
 | |
| 		MergedTime:     mergedTime,
 | |
| 		MergeCommitSHA: o.forgejoPullRequest.PullRequest.MergedCommitID,
 | |
| 		Head:           head,
 | |
| 		Base:           base,
 | |
| 		FetchFunc:      o.fetchFunc,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) FromFormat(content f3.Interface) {
 | |
| 	pullRequest := content.(*f3.PullRequest)
 | |
| 	var milestone *issues_model.Milestone
 | |
| 	if pullRequest.Milestone != nil {
 | |
| 		milestone = &issues_model.Milestone{
 | |
| 			ID: pullRequest.Milestone.GetIDAsInt(),
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	o.headRepository = pullRequest.Head.Repository
 | |
| 	o.baseRepository = pullRequest.Base.Repository
 | |
| 	pr := issues_model.PullRequest{
 | |
| 		HeadBranch: pullRequest.Head.Ref,
 | |
| 		HeadRepoID: o.referenceToRepository(o.headRepository),
 | |
| 		BaseBranch: pullRequest.Base.Ref,
 | |
| 		BaseRepoID: o.referenceToRepository(o.baseRepository),
 | |
| 
 | |
| 		MergeBase: pullRequest.Base.SHA,
 | |
| 		Index:     f3_util.ParseInt(pullRequest.GetID()),
 | |
| 		HasMerged: pullRequest.Merged,
 | |
| 	}
 | |
| 
 | |
| 	o.forgejoPullRequest = &issues_model.Issue{
 | |
| 		Index:    f3_util.ParseInt(pullRequest.GetID()),
 | |
| 		PosterID: pullRequest.PosterID.GetIDAsInt(),
 | |
| 		Poster: &user_model.User{
 | |
| 			ID: pullRequest.PosterID.GetIDAsInt(),
 | |
| 		},
 | |
| 		Title:       pullRequest.Title,
 | |
| 		Content:     pullRequest.Content,
 | |
| 		Milestone:   milestone,
 | |
| 		IsClosed:    pullRequest.State == f3.PullRequestStateClosed,
 | |
| 		CreatedUnix: timeutil.TimeStamp(pullRequest.Created.Unix()),
 | |
| 		UpdatedUnix: timeutil.TimeStamp(pullRequest.Updated.Unix()),
 | |
| 		IsLocked:    pullRequest.IsLocked,
 | |
| 		PullRequest: &pr,
 | |
| 		IsPull:      true,
 | |
| 	}
 | |
| 
 | |
| 	if pullRequest.Closed != nil {
 | |
| 		o.forgejoPullRequest.ClosedUnix = timeutil.TimeStamp(pullRequest.Closed.Unix())
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) Get(ctx context.Context) bool {
 | |
| 	node := o.GetNode()
 | |
| 	o.Trace("%s", node.GetID())
 | |
| 
 | |
| 	project := f3_tree.GetProjectID(o.GetNode())
 | |
| 	id := node.GetID().Int64()
 | |
| 
 | |
| 	issue, err := issues_model.GetIssueByIndex(ctx, project, id)
 | |
| 	if issues_model.IsErrIssueNotExist(err) {
 | |
| 		return false
 | |
| 	}
 | |
| 	if err != nil {
 | |
| 		panic(fmt.Errorf("issue %v %w", id, err))
 | |
| 	}
 | |
| 	if err := issue.LoadAttributes(ctx); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	if err := issue.PullRequest.LoadHeadRepo(ctx); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	o.headRepository = o.repositoryToReference(ctx, issue.PullRequest.HeadRepo)
 | |
| 	if err := issue.PullRequest.LoadBaseRepo(ctx); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	o.baseRepository = o.repositoryToReference(ctx, issue.PullRequest.BaseRepo)
 | |
| 
 | |
| 	o.forgejoPullRequest = issue
 | |
| 	o.Trace("ID = %s", o.forgejoPullRequest.ID)
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) Patch(ctx context.Context) {
 | |
| 	node := o.GetNode()
 | |
| 	project := f3_tree.GetProjectID(o.GetNode())
 | |
| 	id := node.GetID().Int64()
 | |
| 	o.Trace("repo_id = %d, index = %d", project, id)
 | |
| 	if _, err := db.GetEngine(ctx).Where("`repo_id` = ? AND `index` = ?", project, id).Cols("name", "content").Update(o.forgejoPullRequest); err != nil {
 | |
| 		panic(fmt.Errorf("%v %v", o.forgejoPullRequest, err))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) GetPullRequestPushRefs() []string {
 | |
| 	return []string{
 | |
| 		fmt.Sprintf("refs/f3/%s/head", o.GetNativeID()),
 | |
| 		fmt.Sprintf("refs/pull/%s/head", o.GetNativeID()),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) GetPullRequestRef() string {
 | |
| 	return fmt.Sprintf("refs/pull/%s/head", o.GetNativeID())
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) Put(ctx context.Context) f3_id.NodeID {
 | |
| 	node := o.GetNode()
 | |
| 	o.Trace("%s", node.GetID())
 | |
| 
 | |
| 	o.forgejoPullRequest.RepoID = f3_tree.GetProjectID(o.GetNode())
 | |
| 
 | |
| 	ctx, committer, err := db.TxContext(ctx)
 | |
| 	if err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	defer committer.Close()
 | |
| 
 | |
| 	idx, err := db.GetNextResourceIndex(ctx, "issue_index", o.forgejoPullRequest.RepoID)
 | |
| 	if err != nil {
 | |
| 		panic(fmt.Errorf("generate issue index failed: %w", err))
 | |
| 	}
 | |
| 	o.forgejoPullRequest.Index = idx
 | |
| 
 | |
| 	sess := db.GetEngine(ctx)
 | |
| 
 | |
| 	if _, err = sess.NoAutoTime().Insert(o.forgejoPullRequest); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 
 | |
| 	pr := o.forgejoPullRequest.PullRequest
 | |
| 	pr.Index = o.forgejoPullRequest.Index
 | |
| 	pr.IssueID = o.forgejoPullRequest.ID
 | |
| 	pr.HeadRepoID = o.referenceToRepository(o.headRepository)
 | |
| 	if pr.HeadRepoID == 0 {
 | |
| 		panic(fmt.Errorf("HeadRepoID == 0 in %v", pr))
 | |
| 	}
 | |
| 	pr.BaseRepoID = o.referenceToRepository(o.baseRepository)
 | |
| 	if pr.BaseRepoID == 0 {
 | |
| 		panic(fmt.Errorf("BaseRepoID == 0 in %v", pr))
 | |
| 	}
 | |
| 
 | |
| 	if _, err = sess.NoAutoTime().Insert(pr); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 
 | |
| 	if err = committer.Commit(); err != nil {
 | |
| 		panic(fmt.Errorf("Commit: %w", err))
 | |
| 	}
 | |
| 
 | |
| 	if err := pr.LoadBaseRepo(ctx); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	if err := pr.LoadHeadRepo(ctx); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 
 | |
| 	o.Trace("pullRequest created %d/%d", o.forgejoPullRequest.ID, o.forgejoPullRequest.Index)
 | |
| 	return f3_id.NewNodeID(o.forgejoPullRequest.Index)
 | |
| }
 | |
| 
 | |
| func (o *pullRequest) Delete(ctx context.Context) {
 | |
| 	node := o.GetNode()
 | |
| 	o.Trace("%s", node.GetID())
 | |
| 
 | |
| 	owner := f3_tree.GetOwnerName(o.GetNode())
 | |
| 	project := f3_tree.GetProjectName(o.GetNode())
 | |
| 	repoPath := repo_model.RepoPath(owner, project)
 | |
| 	gitRepo, err := git.OpenRepository(ctx, repoPath)
 | |
| 	if err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	defer gitRepo.Close()
 | |
| 
 | |
| 	doer, err := user_model.GetAdminUser(ctx)
 | |
| 	if err != nil {
 | |
| 		panic(fmt.Errorf("GetAdminUser %w", err))
 | |
| 	}
 | |
| 
 | |
| 	if err := issue_service.DeleteIssue(ctx, doer, gitRepo, o.forgejoPullRequest); err != nil {
 | |
| 		panic(err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func newPullRequest() generic.NodeDriverInterface {
 | |
| 	return &pullRequest{}
 | |
| }
 |