You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gitrepo.go 2.9KB

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