this repo has no description
1package reporesolver 2 3import ( 4 "fmt" 5 "log" 6 "net/http" 7 "path" 8 "regexp" 9 "strings" 10 11 "github.com/bluesky-social/indigo/atproto/identity" 12 "github.com/go-chi/chi/v5" 13 "tangled.org/core/appview/config" 14 "tangled.org/core/appview/db" 15 "tangled.org/core/appview/models" 16 "tangled.org/core/appview/oauth" 17 "tangled.org/core/appview/pages/repoinfo" 18 "tangled.org/core/rbac" 19) 20 21type ResolvedRepo struct { 22 models.Repo 23 OwnerId identity.Identity 24 CurrentDir string 25 Ref string 26 27 rr *RepoResolver 28} 29 30type RepoResolver struct { 31 config *config.Config 32 enforcer *rbac.Enforcer 33 execer db.Execer 34} 35 36func New(config *config.Config, enforcer *rbac.Enforcer, execer db.Execer) *RepoResolver { 37 return &RepoResolver{config: config, enforcer: enforcer, execer: execer} 38} 39 40// NOTE: this... should not even be here. the entire package will be removed in future refactor 41func GetBaseRepoPath(r *http.Request, repo *models.Repo) string { 42 var ( 43 user = chi.URLParam(r, "user") 44 name = chi.URLParam(r, "repo") 45 ) 46 if user == "" || name == "" { 47 return repo.DidSlashRepo() 48 } 49 return path.Join(user, name) 50} 51 52func (rr *RepoResolver) Resolve(r *http.Request) (*ResolvedRepo, error) { 53 repo, ok := r.Context().Value("repo").(*models.Repo) 54 if !ok { 55 log.Println("malformed middleware: `repo` not exist in context") 56 return nil, fmt.Errorf("malformed middleware") 57 } 58 id, ok := r.Context().Value("resolvedId").(identity.Identity) 59 if !ok { 60 log.Println("malformed middleware") 61 return nil, fmt.Errorf("malformed middleware") 62 } 63 64 currentDir := path.Dir(extractPathAfterRef(r.URL.EscapedPath())) 65 ref := chi.URLParam(r, "ref") 66 67 return &ResolvedRepo{ 68 Repo: *repo, 69 OwnerId: id, 70 CurrentDir: currentDir, 71 Ref: ref, 72 73 rr: rr, 74 }, nil 75} 76 77// this function is a bit weird since it now returns RepoInfo from an entirely different 78// package. we should refactor this or get rid of RepoInfo entirely. 79func (f *ResolvedRepo) RepoInfo(user *oauth.User) repoinfo.RepoInfo { 80 repoAt := f.RepoAt() 81 isStarred := false 82 roles := repoinfo.RolesInRepo{} 83 if user != nil { 84 isStarred = db.GetStarStatus(f.rr.execer, user.Did, repoAt) 85 roles.Roles = f.rr.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo()) 86 } 87 88 stats := f.RepoStats 89 if stats == nil { 90 starCount, err := db.GetStarCount(f.rr.execer, repoAt) 91 if err != nil { 92 log.Println("failed to get star count for ", repoAt) 93 } 94 issueCount, err := db.GetIssueCount(f.rr.execer, repoAt) 95 if err != nil { 96 log.Println("failed to get issue count for ", repoAt) 97 } 98 pullCount, err := db.GetPullCount(f.rr.execer, repoAt) 99 if err != nil { 100 log.Println("failed to get pull count for ", repoAt) 101 } 102 stats = &models.RepoStats{ 103 StarCount: starCount, 104 IssueCount: issueCount, 105 PullCount: pullCount, 106 } 107 } 108 109 sourceRepo, err := db.GetRepoSourceRepo(f.rr.execer, repoAt) 110 if err != nil { 111 log.Println("failed to get repo by at uri", err) 112 } 113 114 repoInfo := repoinfo.RepoInfo{ 115 // this is basically a models.Repo 116 OwnerDid: f.OwnerId.DID.String(), 117 OwnerHandle: f.OwnerId.Handle.String(), 118 Name: f.Name, 119 Rkey: f.Rkey, 120 Description: f.Description, 121 Website: f.Website, 122 Topics: f.Topics, 123 Knot: f.Knot, 124 Spindle: f.Spindle, 125 Stats: *stats, 126 127 // fork repo upstream 128 Source: sourceRepo, 129 130 CurrentDir: f.CurrentDir, 131 Ref: f.Ref, 132 133 // info related to the session 134 IsStarred: isStarred, 135 Roles: roles, 136 } 137 138 return repoInfo 139} 140 141// extractPathAfterRef gets the actual repository path 142// after the ref. for example: 143// 144// /@icyphox.sh/foorepo/blob/main/abc/xyz/ => abc/xyz/ 145func extractPathAfterRef(fullPath string) string { 146 fullPath = strings.TrimPrefix(fullPath, "/") 147 148 // match blob/, tree/, or raw/ followed by any ref and then a slash 149 // 150 // captures everything after the final slash 151 pattern := `(?:blob|tree|raw)/[^/]+/(.*)$` 152 153 re := regexp.MustCompile(pattern) 154 matches := re.FindStringSubmatch(fullPath) 155 156 if len(matches) > 1 { 157 return matches[1] 158 } 159 160 return "" 161}