Monorepo for Tangled tangled.org

appview/repo: allow viewing unreachable repos

instead of showing a 503 indiscriminately, we now indicate that the knot
is unreachable and display a warning. the user is still free to browse
issues and pulls.

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li 15a45ae1 7615cf12

verified
+39 -22
+5
appview/pages/pages.go
··· 697 Languages []types.RepoLanguageDetails 698 Pipelines map[string]models.Pipeline 699 NeedsKnotUpgrade bool 700 types.RepoIndexResponse 701 } 702 ··· 708 709 if params.NeedsKnotUpgrade { 710 return p.executeRepo("repo/needsUpgrade", w, params) 711 } 712 713 p.rctx.RepoInfo = params.RepoInfo
··· 697 Languages []types.RepoLanguageDetails 698 Pipelines map[string]models.Pipeline 699 NeedsKnotUpgrade bool 700 + KnotUnreachable bool 701 types.RepoIndexResponse 702 } 703 ··· 709 710 if params.NeedsKnotUpgrade { 711 return p.executeRepo("repo/needsUpgrade", w, params) 712 + } 713 + 714 + if params.KnotUnreachable { 715 + return p.executeRepo("repo/knotUnreachable", w, params) 716 } 717 718 p.rctx.RepoInfo = params.RepoInfo
+18
appview/pages/templates/repo/knotUnreachable.html
···
··· 1 + {{ define "title" }}{{ .RepoInfo.FullName }}{{ end }} 2 + {{ define "extrameta" }} 3 + {{ template "repo/fragments/meta" . }} 4 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }} 5 + {{ end }} 6 + {{ define "repoContent" }} 7 + <main> 8 + <div class="relative w-full h-96 flex items-center justify-center"> 9 + <div class="absolute inset-0 flex items-center justify-center py-12 text-red-500 dark:text-red-400 backdrop-blur"> 10 + <div class="text-center"> 11 + {{ i "triangle-alert" "size-5 inline-flex items-center align-middle" }} 12 + The knot hosting this repository is unreachable. 13 + </div> 14 + </div> 15 + </div> 16 + </main> 17 + {{ end }} 18 +
+14 -16
appview/repo/index.go
··· 64 RepoInfo: rp.repoResolver.GetRepoInfo(r, user), 65 }) 66 return 67 } 68 - 69 - rp.pages.Error503(w) 70 - l.Error("failed to build index response", "err", err) 71 - return 72 } 73 74 tagMap := make(map[string][]string) ··· 299 ) 300 301 // tags 302 - wg.Add(1) 303 - go func() { 304 - defer wg.Done() 305 tagsBytes, err := tangled.RepoTags(ctx, xrpcc, "", 0, didSlashRepo) 306 if err != nil { 307 errs = errors.Join(errs, fmt.Errorf("failed to call repoTags: %w", err)) ··· 311 if err := json.Unmarshal(tagsBytes, &tagsResp); err != nil { 312 errs = errors.Join(errs, fmt.Errorf("failed to unmarshal repoTags: %w", err)) 313 } 314 - }() 315 316 // tree/files 317 - wg.Add(1) 318 - go func() { 319 - defer wg.Done() 320 resp, err := tangled.RepoTree(ctx, xrpcc, "", ref, didSlashRepo) 321 if err != nil { 322 errs = errors.Join(errs, fmt.Errorf("failed to call repoTree: %w", err)) 323 return 324 } 325 treeResp = resp 326 - }() 327 328 // commits 329 - wg.Add(1) 330 - go func() { 331 - defer wg.Done() 332 logBytes, err := tangled.RepoLog(ctx, xrpcc, "", 50, "", ref, didSlashRepo) 333 if err != nil { 334 errs = errors.Join(errs, fmt.Errorf("failed to call repoLog: %w", err)) ··· 338 if err := json.Unmarshal(logBytes, &logResp); err != nil { 339 errs = errors.Join(errs, fmt.Errorf("failed to unmarshal repoLog: %w", err)) 340 } 341 - }() 342 343 wg.Wait() 344
··· 64 RepoInfo: rp.repoResolver.GetRepoInfo(r, user), 65 }) 66 return 67 + } else { 68 + l.Error("failed to build index response", "err", err) 69 + rp.pages.RepoIndexPage(w, pages.RepoIndexParams{ 70 + LoggedInUser: user, 71 + KnotUnreachable: true, 72 + RepoInfo: rp.repoResolver.GetRepoInfo(r, user), 73 + }) 74 + return 75 } 76 } 77 78 tagMap := make(map[string][]string) ··· 303 ) 304 305 // tags 306 + wg.Go(func() { 307 tagsBytes, err := tangled.RepoTags(ctx, xrpcc, "", 0, didSlashRepo) 308 if err != nil { 309 errs = errors.Join(errs, fmt.Errorf("failed to call repoTags: %w", err)) ··· 313 if err := json.Unmarshal(tagsBytes, &tagsResp); err != nil { 314 errs = errors.Join(errs, fmt.Errorf("failed to unmarshal repoTags: %w", err)) 315 } 316 + }) 317 318 // tree/files 319 + wg.Go(func() { 320 resp, err := tangled.RepoTree(ctx, xrpcc, "", ref, didSlashRepo) 321 if err != nil { 322 errs = errors.Join(errs, fmt.Errorf("failed to call repoTree: %w", err)) 323 return 324 } 325 treeResp = resp 326 + }) 327 328 // commits 329 + wg.Go(func() { 330 logBytes, err := tangled.RepoLog(ctx, xrpcc, "", 50, "", ref, didSlashRepo) 331 if err != nil { 332 errs = errors.Join(errs, fmt.Errorf("failed to call repoLog: %w", err)) ··· 336 if err := json.Unmarshal(logBytes, &logResp); err != nil { 337 errs = errors.Join(errs, fmt.Errorf("failed to unmarshal repoLog: %w", err)) 338 } 339 + }) 340 341 wg.Wait() 342
+2 -6
appview/repo/settings.go
··· 190 191 repo := fmt.Sprintf("%s/%s", f.Did, f.Name) 192 xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 193 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 194 l.Error("failed to call XRPC repo.branches", "err", xrpcerr) 195 - rp.pages.Error503(w) 196 - return 197 - } 198 - 199 - var result types.RepoBranchesResponse 200 - if err := json.Unmarshal(xrpcBytes, &result); err != nil { 201 l.Error("failed to decode XRPC response", "err", err) 202 rp.pages.Error503(w) 203 return
··· 190 191 repo := fmt.Sprintf("%s/%s", f.Did, f.Name) 192 xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 193 + var result types.RepoBranchesResponse 194 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 195 l.Error("failed to call XRPC repo.branches", "err", xrpcerr) 196 + } else if err := json.Unmarshal(xrpcBytes, &result); err != nil { 197 l.Error("failed to decode XRPC response", "err", err) 198 rp.pages.Error503(w) 199 return