appview,knotserver: remove redundant call to DefaultBranch #513

merged
opened by oppi.li targeting master from push-xopyykmxuqzw
Changed files
+44 -76
appview
pages
repo
reporesolver
state
knotserver
+1
appview/pages/pages.go
··· 520 } 521 522 p.rctx.RepoInfo = params.RepoInfo 523 p.rctx.RendererType = markup.RendererTypeRepoMarkdown 524 525 if params.ReadmeFileName != "" {
··· 520 } 521 522 p.rctx.RepoInfo = params.RepoInfo 523 + p.rctx.RepoInfo.Ref = params.Ref 524 p.rctx.RendererType = markup.RendererTypeRepoMarkdown 525 526 if params.ReadmeFileName != "" {
+12 -9
appview/repo/index.go
··· 24 25 func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { 26 ref := chi.URLParam(r, "ref") 27 f, err := rp.repoResolver.Resolve(r) 28 if err != nil { 29 log.Println("failed to fully resolve repo", err) ··· 118 119 var forkInfo *types.ForkInfo 120 if user != nil && (repoInfo.Roles.IsOwner() || repoInfo.Roles.IsCollaborator()) { 121 - forkInfo, err = getForkInfo(repoInfo, rp, f, user, signedClient) 122 if err != nil { 123 log.Printf("Failed to fetch fork information: %v", err) 124 return ··· 126 } 127 128 // TODO: a bit dirty 129 - languageInfo, err := rp.getLanguageInfo(f, signedClient, chi.URLParam(r, "ref") == "") 130 if err != nil { 131 log.Printf("failed to compute language percentages: %s", err) 132 // non-fatal ··· 161 func (rp *Repo) getLanguageInfo( 162 f *reporesolver.ResolvedRepo, 163 signedClient *knotclient.SignedClient, 164 isDefaultRef bool, 165 ) ([]types.RepoLanguageDetails, error) { 166 // first attempt to fetch from db 167 langs, err := db.GetRepoLanguages( 168 rp.db, 169 db.FilterEq("repo_at", f.RepoAt()), 170 - db.FilterEq("ref", f.Ref), 171 ) 172 173 if err != nil || langs == nil { 174 // non-fatal, fetch langs from ks 175 - ls, err := signedClient.RepoLanguages(f.OwnerDid(), f.Name, f.Ref) 176 if err != nil { 177 return nil, err 178 } ··· 183 for l, s := range ls.Languages { 184 langs = append(langs, db.RepoLanguage{ 185 RepoAt: f.RepoAt(), 186 - Ref: f.Ref, 187 IsDefaultRef: isDefaultRef, 188 Language: l, 189 Bytes: s, ··· 234 repoInfo repoinfo.RepoInfo, 235 rp *Repo, 236 f *reporesolver.ResolvedRepo, 237 user *oauth.User, 238 signedClient *knotclient.SignedClient, 239 ) (*types.ForkInfo, error) { ··· 264 } 265 266 if !slices.ContainsFunc(result.Branches, func(branch types.Branch) bool { 267 - return branch.Name == f.Ref 268 }) { 269 forkInfo.Status = types.MissingBranch 270 return &forkInfo, nil 271 } 272 273 - newHiddenRefResp, err := signedClient.NewHiddenRef(user.Did, repoInfo.Name, f.Ref, f.Ref) 274 if err != nil || newHiddenRefResp.StatusCode != http.StatusNoContent { 275 log.Printf("failed to update tracking branch: %s", err) 276 return nil, err 277 } 278 279 - hiddenRef := fmt.Sprintf("hidden/%s/%s", f.Ref, f.Ref) 280 281 var status types.AncestorCheckResponse 282 - forkSyncableResp, err := signedClient.RepoForkAheadBehind(user.Did, string(f.RepoAt()), repoInfo.Name, f.Ref, hiddenRef) 283 if err != nil { 284 log.Printf("failed to check if fork is ahead/behind: %s", err) 285 return nil, err
··· 24 25 func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { 26 ref := chi.URLParam(r, "ref") 27 + 28 f, err := rp.repoResolver.Resolve(r) 29 if err != nil { 30 log.Println("failed to fully resolve repo", err) ··· 119 120 var forkInfo *types.ForkInfo 121 if user != nil && (repoInfo.Roles.IsOwner() || repoInfo.Roles.IsCollaborator()) { 122 + forkInfo, err = getForkInfo(repoInfo, rp, f, result.Ref, user, signedClient) 123 if err != nil { 124 log.Printf("Failed to fetch fork information: %v", err) 125 return ··· 127 } 128 129 // TODO: a bit dirty 130 + languageInfo, err := rp.getLanguageInfo(f, signedClient, result.Ref, ref == "") 131 if err != nil { 132 log.Printf("failed to compute language percentages: %s", err) 133 // non-fatal ··· 162 func (rp *Repo) getLanguageInfo( 163 f *reporesolver.ResolvedRepo, 164 signedClient *knotclient.SignedClient, 165 + currentRef string, 166 isDefaultRef bool, 167 ) ([]types.RepoLanguageDetails, error) { 168 // first attempt to fetch from db 169 langs, err := db.GetRepoLanguages( 170 rp.db, 171 db.FilterEq("repo_at", f.RepoAt()), 172 + db.FilterEq("ref", currentRef), 173 ) 174 175 if err != nil || langs == nil { 176 // non-fatal, fetch langs from ks 177 + ls, err := signedClient.RepoLanguages(f.OwnerDid(), f.Name, currentRef) 178 if err != nil { 179 return nil, err 180 } ··· 185 for l, s := range ls.Languages { 186 langs = append(langs, db.RepoLanguage{ 187 RepoAt: f.RepoAt(), 188 + Ref: currentRef, 189 IsDefaultRef: isDefaultRef, 190 Language: l, 191 Bytes: s, ··· 236 repoInfo repoinfo.RepoInfo, 237 rp *Repo, 238 f *reporesolver.ResolvedRepo, 239 + currentRef string, 240 user *oauth.User, 241 signedClient *knotclient.SignedClient, 242 ) (*types.ForkInfo, error) { ··· 267 } 268 269 if !slices.ContainsFunc(result.Branches, func(branch types.Branch) bool { 270 + return branch.Name == currentRef 271 }) { 272 forkInfo.Status = types.MissingBranch 273 return &forkInfo, nil 274 } 275 276 + newHiddenRefResp, err := signedClient.NewHiddenRef(user.Did, repoInfo.Name, currentRef, currentRef) 277 if err != nil || newHiddenRefResp.StatusCode != http.StatusNoContent { 278 log.Printf("failed to update tracking branch: %s", err) 279 return nil, err 280 } 281 282 + hiddenRef := fmt.Sprintf("hidden/%s/%s", currentRef, currentRef) 283 284 var status types.AncestorCheckResponse 285 + forkSyncableResp, err := signedClient.RepoForkAheadBehind(user.Did, string(f.RepoAt()), repoInfo.Name, currentRef, hiddenRef) 286 if err != nil { 287 log.Printf("failed to check if fork is ahead/behind: %s", err) 288 return nil, err
+3 -1
appview/repo/repo.go
··· 1315 } 1316 1317 func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) { 1318 user := rp.oauth.GetUser(r) 1319 f, err := rp.repoResolver.Resolve(r) 1320 if err != nil { ··· 1345 forkName := fmt.Sprintf("%s", f.Name) 1346 forkSourceUrl := fmt.Sprintf("%s://%s/%s/%s", uri, f.Knot, f.OwnerDid(), f.Repo.Name) 1347 1348 - _, err = client.SyncRepoFork(user.Did, forkSourceUrl, forkName, f.Ref) 1349 if err != nil { 1350 rp.pages.Notice(w, "repo", "Failed to sync repository fork.") 1351 return
··· 1315 } 1316 1317 func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) { 1318 + ref := chi.URLParam(r, "ref") 1319 + 1320 user := rp.oauth.GetUser(r) 1321 f, err := rp.repoResolver.Resolve(r) 1322 if err != nil { ··· 1347 forkName := fmt.Sprintf("%s", f.Name) 1348 forkSourceUrl := fmt.Sprintf("%s://%s/%s/%s", uri, f.Knot, f.OwnerDid(), f.Repo.Name) 1349 1350 + _, err = client.SyncRepoFork(user.Did, forkSourceUrl, forkName, ref) 1351 if err != nil { 1352 rp.pages.Notice(w, "repo", "Failed to sync repository fork.") 1353 return
+18 -39
appview/reporesolver/resolver.go
··· 7 "fmt" 8 "log" 9 "net/http" 10 - "net/url" 11 "path" 12 "strings" 13 14 "github.com/bluesky-social/indigo/atproto/identity" ··· 26 27 type ResolvedRepo struct { 28 db.Repo 29 - OwnerId identity.Identity 30 - Ref string 31 - CurrentDir string 32 33 rr *RepoResolver 34 } ··· 56 return nil, fmt.Errorf("malformed middleware") 57 } 58 59 ref := chi.URLParam(r, "ref") 60 61 - if ref == "" { 62 - us, err := knotclient.NewUnsignedClient(repo.Knot, rr.config.Core.Dev) 63 - if err != nil { 64 - return nil, err 65 - } 66 - 67 - defaultBranch, err := us.DefaultBranch(id.DID.String(), repo.Name) 68 - if err != nil { 69 - return nil, err 70 - } 71 - 72 - ref = defaultBranch.Branch 73 - } 74 - 75 - currentDir := path.Dir(extractPathAfterRef(r.URL.EscapedPath(), ref)) 76 - 77 return &ResolvedRepo{ 78 Repo: *repo, 79 OwnerId: id, 80 - Ref: ref, 81 CurrentDir: currentDir, 82 83 rr: rr, 84 }, nil ··· 200 if err != nil { 201 log.Printf("failed to create unsigned client for %s: %v", knot, err) 202 } else { 203 - result, err := us.Branches(f.OwnerDid(), f.Name) 204 - if err != nil { 205 log.Printf("failed to get branches for %s/%s: %v", f.OwnerDid(), f.Name, err) 206 - } 207 - 208 - if len(result.Branches) == 0 { 209 disableFork = true 210 } 211 } ··· 216 Name: f.Name, 217 RepoAt: repoAt, 218 Description: f.Description, 219 - Ref: f.Ref, 220 IsStarred: isStarred, 221 Knot: knot, 222 Spindle: f.Spindle, ··· 228 }, 229 DisableFork: disableFork, 230 CurrentDir: f.CurrentDir, 231 } 232 233 if sourceRepo != nil { ··· 251 // after the ref. for example: 252 // 253 // /@icyphox.sh/foorepo/blob/main/abc/xyz/ => abc/xyz/ 254 - func extractPathAfterRef(fullPath, ref string) string { 255 fullPath = strings.TrimPrefix(fullPath, "/") 256 257 - ref = url.PathEscape(ref) 258 259 - prefixes := []string{ 260 - fmt.Sprintf("blob/%s/", ref), 261 - fmt.Sprintf("tree/%s/", ref), 262 - fmt.Sprintf("raw/%s/", ref), 263 - } 264 265 - for _, prefix := range prefixes { 266 - idx := strings.Index(fullPath, prefix) 267 - if idx != -1 { 268 - return fullPath[idx+len(prefix):] 269 - } 270 } 271 272 return ""
··· 7 "fmt" 8 "log" 9 "net/http" 10 "path" 11 + "regexp" 12 "strings" 13 14 "github.com/bluesky-social/indigo/atproto/identity" ··· 26 27 type ResolvedRepo struct { 28 db.Repo 29 + OwnerId identity.Identity 30 + CurrentDir string 31 + Ref string 32 33 rr *RepoResolver 34 } ··· 56 return nil, fmt.Errorf("malformed middleware") 57 } 58 59 + currentDir := path.Dir(extractPathAfterRef(r.URL.EscapedPath())) 60 ref := chi.URLParam(r, "ref") 61 62 return &ResolvedRepo{ 63 Repo: *repo, 64 OwnerId: id, 65 CurrentDir: currentDir, 66 + Ref: ref, 67 68 rr: rr, 69 }, nil ··· 185 if err != nil { 186 log.Printf("failed to create unsigned client for %s: %v", knot, err) 187 } else { 188 + if result, err := us.Branches(f.OwnerDid(), f.Name); err != nil { 189 log.Printf("failed to get branches for %s/%s: %v", f.OwnerDid(), f.Name, err) 190 + } else if len(result.Branches) == 0 { 191 disableFork = true 192 } 193 } ··· 198 Name: f.Name, 199 RepoAt: repoAt, 200 Description: f.Description, 201 IsStarred: isStarred, 202 Knot: knot, 203 Spindle: f.Spindle, ··· 209 }, 210 DisableFork: disableFork, 211 CurrentDir: f.CurrentDir, 212 + Ref: f.Ref, 213 } 214 215 if sourceRepo != nil { ··· 233 // after the ref. for example: 234 // 235 // /@icyphox.sh/foorepo/blob/main/abc/xyz/ => abc/xyz/ 236 + func extractPathAfterRef(fullPath string) string { 237 fullPath = strings.TrimPrefix(fullPath, "/") 238 239 + // match blob/, tree/, or raw/ followed by any ref and then a slash 240 + // 241 + // captures everything after the final slash 242 + pattern := `(?:blob|tree|raw)/[^/]+/(.*)$` 243 244 + re := regexp.MustCompile(pattern) 245 + matches := re.FindStringSubmatch(fullPath) 246 247 + if len(matches) > 1 { 248 + return matches[1] 249 } 250 251 return ""
-19
appview/state/profile.go
··· 89 log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err) 90 } 91 92 - var didsToResolve []string 93 - for _, r := range collaboratingRepos { 94 - didsToResolve = append(didsToResolve, r.Did) 95 - } 96 - for _, byMonth := range timeline.ByMonth { 97 - for _, pe := range byMonth.PullEvents.Items { 98 - didsToResolve = append(didsToResolve, pe.Repo.Did) 99 - } 100 - for _, ie := range byMonth.IssueEvents.Items { 101 - didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did) 102 - } 103 - for _, re := range byMonth.RepoEvents { 104 - didsToResolve = append(didsToResolve, re.Repo.Did) 105 - if re.Source != nil { 106 - didsToResolve = append(didsToResolve, re.Source.Did) 107 - } 108 - } 109 - } 110 - 111 followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String()) 112 if err != nil { 113 log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
··· 89 log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err) 90 } 91 92 followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String()) 93 if err != nil { 94 log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
+4 -2
knotserver/git/fork.go
··· 27 return nil 28 } 29 30 - func (g *GitRepo) Sync(branch string) error { 31 fetchOpts := &git.FetchOptions{ 32 RefSpecs: []config.RefSpec{ 33 - config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/heads/%s", branch, branch)), 34 }, 35 } 36
··· 27 return nil 28 } 29 30 + func (g *GitRepo) Sync() error { 31 + branch := g.h.String() 32 + 33 fetchOpts := &git.FetchOptions{ 34 RefSpecs: []config.RefSpec{ 35 + config.RefSpec("+" + branch + ":" + branch), // +refs/heads/master:refs/heads/master 36 }, 37 } 38
+2 -2
knotserver/handler.go
··· 142 r.Delete("/", h.RemoveRepo) 143 r.Route("/fork", func(r chi.Router) { 144 r.Post("/", h.RepoFork) 145 - r.Post("/sync/{branch}", h.RepoForkSync) 146 - r.Get("/sync/{branch}", h.RepoForkAheadBehind) 147 }) 148 }) 149
··· 142 r.Delete("/", h.RemoveRepo) 143 r.Route("/fork", func(r chi.Router) { 144 r.Post("/", h.RepoFork) 145 + r.Post("/sync/*", h.RepoForkSync) 146 + r.Get("/sync/*", h.RepoForkAheadBehind) 147 }) 148 }) 149
+4 -4
knotserver/routes.go
··· 710 } 711 712 func (h *Handle) RepoForkAheadBehind(w http.ResponseWriter, r *http.Request) { 713 - l := h.l.With("handler", "RepoForkSync") 714 715 data := struct { 716 Did string `json:"did"` ··· 845 name = filepath.Base(source) 846 } 847 848 - branch := chi.URLParam(r, "branch") 849 branch, _ = url.PathUnescape(branch) 850 851 relativeRepoPath := filepath.Join(did, name) 852 repoPath, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, relativeRepoPath) 853 854 - gr, err := git.PlainOpen(repoPath) 855 if err != nil { 856 log.Println(err) 857 notFound(w) 858 return 859 } 860 861 - err = gr.Sync(branch) 862 if err != nil { 863 l.Error("error syncing repo fork", "error", err.Error()) 864 writeError(w, err.Error(), http.StatusInternalServerError)
··· 710 } 711 712 func (h *Handle) RepoForkAheadBehind(w http.ResponseWriter, r *http.Request) { 713 + l := h.l.With("handler", "RepoForkAheadBehind") 714 715 data := struct { 716 Did string `json:"did"` ··· 845 name = filepath.Base(source) 846 } 847 848 + branch := chi.URLParam(r, "*") 849 branch, _ = url.PathUnescape(branch) 850 851 relativeRepoPath := filepath.Join(did, name) 852 repoPath, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, relativeRepoPath) 853 854 + gr, err := git.Open(repoPath, branch) 855 if err != nil { 856 log.Println(err) 857 notFound(w) 858 return 859 } 860 861 + err = gr.Sync() 862 if err != nil { 863 l.Error("error syncing repo fork", "error", err.Error()) 864 writeError(w, err.Error(), http.StatusInternalServerError)