Skip to content

Commit 87c5bb8

Browse files
committed
fix git repo
1 parent 98a0b71 commit 87c5bb8

File tree

23 files changed

+251
-278
lines changed

23 files changed

+251
-278
lines changed

modules/gitrepo/gitrepo.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ type contextKey struct {
4444

4545
// RepositoryFromContextOrOpen attempts to get the repository from the context or just opens it
4646
func RepositoryFromContextOrOpen(ctx context.Context, repo Repository) (*git.Repository, io.Closer, error) {
47-
reqCtx := reqctx.GetRequestContext(ctx)
48-
if reqCtx != nil {
49-
gitRepo, err := RepositoryFromRequestContextOrOpen(reqCtx, repo)
47+
ds := reqctx.GetRequestDataStore(ctx)
48+
if ds != nil {
49+
gitRepo, err := RepositoryFromRequestContextOrOpen(ctx, ds, repo)
5050
return gitRepo, util.NopCloser{}, err
5151
}
5252
gitRepo, err := OpenRepository(ctx, repo)
@@ -55,7 +55,7 @@ func RepositoryFromContextOrOpen(ctx context.Context, repo Repository) (*git.Rep
5555

5656
// RepositoryFromRequestContextOrOpen opens the repository at the given relative path in the provided request context
5757
// The repo will be automatically closed when the request context is done
58-
func RepositoryFromRequestContextOrOpen(ctx *reqctx.RequestContext, repo Repository) (*git.Repository, error) {
58+
func RepositoryFromRequestContextOrOpen(ctx context.Context, ds reqctx.RequestDataStore, repo Repository) (*git.Repository, error) {
5959
ck := contextKey{repoPath: repoPath(repo)}
6060
if gitRepo, ok := ctx.Value(ck).(*git.Repository); ok {
6161
return gitRepo, nil
@@ -64,9 +64,9 @@ func RepositoryFromRequestContextOrOpen(ctx *reqctx.RequestContext, repo Reposit
6464
if err != nil {
6565
return nil, err
6666
}
67-
ctx.AddCleanUp(func() {
67+
ds.AddCleanUp(func() {
6868
gitRepo.Close()
6969
})
70-
ctx.SetContextValue(ck, gitRepo)
70+
ds.SetContextValue(ck, gitRepo)
7171
return gitRepo, nil
7272
}

modules/reqctx/ctxdata.go

-21
This file was deleted.

modules/reqctx/datastore.go

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package reqctx
5+
6+
import (
7+
"context"
8+
"io"
9+
"sync"
10+
11+
"code.gitea.io/gitea/modules/process"
12+
)
13+
14+
type ContextDataProvider interface {
15+
GetData() ContextData
16+
}
17+
18+
type ContextData map[string]any
19+
20+
func (ds ContextData) GetData() ContextData {
21+
return ds
22+
}
23+
24+
func (ds ContextData) MergeFrom(other ContextData) ContextData {
25+
for k, v := range other {
26+
ds[k] = v
27+
}
28+
return ds
29+
}
30+
31+
// RequestDataStore is a short-lived context-related object that is used to store request-specific data.
32+
type RequestDataStore interface {
33+
GetData() ContextData
34+
SetContextValue(k, v any)
35+
GetContextValue(key any) any
36+
AddCleanUp(f func())
37+
AddCloser(c io.Closer)
38+
}
39+
40+
type requestDataStoreKeyType struct{}
41+
42+
var RequestDataStoreKey requestDataStoreKeyType
43+
44+
type requestDataStore struct {
45+
data ContextData
46+
47+
mu sync.RWMutex
48+
values map[any]any
49+
50+
cleanUpFuncs []func()
51+
}
52+
53+
func (r *requestDataStore) GetContextValue(key any) any {
54+
if key == RequestDataStoreKey {
55+
return r
56+
}
57+
r.mu.RLock()
58+
if v, ok := r.values[key]; ok {
59+
r.mu.RUnlock()
60+
return v
61+
}
62+
r.mu.RUnlock()
63+
return nil
64+
}
65+
66+
func (r *requestDataStore) SetContextValue(k, v any) {
67+
r.mu.Lock()
68+
r.values[k] = v
69+
r.mu.Unlock()
70+
}
71+
72+
// GetData and the underlying ContextData are not thread-safe, callers should ensure thread-safety.
73+
func (r *requestDataStore) GetData() ContextData {
74+
if r.data == nil {
75+
r.data = make(ContextData)
76+
}
77+
return r.data
78+
}
79+
80+
func (r *requestDataStore) AddCleanUp(f func()) {
81+
r.mu.Lock()
82+
r.cleanUpFuncs = append(r.cleanUpFuncs, f)
83+
r.mu.Unlock()
84+
}
85+
86+
func (r *requestDataStore) AddCloser(c io.Closer) {
87+
r.AddCleanUp(func() { _ = c.Close() })
88+
}
89+
90+
func (r *requestDataStore) cleanUp() {
91+
for _, f := range r.cleanUpFuncs {
92+
f()
93+
}
94+
}
95+
96+
func GetRequestDataStore(ctx context.Context) RequestDataStore {
97+
if req, ok := ctx.Value(RequestDataStoreKey).(*requestDataStore); ok {
98+
return req
99+
}
100+
return nil
101+
}
102+
103+
type requestContext struct {
104+
context.Context
105+
dataStore *requestDataStore
106+
}
107+
108+
func (c *requestContext) Value(key any) any {
109+
if key == RequestDataStoreKey {
110+
return c.dataStore
111+
}
112+
if v := c.dataStore.GetContextValue(key); v != nil {
113+
return v
114+
}
115+
return c.Context.Value(key)
116+
}
117+
118+
func NewRequestContext(parentCtx context.Context, profDesc string) (_ context.Context, finished func()) {
119+
ctx, _, processFinished := process.GetManager().AddTypedContext(parentCtx, profDesc, process.RequestProcessType, true)
120+
reqCtx := &requestContext{Context: ctx, dataStore: &requestDataStore{values: make(map[any]any)}}
121+
return reqCtx, func() {
122+
reqCtx.dataStore.cleanUp()
123+
processFinished()
124+
}
125+
}
126+
127+
// NewRequestContextForTest creates a new RequestContext for testing purposes
128+
// It doesn't add the context to the process manager, nor do cleanup
129+
func NewRequestContextForTest(parentCtx context.Context) context.Context {
130+
return &requestContext{Context: parentCtx, dataStore: &requestDataStore{values: make(map[any]any)}}
131+
}

modules/reqctx/reqctx.go

-101
This file was deleted.

modules/web/middleware/data.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
const ContextDataKeySignedUser = "SignedUser"
1515

1616
func GetContextData(c context.Context) reqctx.ContextData {
17-
if rc := reqctx.GetRequestContext(c); rc != nil {
17+
if rc := reqctx.GetRequestDataStore(c); rc != nil {
1818
return rc.GetData()
1919
}
2020
return nil

modules/web/middleware/flash.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
// Flash represents a one time data transfer between two requests.
1515
type Flash struct {
16-
DataStore reqctx.ContextDataStore
16+
DataStore reqctx.RequestDataStore
1717
url.Values
1818
ErrorMsg, WarningMsg, InfoMsg, SuccessMsg string
1919
}

modules/web/route.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ func Bind[T any](_ T) http.HandlerFunc {
3030
}
3131

3232
// SetForm set the form object
33-
func SetForm(dataStore reqctx.ContextDataStore, obj any) {
33+
func SetForm(dataStore reqctx.ContextDataProvider, obj any) {
3434
dataStore.GetData()["__form"] = obj
3535
}
3636

3737
// GetForm returns the validate form information
38-
func GetForm(dataStore reqctx.ContextDataStore) any {
38+
func GetForm(dataStore reqctx.RequestDataStore) any {
3939
return dataStore.GetData()["__form"]
4040
}
4141

routers/api/v1/repo/branch.go

+2-10
Original file line numberDiff line numberDiff line change
@@ -729,15 +729,11 @@ func CreateBranchProtection(ctx *context.APIContext) {
729729
} else {
730730
if !isPlainRule {
731731
if ctx.Repo.GitRepo == nil {
732-
ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
732+
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
733733
if err != nil {
734734
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
735735
return
736736
}
737-
defer func() {
738-
ctx.Repo.GitRepo.Close()
739-
ctx.Repo.GitRepo = nil
740-
}()
741737
}
742738
// FIXME: since we only need to recheck files protected rules, we could improve this
743739
matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.Repository.ID, ruleName)
@@ -1061,15 +1057,11 @@ func EditBranchProtection(ctx *context.APIContext) {
10611057
} else {
10621058
if !isPlainRule {
10631059
if ctx.Repo.GitRepo == nil {
1064-
ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
1060+
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
10651061
if err != nil {
10661062
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
10671063
return
10681064
}
1069-
defer func() {
1070-
ctx.Repo.GitRepo.Close()
1071-
ctx.Repo.GitRepo = nil
1072-
}()
10731065
}
10741066

10751067
// FIXME: since we only need to recheck files protected rules, we could improve this

routers/api/v1/repo/compare.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,12 @@ func CompareDiff(ctx *context.APIContext) {
4444
// "$ref": "#/responses/notFound"
4545

4646
if ctx.Repo.GitRepo == nil {
47-
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
47+
var err error
48+
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
4849
if err != nil {
4950
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
5051
return
5152
}
52-
ctx.Repo.GitRepo = gitRepo
53-
defer gitRepo.Close()
5453
}
5554

5655
infoPath := ctx.PathParam("*")

routers/api/v1/repo/download.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,12 @@ func DownloadArchive(ctx *context.APIContext) {
2828
}
2929

3030
if ctx.Repo.GitRepo == nil {
31-
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
31+
var err error
32+
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx, ctx.Repo.Repository)
3233
if err != nil {
3334
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
3435
return
3536
}
36-
ctx.Repo.GitRepo = gitRepo
37-
defer gitRepo.Close()
3837
}
3938

4039
r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"), tp)

0 commit comments

Comments
 (0)