code.gitea.io/gitea@v1.22.3/modules/gitrepo/gitrepo.go (about)

     1  // Copyright 2024 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package gitrepo
     5  
     6  import (
     7  	"context"
     8  	"io"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"code.gitea.io/gitea/modules/git"
    13  	"code.gitea.io/gitea/modules/setting"
    14  )
    15  
    16  type Repository interface {
    17  	GetName() string
    18  	GetOwnerName() string
    19  }
    20  
    21  func repoPath(repo Repository) string {
    22  	return filepath.Join(setting.RepoRootPath, strings.ToLower(repo.GetOwnerName()), strings.ToLower(repo.GetName())+".git")
    23  }
    24  
    25  func wikiPath(repo Repository) string {
    26  	return filepath.Join(setting.RepoRootPath, strings.ToLower(repo.GetOwnerName()), strings.ToLower(repo.GetName())+".wiki.git")
    27  }
    28  
    29  // OpenRepository opens the repository at the given relative path with the provided context.
    30  func OpenRepository(ctx context.Context, repo Repository) (*git.Repository, error) {
    31  	return git.OpenRepository(ctx, repoPath(repo))
    32  }
    33  
    34  func OpenWikiRepository(ctx context.Context, repo Repository) (*git.Repository, error) {
    35  	return git.OpenRepository(ctx, wikiPath(repo))
    36  }
    37  
    38  // contextKey is a value for use with context.WithValue.
    39  type contextKey struct {
    40  	name string
    41  }
    42  
    43  // RepositoryContextKey is a context key. It is used with context.Value() to get the current Repository for the context
    44  var RepositoryContextKey = &contextKey{"repository"}
    45  
    46  // RepositoryFromContext attempts to get the repository from the context
    47  func repositoryFromContext(ctx context.Context, repo Repository) *git.Repository {
    48  	value := ctx.Value(RepositoryContextKey)
    49  	if value == nil {
    50  		return nil
    51  	}
    52  
    53  	if gitRepo, ok := value.(*git.Repository); ok && gitRepo != nil {
    54  		if gitRepo.Path == repoPath(repo) {
    55  			return gitRepo
    56  		}
    57  	}
    58  
    59  	return nil
    60  }
    61  
    62  type nopCloser func()
    63  
    64  func (nopCloser) Close() error { return nil }
    65  
    66  // RepositoryFromContextOrOpen attempts to get the repository from the context or just opens it
    67  func RepositoryFromContextOrOpen(ctx context.Context, repo Repository) (*git.Repository, io.Closer, error) {
    68  	gitRepo := repositoryFromContext(ctx, repo)
    69  	if gitRepo != nil {
    70  		return gitRepo, nopCloser(nil), nil
    71  	}
    72  
    73  	gitRepo, err := OpenRepository(ctx, repo)
    74  	return gitRepo, gitRepo, err
    75  }
    76  
    77  // repositoryFromContextPath attempts to get the repository from the context
    78  func repositoryFromContextPath(ctx context.Context, path string) *git.Repository {
    79  	value := ctx.Value(RepositoryContextKey)
    80  	if value == nil {
    81  		return nil
    82  	}
    83  
    84  	if repo, ok := value.(*git.Repository); ok && repo != nil {
    85  		if repo.Path == path {
    86  			return repo
    87  		}
    88  	}
    89  
    90  	return nil
    91  }
    92  
    93  // RepositoryFromContextOrOpenPath attempts to get the repository from the context or just opens it
    94  // Deprecated: Use RepositoryFromContextOrOpen instead
    95  func RepositoryFromContextOrOpenPath(ctx context.Context, path string) (*git.Repository, io.Closer, error) {
    96  	gitRepo := repositoryFromContextPath(ctx, path)
    97  	if gitRepo != nil {
    98  		return gitRepo, nopCloser(nil), nil
    99  	}
   100  
   101  	gitRepo, err := git.OpenRepository(ctx, path)
   102  	return gitRepo, gitRepo, err
   103  }