summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2022-01-19 23:26:57 +0000
committerGitHub <noreply@github.com>2022-01-19 23:26:57 +0000
commit5cb0c9aa0d7eed087055b1efca79628957207d36 (patch)
treed117a514e1f17e5f6bfcda1be273f6a971112663 /models
parent4563148a61ba892e8f2bb66342f00a950bcd5315 (diff)
downloadgitea-5cb0c9aa0d7eed087055b1efca79628957207d36.tar.gz
gitea-5cb0c9aa0d7eed087055b1efca79628957207d36.zip
Propagate context and ensure git commands run in request context (#17868)
This PR continues the work in #17125 by progressively ensuring that git commands run within the request context. This now means that the if there is a git repo already open in the context it will be used instead of reopening it. Signed-off-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'models')
-rw-r--r--models/admin/notice.go8
-rw-r--r--models/db/context.go7
-rwxr-xr-xmodels/db/engine.go1
-rw-r--r--models/issue_comment.go25
-rw-r--r--models/issue_comment_test.go5
-rw-r--r--models/issue_xref_test.go2
-rw-r--r--models/migrations/v136.go3
-rw-r--r--models/migrations/v156.go2
-rw-r--r--models/migrations/v82.go2
-rw-r--r--models/pull.go3
-rw-r--r--models/repo/repo.go3
-rw-r--r--models/repo_activity.go13
-rw-r--r--models/review.go20
-rw-r--r--models/review_test.go11
14 files changed, 57 insertions, 48 deletions
diff --git a/models/admin/notice.go b/models/admin/notice.go
index 2d71b426dd..daf095f680 100644
--- a/models/admin/notice.go
+++ b/models/admin/notice.go
@@ -56,6 +56,7 @@ func CreateNotice(ctx context.Context, tp NoticeType, desc string, args ...inter
// CreateRepositoryNotice creates new system notice with type NoticeRepository.
func CreateRepositoryNotice(desc string, args ...interface{}) error {
+ // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled
return CreateNotice(db.DefaultContext, NoticeRepository, desc, args...)
}
@@ -65,7 +66,8 @@ func RemoveAllWithNotice(ctx context.Context, title, path string) {
if err := util.RemoveAll(path); err != nil {
desc := fmt.Sprintf("%s [%s]: %v", title, path, err)
log.Warn(title+" [%s]: %v", path, err)
- if err = CreateNotice(ctx, NoticeRepository, desc); err != nil {
+ // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled
+ if err = CreateNotice(db.DefaultContext, NoticeRepository, desc); err != nil {
log.Error("CreateRepositoryNotice: %v", err)
}
}
@@ -77,7 +79,9 @@ func RemoveStorageWithNotice(ctx context.Context, bucket storage.ObjectStorage,
if err := bucket.Delete(path); err != nil {
desc := fmt.Sprintf("%s [%s]: %v", title, path, err)
log.Warn(title+" [%s]: %v", path, err)
- if err = CreateNotice(ctx, NoticeRepository, desc); err != nil {
+
+ // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled
+ if err = CreateNotice(db.DefaultContext, NoticeRepository, desc); err != nil {
log.Error("CreateRepositoryNotice: %v", err)
}
}
diff --git a/models/db/context.go b/models/db/context.go
index 55e38ba7e5..833c26ff6c 100644
--- a/models/db/context.go
+++ b/models/db/context.go
@@ -35,7 +35,7 @@ type Context struct {
func WithEngine(ctx context.Context, e Engine) *Context {
return &Context{
Context: ctx,
- e: e,
+ e: e.Context(ctx),
}
}
@@ -52,6 +52,11 @@ func (ctx *Context) Value(key interface{}) interface{} {
return ctx.Context.Value(key)
}
+// WithContext returns this engine tied to this context
+func (ctx *Context) WithContext(other context.Context) *Context {
+ return WithEngine(other, ctx.e)
+}
+
// Engined structs provide an Engine
type Engined interface {
Engine() Engine
diff --git a/models/db/engine.go b/models/db/engine.go
index 63e1d5547a..665808d701 100755
--- a/models/db/engine.go
+++ b/models/db/engine.go
@@ -64,6 +64,7 @@ type Engine interface {
Distinct(...string) *xorm.Session
Query(...interface{}) ([]map[string][]byte, error)
Cols(...string) *xorm.Session
+ Context(ctx context.Context) *xorm.Session
}
// TableInfo returns table's information via an object
diff --git a/models/issue_comment.go b/models/issue_comment.go
index f4a6b3ce13..bf36881a00 100644
--- a/models/issue_comment.go
+++ b/models/issue_comment.go
@@ -724,7 +724,7 @@ func (c *Comment) CodeCommentURL() string {
}
// LoadPushCommits Load push commits
-func (c *Comment) LoadPushCommits() (err error) {
+func (c *Comment) LoadPushCommits(ctx context.Context) (err error) {
if c.Content == "" || c.Commits != nil || c.Type != CommentTypePullPush {
return nil
}
@@ -746,11 +746,11 @@ func (c *Comment) LoadPushCommits() (err error) {
c.NewCommit = data.CommitIDs[1]
} else {
repoPath := c.Issue.Repo.RepoPath()
- gitRepo, err := git.OpenRepository(repoPath)
+ gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repoPath)
if err != nil {
return err
}
- defer gitRepo.Close()
+ defer closer.Close()
c.Commits = ConvertFromGitCommit(gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo)
c.CommitsNum = int64(len(c.Commits))
@@ -1272,6 +1272,7 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
var err error
if comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
+ Ctx: ctx,
URLPrefix: issue.Repo.Link(),
Metas: issue.Repo.ComposeMetas(),
}, comment.Content); err != nil {
@@ -1282,19 +1283,19 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
}
// FetchCodeCommentsByLine fetches the code comments for a given treePath and line number
-func FetchCodeCommentsByLine(issue *Issue, currentUser *user_model.User, treePath string, line int64) ([]*Comment, error) {
+func FetchCodeCommentsByLine(ctx context.Context, issue *Issue, currentUser *user_model.User, treePath string, line int64) ([]*Comment, error) {
opts := FindCommentsOptions{
Type: CommentTypeCode,
IssueID: issue.ID,
TreePath: treePath,
Line: line,
}
- return findCodeComments(db.DefaultContext, opts, issue, currentUser, nil)
+ return findCodeComments(ctx, opts, issue, currentUser, nil)
}
// FetchCodeComments will return a 2d-map: ["Path"]["Line"] = Comments at line
-func FetchCodeComments(issue *Issue, currentUser *user_model.User) (CodeComments, error) {
- return fetchCodeComments(db.DefaultContext, issue, currentUser)
+func FetchCodeComments(ctx context.Context, issue *Issue, currentUser *user_model.User) (CodeComments, error) {
+ return fetchCodeComments(ctx, issue, currentUser)
}
// UpdateCommentsMigrationsByType updates comments' migrations information via given git service type and original id and poster id
@@ -1318,7 +1319,7 @@ func UpdateCommentsMigrationsByType(tp structs.GitServiceType, originalAuthorID
}
// CreatePushPullComment create push code to pull base comment
-func CreatePushPullComment(pusher *user_model.User, pr *PullRequest, oldCommitID, newCommitID string) (comment *Comment, err error) {
+func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *PullRequest, oldCommitID, newCommitID string) (comment *Comment, err error) {
if pr.HasMerged || oldCommitID == "" || newCommitID == "" {
return nil, nil
}
@@ -1331,7 +1332,7 @@ func CreatePushPullComment(pusher *user_model.User, pr *PullRequest, oldCommitID
var data PushActionContent
- data.CommitIDs, data.IsForcePush, err = getCommitIDsFromRepo(pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch)
+ data.CommitIDs, data.IsForcePush, err = getCommitIDsFromRepo(ctx, pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch)
if err != nil {
return nil, err
}
@@ -1353,13 +1354,13 @@ func CreatePushPullComment(pusher *user_model.User, pr *PullRequest, oldCommitID
// getCommitsFromRepo get commit IDs from repo in between oldCommitID and newCommitID
// isForcePush will be true if oldCommit isn't on the branch
// Commit on baseBranch will skip
-func getCommitIDsFromRepo(repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
+func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
repoPath := repo.RepoPath()
- gitRepo, err := git.OpenRepository(repoPath)
+ gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repoPath)
if err != nil {
return nil, false, err
}
- defer gitRepo.Close()
+ defer closer.Close()
oldCommit, err := gitRepo.GetCommit(oldCommitID)
if err != nil {
diff --git a/models/issue_comment_test.go b/models/issue_comment_test.go
index ec318688ee..d323a08167 100644
--- a/models/issue_comment_test.go
+++ b/models/issue_comment_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"time"
+ "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -49,7 +50,7 @@ func TestFetchCodeComments(t *testing.T) {
issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
- res, err := FetchCodeComments(issue, user)
+ res, err := FetchCodeComments(db.DefaultContext, issue, user)
assert.NoError(t, err)
assert.Contains(t, res, "README.md")
assert.Contains(t, res["README.md"], int64(4))
@@ -57,7 +58,7 @@ func TestFetchCodeComments(t *testing.T) {
assert.Equal(t, int64(4), res["README.md"][4][0].ID)
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- res, err = FetchCodeComments(issue, user2)
+ res, err = FetchCodeComments(db.DefaultContext, issue, user2)
assert.NoError(t, err)
assert.Len(t, res, 1)
}
diff --git a/models/issue_xref_test.go b/models/issue_xref_test.go
index 9b1cb5e2d5..1deeb44ad5 100644
--- a/models/issue_xref_test.go
+++ b/models/issue_xref_test.go
@@ -162,7 +162,7 @@ func testCreatePR(t *testing.T, repo, doer int64, title, content string) *PullRe
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
i := &Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true}
pr := &PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: PullRequestStatusMergeable}
- assert.NoError(t, NewPullRequest(r, i, nil, nil, pr))
+ assert.NoError(t, NewPullRequest(db.DefaultContext, r, i, nil, nil, pr))
pr.Issue = i
return pr
}
diff --git a/models/migrations/v136.go b/models/migrations/v136.go
index 101cf75955..94372e4142 100644
--- a/models/migrations/v136.go
+++ b/models/migrations/v136.go
@@ -12,6 +12,7 @@ import (
"time"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@@ -90,7 +91,7 @@ func addCommitDivergenceToPulls(x *xorm.Engine) error {
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
- divergence, err := git.GetDivergingCommits(repoPath, pr.BaseBranch, gitRefName)
+ divergence, err := git.GetDivergingCommits(graceful.GetManager().HammerContext(), repoPath, pr.BaseBranch, gitRefName)
if err != nil {
log.Warn("Could not recalculate Divergence for pull: %d", pr.ID)
pr.CommitsAhead = 0
diff --git a/models/migrations/v156.go b/models/migrations/v156.go
index 7158d7bb6b..77aed3ff57 100644
--- a/models/migrations/v156.go
+++ b/models/migrations/v156.go
@@ -109,7 +109,7 @@ func fixPublisherIDforTagReleases(x *xorm.Engine) error {
return err
}
}
- gitRepo, err = git.OpenRepository(repoPath(repo.OwnerName, repo.Name))
+ gitRepo, err = git.OpenRepositoryCtx(git.DefaultContext, repoPath(repo.OwnerName, repo.Name))
if err != nil {
log.Error("Error whilst opening git repo for [%d]%s/%s. Error: %v", repo.ID, repo.OwnerName, repo.Name, err)
return err
diff --git a/models/migrations/v82.go b/models/migrations/v82.go
index 67bb0cb8c9..7f9f979d95 100644
--- a/models/migrations/v82.go
+++ b/models/migrations/v82.go
@@ -99,7 +99,7 @@ func fixReleaseSha1OnReleaseTable(x *xorm.Engine) error {
userCache[repo.OwnerID] = user
}
- gitRepo, err = git.OpenRepository(RepoPath(user.Name, repo.Name))
+ gitRepo, err = git.OpenRepositoryCtx(git.DefaultContext, RepoPath(user.Name, repo.Name))
if err != nil {
return err
}
diff --git a/models/pull.go b/models/pull.go
index 243d40b1fa..d6bfbbf09f 100644
--- a/models/pull.go
+++ b/models/pull.go
@@ -436,7 +436,7 @@ func (pr *PullRequest) SetMerged() (bool, error) {
}
// NewPullRequest creates new pull request with labels for repository.
-func NewPullRequest(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
+func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
if err != nil {
return fmt.Errorf("generate pull request index failed: %v", err)
@@ -449,6 +449,7 @@ func NewPullRequest(repo *repo_model.Repository, issue *Issue, labelIDs []int64,
return err
}
defer committer.Close()
+ ctx.WithContext(outerCtx)
if err = newIssue(ctx, issue.Poster, NewIssueOptions{
Repo: repo,
diff --git a/models/repo/repo.go b/models/repo/repo.go
index 5108231cd8..a78d287315 100644
--- a/models/repo/repo.go
+++ b/models/repo/repo.go
@@ -485,8 +485,9 @@ func (repo *Repository) CanEnableEditor() bool {
}
// DescriptionHTML does special handles to description and return HTML string.
-func (repo *Repository) DescriptionHTML() template.HTML {
+func (repo *Repository) DescriptionHTML(ctx context.Context) template.HTML {
desc, err := markup.RenderDescriptionHTML(&markup.RenderContext{
+ Ctx: ctx,
URLPrefix: repo.HTMLURL(),
Metas: repo.ComposeMetas(),
}, repo.Description)
diff --git a/models/repo_activity.go b/models/repo_activity.go
index 5bdea80b97..7475be2b11 100644
--- a/models/repo_activity.go
+++ b/models/repo_activity.go
@@ -5,6 +5,7 @@
package models
import (
+ "context"
"fmt"
"sort"
"time"
@@ -43,7 +44,7 @@ type ActivityStats struct {
}
// GetActivityStats return stats for repository at given time range
-func GetActivityStats(repo *repo_model.Repository, timeFrom time.Time, releases, issues, prs, code bool) (*ActivityStats, error) {
+func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, releases, issues, prs, code bool) (*ActivityStats, error) {
stats := &ActivityStats{Code: &git.CodeActivityStats{}}
if releases {
if err := stats.FillReleases(repo.ID, timeFrom); err != nil {
@@ -64,11 +65,11 @@ func GetActivityStats(repo *repo_model.Repository, timeFrom time.Time, releases,
return nil, fmt.Errorf("FillUnresolvedIssues: %v", err)
}
if code {
- gitRepo, err := git.OpenRepository(repo.RepoPath())
+ gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
if err != nil {
return nil, fmt.Errorf("OpenRepository: %v", err)
}
- defer gitRepo.Close()
+ defer closer.Close()
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
if err != nil {
@@ -80,12 +81,12 @@ func GetActivityStats(repo *repo_model.Repository, timeFrom time.Time, releases,
}
// GetActivityStatsTopAuthors returns top author stats for git commits for all branches
-func GetActivityStatsTopAuthors(repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
- gitRepo, err := git.OpenRepository(repo.RepoPath())
+func GetActivityStatsTopAuthors(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
+ gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
if err != nil {
return nil, fmt.Errorf("OpenRepository: %v", err)
}
- defer gitRepo.Close()
+ defer closer.Close()
code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
if err != nil {
diff --git a/models/review.go b/models/review.go
index 88d0819089..8b0092b1ed 100644
--- a/models/review.go
+++ b/models/review.go
@@ -86,7 +86,8 @@ func init() {
db.RegisterModel(new(Review))
}
-func (r *Review) loadCodeComments(ctx context.Context) (err error) {
+// LoadCodeComments loads CodeComments
+func (r *Review) LoadCodeComments(ctx context.Context) (err error) {
if r.CodeComments != nil {
return
}
@@ -97,11 +98,6 @@ func (r *Review) loadCodeComments(ctx context.Context) (err error) {
return
}
-// LoadCodeComments loads CodeComments
-func (r *Review) LoadCodeComments() error {
- return r.loadCodeComments(db.DefaultContext)
-}
-
func (r *Review) loadIssue(e db.Engine) (err error) {
if r.Issue != nil {
return
@@ -137,12 +133,13 @@ func (r *Review) LoadReviewerTeam() error {
return r.loadReviewerTeam(db.GetEngine(db.DefaultContext))
}
-func (r *Review) loadAttributes(ctx context.Context) (err error) {
+// LoadAttributes loads all attributes except CodeComments
+func (r *Review) LoadAttributes(ctx context.Context) (err error) {
e := db.GetEngine(ctx)
if err = r.loadIssue(e); err != nil {
return
}
- if err = r.loadCodeComments(ctx); err != nil {
+ if err = r.LoadCodeComments(ctx); err != nil {
return
}
if err = r.loadReviewer(e); err != nil {
@@ -154,11 +151,6 @@ func (r *Review) loadAttributes(ctx context.Context) (err error) {
return
}
-// LoadAttributes loads all attributes except CodeComments
-func (r *Review) LoadAttributes() error {
- return r.loadAttributes(db.DefaultContext)
-}
-
func getReviewByID(e db.Engine, id int64) (*Review, error) {
review := new(Review)
if has, err := e.ID(id).Get(review); err != nil {
@@ -405,7 +397,7 @@ func SubmitReview(doer *user_model.User, issue *Issue, reviewType ReviewType, co
return nil, nil, err
}
} else {
- if err := review.loadCodeComments(ctx); err != nil {
+ if err := review.LoadCodeComments(ctx); err != nil {
return nil, nil, err
}
if reviewType != ReviewTypeApprove && len(review.CodeComments) == 0 && len(strings.TrimSpace(content)) == 0 {
diff --git a/models/review_test.go b/models/review_test.go
index b9d156ceb1..20810dac4a 100644
--- a/models/review_test.go
+++ b/models/review_test.go
@@ -7,6 +7,7 @@ package models
import (
"testing"
+ "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -28,23 +29,23 @@ func TestGetReviewByID(t *testing.T) {
func TestReview_LoadAttributes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
review := unittest.AssertExistsAndLoadBean(t, &Review{ID: 1}).(*Review)
- assert.NoError(t, review.LoadAttributes())
+ assert.NoError(t, review.LoadAttributes(db.DefaultContext))
assert.NotNil(t, review.Issue)
assert.NotNil(t, review.Reviewer)
invalidReview1 := unittest.AssertExistsAndLoadBean(t, &Review{ID: 2}).(*Review)
- assert.Error(t, invalidReview1.LoadAttributes())
+ assert.Error(t, invalidReview1.LoadAttributes(db.DefaultContext))
invalidReview2 := unittest.AssertExistsAndLoadBean(t, &Review{ID: 3}).(*Review)
- assert.Error(t, invalidReview2.LoadAttributes())
+ assert.Error(t, invalidReview2.LoadAttributes(db.DefaultContext))
}
func TestReview_LoadCodeComments(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
review := unittest.AssertExistsAndLoadBean(t, &Review{ID: 4}).(*Review)
- assert.NoError(t, review.LoadAttributes())
- assert.NoError(t, review.LoadCodeComments())
+ assert.NoError(t, review.LoadAttributes(db.DefaultContext))
+ assert.NoError(t, review.LoadCodeComments(db.DefaultContext))
assert.Len(t, review.CodeComments, 1)
assert.Equal(t, int64(4), review.CodeComments["README.md"][int64(4)][0].Line)
}