Skip to content

Commit

Permalink
fix git repo
Browse files Browse the repository at this point in the history
  • Loading branch information
wxiaoguang committed Dec 22, 2024
1 parent 98a0b71 commit 396f6db
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 147 deletions.
2 changes: 1 addition & 1 deletion modules/gitrepo/gitrepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func RepositoryFromContextOrOpen(ctx context.Context, repo Repository) (*git.Rep

// RepositoryFromRequestContextOrOpen opens the repository at the given relative path in the provided request context
// The repo will be automatically closed when the request context is done
func RepositoryFromRequestContextOrOpen(ctx *reqctx.RequestContext, repo Repository) (*git.Repository, error) {
func RepositoryFromRequestContextOrOpen(ctx reqctx.RequestContext, repo Repository) (*git.Repository, error) {
ck := contextKey{repoPath: repoPath(repo)}
if gitRepo, ok := ctx.Value(ck).(*git.Repository); ok {
return gitRepo, nil
Expand Down
43 changes: 28 additions & 15 deletions modules/reqctx/reqctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package reqctx

import (
"context"
"io"
"sync"
"time"

Expand All @@ -15,8 +16,16 @@ type RequestContextKeyType struct{}

var RequestContextKey RequestContextKeyType

type RequestContext interface {
context.Context
SetContextValue(k, v any)
GetData() ContextData
AddCleanUp(f func())
AddCloser(c io.Closer)
}

// RequestContext is a short-lived context that is used to store request-specific data.
type RequestContext struct {
type requestContext struct {
ctx context.Context
data ContextData

Expand All @@ -26,19 +35,19 @@ type RequestContext struct {
cleanUpFuncs []func()
}

func (r *RequestContext) Deadline() (deadline time.Time, ok bool) {
func (r *requestContext) Deadline() (deadline time.Time, ok bool) {
return r.ctx.Deadline()
}

func (r *RequestContext) Done() <-chan struct{} {
func (r *requestContext) Done() <-chan struct{} {
return r.ctx.Done()
}

func (r *RequestContext) Err() error {
func (r *requestContext) Err() error {
return r.ctx.Err()
}

func (r *RequestContext) Value(key any) any {
func (r *requestContext) Value(key any) any {
if key == RequestContextKey {
return r
}
Expand All @@ -51,42 +60,46 @@ func (r *RequestContext) Value(key any) any {
return r.ctx.Value(key)
}

func (r *RequestContext) SetContextValue(k, v any) {
func (r *requestContext) SetContextValue(k, v any) {
r.mu.Lock()
r.values[k] = v
r.mu.Unlock()
}

// GetData and the underlying ContextData are not thread-safe, callers should ensure thread-safety.
func (r *RequestContext) GetData() ContextData {
func (r *requestContext) GetData() ContextData {
if r.data == nil {
r.data = make(ContextData)
}
return r.data
}

func (r *RequestContext) AddCleanUp(f func()) {
func (r *requestContext) AddCleanUp(f func()) {
r.mu.Lock()
r.cleanUpFuncs = append(r.cleanUpFuncs, f)
r.mu.Unlock()
}

func (r *RequestContext) cleanUp() {
func (r *requestContext) AddCloser(c io.Closer) {
r.AddCleanUp(func() { _ = c.Close() })
}

func (r *requestContext) cleanUp() {
for _, f := range r.cleanUpFuncs {
f()
}
}

func GetRequestContext(ctx context.Context) *RequestContext {
if req, ok := ctx.Value(RequestContextKey).(*RequestContext); ok {
func GetRequestContext(ctx context.Context) RequestContext {
if req, ok := ctx.Value(RequestContextKey).(*requestContext); ok {
return req
}
return nil
}

func NewRequestContext(parentCtx context.Context, profDesc string) (_ *RequestContext, finished func()) {
func NewRequestContext(parentCtx context.Context, profDesc string) (_ RequestContext, finished func()) {
ctx, _, processFinished := process.GetManager().AddTypedContext(parentCtx, profDesc, process.RequestProcessType, true)
reqCtx := &RequestContext{ctx: ctx, values: make(map[any]any)}
reqCtx := &requestContext{ctx: ctx, values: make(map[any]any)}
return reqCtx, func() {
reqCtx.cleanUp()
processFinished()
Expand All @@ -95,7 +108,7 @@ func NewRequestContext(parentCtx context.Context, profDesc string) (_ *RequestCo

// NewRequestContextForTest creates a new RequestContext for testing purposes
// It doesn't add the context to the process manager, nor do cleanup
func NewRequestContextForTest(parentCtx context.Context) *RequestContext {
reqCtx := &RequestContext{ctx: parentCtx, values: make(map[any]any)}
func NewRequestContextForTest(parentCtx context.Context) RequestContext {
reqCtx := &requestContext{ctx: parentCtx, values: make(map[any]any)}
return reqCtx
}
10 changes: 1 addition & 9 deletions routers/api/v1/repo/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,15 +729,11 @@ func CreateBranchProtection(ctx *context.APIContext) {
} else {
if !isPlainRule {
if ctx.Repo.GitRepo == nil {
ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
}
defer func() {
ctx.Repo.GitRepo.Close()
ctx.Repo.GitRepo = nil
}()
}
// FIXME: since we only need to recheck files protected rules, we could improve this
matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.Repository.ID, ruleName)
Expand Down Expand Up @@ -1066,10 +1062,6 @@ func EditBranchProtection(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
}
defer func() {
ctx.Repo.GitRepo.Close()
ctx.Repo.GitRepo = nil
}()
}

// FIXME: since we only need to recheck files protected rules, we could improve this
Expand Down
5 changes: 2 additions & 3 deletions routers/api/v1/repo/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ func CompareDiff(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"

if ctx.Repo.GitRepo == nil {
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
}
ctx.Repo.GitRepo = gitRepo
defer gitRepo.Close()
}

infoPath := ctx.PathParam("*")
Expand Down
5 changes: 2 additions & 3 deletions routers/api/v1/repo/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@ func DownloadArchive(ctx *context.APIContext) {
}

if ctx.Repo.GitRepo == nil {
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
}
ctx.Repo.GitRepo = gitRepo
defer gitRepo.Close()
}

r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"), tp)
Expand Down
5 changes: 2 additions & 3 deletions routers/api/v1/repo/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,12 @@ func GetArchive(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"

if ctx.Repo.GitRepo == nil {
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
}
ctx.Repo.GitRepo = gitRepo
defer gitRepo.Close()
}

archiveDownload(ctx)
Expand Down
3 changes: 1 addition & 2 deletions routers/api/v1/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,12 +726,11 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err

if ctx.Repo.GitRepo == nil && !repo.IsEmpty {
var err error
ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, repo)
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, repo)
if err != nil {
ctx.Error(http.StatusInternalServerError, "Unable to OpenRepository", err)
return err
}
defer ctx.Repo.GitRepo.Close()
}

// Default branch only updated if changed and exist or the repository is empty
Expand Down
2 changes: 1 addition & 1 deletion routers/api/v1/repo/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func Transfer(ctx *context.APIContext) {
}

if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
_ = ctx.Repo.GitRepo.Close()
ctx.Repo.GitRepo = nil
}

Expand Down
18 changes: 4 additions & 14 deletions routers/private/internal_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package private

import (
"context"
"fmt"
"net/http"

Expand All @@ -18,14 +17,14 @@ import (
// This file contains common functions relating to setting the Repository for the internal routes

// RepoAssignment assigns the repository and gitrepository to the private context
func RepoAssignment(ctx *gitea_context.PrivateContext) context.CancelFunc {
func RepoAssignment(ctx *gitea_context.PrivateContext) {
ownerName := ctx.PathParam(":owner")
repoName := ctx.PathParam(":repo")

repo := loadRepository(ctx, ownerName, repoName)
if ctx.Written() {
// Error handled in loadRepository
return nil
return
}

gitRepo, err := gitrepo.OpenRepository(ctx, repo)
Expand All @@ -34,23 +33,14 @@ func RepoAssignment(ctx *gitea_context.PrivateContext) context.CancelFunc {
ctx.JSON(http.StatusInternalServerError, private.Response{
Err: fmt.Sprintf("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err),
})
return nil
return
}

ctx.Repo = &gitea_context.Repository{
Repository: repo,
GitRepo: gitRepo,
}

// We opened it, we should close it
cancel := func() {
// If it's been set to nil then assume someone else has closed it.
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
}

return cancel
ctx.AddCloser(gitRepo) // We opened it, we should close it
}

func loadRepository(ctx *gitea_context.PrivateContext, ownerName, repoName string) *repo_model.Repository {
Expand Down
13 changes: 6 additions & 7 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package web

import (
gocontext "context"
"net/http"
"strings"

Expand Down Expand Up @@ -1521,24 +1520,24 @@ func registerRoutes(m *web.Router) {

m.Group("/blob_excerpt", func() {
m.Get("/{sha}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob)
}, func(ctx *context.Context) gocontext.CancelFunc {
}, func(ctx *context.Context) {
// FIXME: refactor this function, use separate routes for wiki/code
if ctx.FormBool("wiki") {
ctx.Data["PageIsWiki"] = true
repo.MustEnableWiki(ctx)
return nil
return
}

if ctx.Written() {
return nil
return
}
cancel := context.RepoRef()(ctx)
context.RepoRef()(ctx)
if ctx.Written() {
return cancel
return
}

repo.MustBeNotEmpty(ctx)
return cancel
return

Check failure on line 1540 in routers/web/web.go

View workflow job for this annotation

GitHub Actions / lint-backend

S1023: redundant `return` statement (gosimple)

Check failure on line 1540 in routers/web/web.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

S1023: redundant `return` statement (gosimple)

Check failure on line 1540 in routers/web/web.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

S1023: redundant `return` statement (gosimple)
})

m.Group("/media", func() {
Expand Down
22 changes: 7 additions & 15 deletions services/context/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package context

import (
"context"
"fmt"
"net/http"
"net/url"
Expand Down Expand Up @@ -265,31 +264,24 @@ func (ctx *APIContext) NotFound(objs ...any) {

// ReferencesGitRepo injects the GitRepo into the Context
// you can optional skip the IsEmpty check
func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) (cancel context.CancelFunc) {
return func(ctx *APIContext) (cancel context.CancelFunc) {
func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) {
return func(ctx *APIContext) {
// Empty repository does not have reference information.
if ctx.Repo.Repository.IsEmpty && !(len(allowEmpty) != 0 && allowEmpty[0]) {
return nil
return
}

// For API calls.
if ctx.Repo.GitRepo == nil {
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, fmt.Sprintf("Open Repository %v failed", ctx.Repo.Repository.FullName()), err)
return cancel
}
ctx.Repo.GitRepo = gitRepo
// We opened it, we should close it
return func() {
// If it's been set to nil then assume someone else has closed it.
if ctx.Repo.GitRepo != nil {
_ = ctx.Repo.GitRepo.Close()
}
return
}
}

return cancel
return

Check failure on line 284 in services/context/api.go

View workflow job for this annotation

GitHub Actions / lint-backend

S1023: redundant `return` statement (gosimple)

Check failure on line 284 in services/context/api.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

S1023: redundant `return` statement (gosimple)

Check failure on line 284 in services/context/api.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

S1023: redundant `return` statement (gosimple)
}
}

Expand Down
Loading

0 comments on commit 396f6db

Please sign in to comment.