Monorepo for Tangled tangled.org

appview: pages/markup: resolve relative links

+43
appview/pages/markup/markdown.go
··· 3 4 import ( 5 "bytes" 6 7 "github.com/yuin/goldmark" 8 "github.com/yuin/goldmark/extension" 9 "github.com/yuin/goldmark/parser" 10 ) 11 12 func RenderMarkdown(source string) string { ··· 22 } 23 return buf.String() 24 }
··· 3 4 import ( 5 "bytes" 6 + "fmt" 7 8 "github.com/yuin/goldmark" 9 + "github.com/yuin/goldmark/ast" 10 "github.com/yuin/goldmark/extension" 11 "github.com/yuin/goldmark/parser" 12 + "github.com/yuin/goldmark/text" 13 + "github.com/yuin/goldmark/util" 14 ) 15 16 func RenderMarkdown(source string) string { ··· 26 } 27 return buf.String() 28 } 29 + 30 + type RelativeLinkTransformer struct { 31 + User string 32 + Repo string 33 + Ref string 34 + } 35 + 36 + func (t *RelativeLinkTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) { 37 + ast.Walk(node, func(n ast.Node, entering bool) (ast.WalkStatus, error) { 38 + if !entering { 39 + fmt.Printf("Node: %T\n", n) 40 + } 41 + return ast.WalkContinue, nil 42 + }) 43 + } 44 + 45 + func RenderMarkdownExtended(source, user, repo, ref string) string { 46 + md := goldmark.New( 47 + goldmark.WithExtensions(extension.GFM), 48 + goldmark.WithParserOptions(parser.WithAutoHeadingID()), 49 + goldmark.WithParser( 50 + parser.NewParser( 51 + parser.WithASTTransformers( 52 + util.Prioritized(&RelativeLinkTransformer{ 53 + User: user, 54 + Repo: repo, 55 + Ref: ref, 56 + }, 999), 57 + ), 58 + ), 59 + ), 60 + ) 61 + 62 + var buf bytes.Buffer 63 + if err := md.Convert([]byte(source), &buf); err != nil { 64 + return source 65 + } 66 + return buf.String() 67 + }
appview/pages/markup/readme.go appview/pages/markup/format.go
+13 -2
appview/pages/pages.go
··· 231 OwnerHandle string 232 Description string 233 Knot string 234 RepoAt syntax.ATURI 235 IsStarred bool 236 Stats db.RepoStats ··· 351 ext := filepath.Ext(params.ReadmeFileName) 352 switch ext { 353 case ".md", ".markdown", ".mdown", ".mkdn", ".mkd": 354 - htmlString = markup.RenderMarkdown(params.Readme) 355 params.Raw = false 356 params.HTMLReadme = template.HTML(bluemonday.UGCPolicy().Sanitize(htmlString)) 357 default: ··· 466 if params.ShowRendered { 467 switch markup.GetFormat(params.Path) { 468 case markup.FormatMarkdown: 469 - params.RenderedContents = template.HTML(markup.RenderMarkdown(params.Contents)) 470 } 471 } 472
··· 231 OwnerHandle string 232 Description string 233 Knot string 234 + Ref string 235 RepoAt syntax.ATURI 236 IsStarred bool 237 Stats db.RepoStats ··· 352 ext := filepath.Ext(params.ReadmeFileName) 353 switch ext { 354 case ".md", ".markdown", ".mdown", ".mkdn", ".mkd": 355 + htmlString = markup.RenderMarkdownExtended( 356 + params.Readme, 357 + params.RepoInfo.OwnerHandle, 358 + params.RepoInfo.Name, 359 + params.RepoInfo.Ref, 360 + ) 361 params.Raw = false 362 params.HTMLReadme = template.HTML(bluemonday.UGCPolicy().Sanitize(htmlString)) 363 default: ··· 472 if params.ShowRendered { 473 switch markup.GetFormat(params.Path) { 474 case markup.FormatMarkdown: 475 + params.RenderedContents = template.HTML(markup.RenderMarkdownExtended( 476 + params.Contents, 477 + params.RepoInfo.OwnerHandle, 478 + params.RepoInfo.Name, 479 + params.RepoInfo.Ref, 480 + )) 481 } 482 } 483
+2 -2
appview/state/middleware.go
··· 144 http.Error(w, "Forbiden", http.StatusUnauthorized) 145 return 146 } 147 - f, err := fullyResolvedRepo(r) 148 if err != nil { 149 http.Error(w, "malformed url", http.StatusBadRequest) 150 return ··· 225 func ResolvePull(s *State) Middleware { 226 return func(next http.Handler) http.Handler { 227 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 228 - f, err := fullyResolvedRepo(r) 229 if err != nil { 230 log.Println("failed to fully resolve repo", err) 231 http.Error(w, "invalid repo url", http.StatusNotFound)
··· 144 http.Error(w, "Forbiden", http.StatusUnauthorized) 145 return 146 } 147 + f, err := s.fullyResolvedRepo(r) 148 if err != nil { 149 http.Error(w, "malformed url", http.StatusBadRequest) 150 return ··· 225 func ResolvePull(s *State) Middleware { 226 return func(next http.Handler) http.Handler { 227 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 228 + f, err := s.fullyResolvedRepo(r) 229 if err != nil { 230 log.Println("failed to fully resolve repo", err) 231 http.Error(w, "invalid repo url", http.StatusNotFound)
+14 -14
appview/state/pull.go
··· 30 switch r.Method { 31 case http.MethodGet: 32 user := s.auth.GetUser(r) 33 - f, err := fullyResolvedRepo(r) 34 if err != nil { 35 log.Println("failed to get repo and knot", err) 36 return ··· 74 75 func (s *State) RepoSinglePull(w http.ResponseWriter, r *http.Request) { 76 user := s.auth.GetUser(r) 77 - f, err := fullyResolvedRepo(r) 78 if err != nil { 79 log.Println("failed to get repo and knot", err) 80 return ··· 262 263 func (s *State) RepoPullPatch(w http.ResponseWriter, r *http.Request) { 264 user := s.auth.GetUser(r) 265 - f, err := fullyResolvedRepo(r) 266 if err != nil { 267 log.Println("failed to get repo and knot", err) 268 return ··· 349 state = db.PullMerged 350 } 351 352 - f, err := fullyResolvedRepo(r) 353 if err != nil { 354 log.Println("failed to get repo and knot", err) 355 return ··· 402 403 func (s *State) PullComment(w http.ResponseWriter, r *http.Request) { 404 user := s.auth.GetUser(r) 405 - f, err := fullyResolvedRepo(r) 406 if err != nil { 407 log.Println("failed to get repo and knot", err) 408 return ··· 509 510 func (s *State) NewPull(w http.ResponseWriter, r *http.Request) { 511 user := s.auth.GetUser(r) 512 - f, err := fullyResolvedRepo(r) 513 if err != nil { 514 log.Println("failed to get repo and knot", err) 515 return ··· 842 843 func (s *State) PatchUploadFragment(w http.ResponseWriter, r *http.Request) { 844 user := s.auth.GetUser(r) 845 - f, err := fullyResolvedRepo(r) 846 if err != nil { 847 log.Println("failed to get repo and knot", err) 848 return ··· 855 856 func (s *State) CompareBranchesFragment(w http.ResponseWriter, r *http.Request) { 857 user := s.auth.GetUser(r) 858 - f, err := fullyResolvedRepo(r) 859 if err != nil { 860 log.Println("failed to get repo and knot", err) 861 return ··· 895 896 func (s *State) CompareForksFragment(w http.ResponseWriter, r *http.Request) { 897 user := s.auth.GetUser(r) 898 - f, err := fullyResolvedRepo(r) 899 if err != nil { 900 log.Println("failed to get repo and knot", err) 901 return ··· 916 func (s *State) CompareForksBranchesFragment(w http.ResponseWriter, r *http.Request) { 917 user := s.auth.GetUser(r) 918 919 - f, err := fullyResolvedRepo(r) 920 if err != nil { 921 log.Println("failed to get repo and knot", err) 922 return ··· 994 995 func (s *State) ResubmitPull(w http.ResponseWriter, r *http.Request) { 996 user := s.auth.GetUser(r) 997 - f, err := fullyResolvedRepo(r) 998 if err != nil { 999 log.Println("failed to get repo and knot", err) 1000 return ··· 1193 } 1194 1195 func (s *State) MergePull(w http.ResponseWriter, r *http.Request) { 1196 - f, err := fullyResolvedRepo(r) 1197 if err != nil { 1198 log.Println("failed to resolve repo:", err) 1199 s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.") ··· 1258 func (s *State) ClosePull(w http.ResponseWriter, r *http.Request) { 1259 user := s.auth.GetUser(r) 1260 1261 - f, err := fullyResolvedRepo(r) 1262 if err != nil { 1263 log.Println("malformed middleware") 1264 return ··· 1312 func (s *State) ReopenPull(w http.ResponseWriter, r *http.Request) { 1313 user := s.auth.GetUser(r) 1314 1315 - f, err := fullyResolvedRepo(r) 1316 if err != nil { 1317 log.Println("failed to resolve repo", err) 1318 s.pages.Notice(w, "pull-reopen", "Failed to reopen pull.")
··· 30 switch r.Method { 31 case http.MethodGet: 32 user := s.auth.GetUser(r) 33 + f, err := s.fullyResolvedRepo(r) 34 if err != nil { 35 log.Println("failed to get repo and knot", err) 36 return ··· 74 75 func (s *State) RepoSinglePull(w http.ResponseWriter, r *http.Request) { 76 user := s.auth.GetUser(r) 77 + f, err := s.fullyResolvedRepo(r) 78 if err != nil { 79 log.Println("failed to get repo and knot", err) 80 return ··· 262 263 func (s *State) RepoPullPatch(w http.ResponseWriter, r *http.Request) { 264 user := s.auth.GetUser(r) 265 + f, err := s.fullyResolvedRepo(r) 266 if err != nil { 267 log.Println("failed to get repo and knot", err) 268 return ··· 349 state = db.PullMerged 350 } 351 352 + f, err := s.fullyResolvedRepo(r) 353 if err != nil { 354 log.Println("failed to get repo and knot", err) 355 return ··· 402 403 func (s *State) PullComment(w http.ResponseWriter, r *http.Request) { 404 user := s.auth.GetUser(r) 405 + f, err := s.fullyResolvedRepo(r) 406 if err != nil { 407 log.Println("failed to get repo and knot", err) 408 return ··· 509 510 func (s *State) NewPull(w http.ResponseWriter, r *http.Request) { 511 user := s.auth.GetUser(r) 512 + f, err := s.fullyResolvedRepo(r) 513 if err != nil { 514 log.Println("failed to get repo and knot", err) 515 return ··· 842 843 func (s *State) PatchUploadFragment(w http.ResponseWriter, r *http.Request) { 844 user := s.auth.GetUser(r) 845 + f, err := s.fullyResolvedRepo(r) 846 if err != nil { 847 log.Println("failed to get repo and knot", err) 848 return ··· 855 856 func (s *State) CompareBranchesFragment(w http.ResponseWriter, r *http.Request) { 857 user := s.auth.GetUser(r) 858 + f, err := s.fullyResolvedRepo(r) 859 if err != nil { 860 log.Println("failed to get repo and knot", err) 861 return ··· 895 896 func (s *State) CompareForksFragment(w http.ResponseWriter, r *http.Request) { 897 user := s.auth.GetUser(r) 898 + f, err := s.fullyResolvedRepo(r) 899 if err != nil { 900 log.Println("failed to get repo and knot", err) 901 return ··· 916 func (s *State) CompareForksBranchesFragment(w http.ResponseWriter, r *http.Request) { 917 user := s.auth.GetUser(r) 918 919 + f, err := s.fullyResolvedRepo(r) 920 if err != nil { 921 log.Println("failed to get repo and knot", err) 922 return ··· 994 995 func (s *State) ResubmitPull(w http.ResponseWriter, r *http.Request) { 996 user := s.auth.GetUser(r) 997 + f, err := s.fullyResolvedRepo(r) 998 if err != nil { 999 log.Println("failed to get repo and knot", err) 1000 return ··· 1193 } 1194 1195 func (s *State) MergePull(w http.ResponseWriter, r *http.Request) { 1196 + f, err := s.fullyResolvedRepo(r) 1197 if err != nil { 1198 log.Println("failed to resolve repo:", err) 1199 s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.") ··· 1258 func (s *State) ClosePull(w http.ResponseWriter, r *http.Request) { 1259 user := s.auth.GetUser(r) 1260 1261 + f, err := s.fullyResolvedRepo(r) 1262 if err != nil { 1263 log.Println("malformed middleware") 1264 return ··· 1312 func (s *State) ReopenPull(w http.ResponseWriter, r *http.Request) { 1313 user := s.auth.GetUser(r) 1314 1315 + f, err := s.fullyResolvedRepo(r) 1316 if err != nil { 1317 log.Println("failed to resolve repo", err) 1318 s.pages.Notice(w, "pull-reopen", "Failed to reopen pull.")
+34 -39
appview/state/repo.go
··· 34 35 func (s *State) RepoIndex(w http.ResponseWriter, r *http.Request) { 36 ref := chi.URLParam(r, "ref") 37 - f, err := fullyResolvedRepo(r) 38 if err != nil { 39 log.Println("failed to fully resolve repo", err) 40 return ··· 93 } 94 95 func (s *State) RepoLog(w http.ResponseWriter, r *http.Request) { 96 - f, err := fullyResolvedRepo(r) 97 if err != nil { 98 log.Println("failed to fully resolve repo", err) 99 return ··· 144 } 145 146 func (s *State) RepoDescriptionEdit(w http.ResponseWriter, r *http.Request) { 147 - f, err := fullyResolvedRepo(r) 148 if err != nil { 149 log.Println("failed to get repo and knot", err) 150 w.WriteHeader(http.StatusBadRequest) ··· 159 } 160 161 func (s *State) RepoDescription(w http.ResponseWriter, r *http.Request) { 162 - f, err := fullyResolvedRepo(r) 163 if err != nil { 164 log.Println("failed to get repo and knot", err) 165 w.WriteHeader(http.StatusBadRequest) ··· 238 } 239 240 func (s *State) RepoCommit(w http.ResponseWriter, r *http.Request) { 241 - f, err := fullyResolvedRepo(r) 242 if err != nil { 243 log.Println("failed to fully resolve repo", err) 244 return ··· 278 } 279 280 func (s *State) RepoTree(w http.ResponseWriter, r *http.Request) { 281 - f, err := fullyResolvedRepo(r) 282 if err != nil { 283 log.Println("failed to fully resolve repo", err) 284 return ··· 309 return 310 } 311 312 user := s.auth.GetUser(r) 313 314 var breadcrumbs [][]string ··· 334 } 335 336 func (s *State) RepoTags(w http.ResponseWriter, r *http.Request) { 337 - f, err := fullyResolvedRepo(r) 338 if err != nil { 339 log.Println("failed to get repo and knot", err) 340 return ··· 374 } 375 376 func (s *State) RepoBranches(w http.ResponseWriter, r *http.Request) { 377 - f, err := fullyResolvedRepo(r) 378 if err != nil { 379 log.Println("failed to get repo and knot", err) 380 return ··· 415 } 416 417 func (s *State) RepoBlob(w http.ResponseWriter, r *http.Request) { 418 - f, err := fullyResolvedRepo(r) 419 if err != nil { 420 log.Println("failed to get repo and knot", err) 421 return ··· 475 } 476 477 func (s *State) RepoBlobRaw(w http.ResponseWriter, r *http.Request) { 478 - f, err := fullyResolvedRepo(r) 479 if err != nil { 480 log.Println("failed to get repo and knot", err) 481 return ··· 519 } 520 521 func (s *State) AddCollaborator(w http.ResponseWriter, r *http.Request) { 522 - f, err := fullyResolvedRepo(r) 523 if err != nil { 524 log.Println("failed to get repo and knot", err) 525 return ··· 610 func (s *State) DeleteRepo(w http.ResponseWriter, r *http.Request) { 611 user := s.auth.GetUser(r) 612 613 - f, err := fullyResolvedRepo(r) 614 if err != nil { 615 log.Println("failed to get repo and knot", err) 616 return ··· 714 } 715 716 func (s *State) SetDefaultBranch(w http.ResponseWriter, r *http.Request) { 717 - f, err := fullyResolvedRepo(r) 718 if err != nil { 719 log.Println("failed to get repo and knot", err) 720 return ··· 753 } 754 755 func (s *State) RepoSettings(w http.ResponseWriter, r *http.Request) { 756 - f, err := fullyResolvedRepo(r) 757 if err != nil { 758 log.Println("failed to get repo and knot", err) 759 return ··· 804 } 805 } 806 807 - resp, err = us.DefaultBranch(f.OwnerDid(), f.RepoName) 808 if err != nil { 809 log.Println("failed to reach knotserver", err) 810 } else { 811 - defer resp.Body.Close() 812 - 813 - body, err := io.ReadAll(resp.Body) 814 - if err != nil { 815 - log.Printf("Error reading response body: %v", err) 816 - } else { 817 - var result types.RepoDefaultBranchResponse 818 - err = json.Unmarshal(body, &result) 819 - if err != nil { 820 - log.Println("failed to parse response:", err) 821 - } else { 822 - defaultBranch = result.Branch 823 - } 824 - } 825 } 826 } 827 ··· 840 Knot string 841 OwnerId identity.Identity 842 RepoName string 843 RepoAt syntax.ATURI 844 Description string 845 AddedAt string ··· 984 Description: f.Description, 985 IsStarred: isStarred, 986 Knot: knot, 987 Roles: RolesInRepo(s, u, f), 988 Stats: db.RepoStats{ 989 StarCount: starCount, ··· 1003 1004 func (s *State) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { 1005 user := s.auth.GetUser(r) 1006 - f, err := fullyResolvedRepo(r) 1007 if err != nil { 1008 log.Println("failed to get repo and knot", err) 1009 return ··· 1057 1058 func (s *State) CloseIssue(w http.ResponseWriter, r *http.Request) { 1059 user := s.auth.GetUser(r) 1060 - f, err := fullyResolvedRepo(r) 1061 if err != nil { 1062 log.Println("failed to get repo and knot", err) 1063 return ··· 1129 1130 func (s *State) ReopenIssue(w http.ResponseWriter, r *http.Request) { 1131 user := s.auth.GetUser(r) 1132 - f, err := fullyResolvedRepo(r) 1133 if err != nil { 1134 log.Println("failed to get repo and knot", err) 1135 return ··· 1177 1178 func (s *State) NewIssueComment(w http.ResponseWriter, r *http.Request) { 1179 user := s.auth.GetUser(r) 1180 - f, err := fullyResolvedRepo(r) 1181 if err != nil { 1182 log.Println("failed to get repo and knot", err) 1183 return ··· 1256 1257 func (s *State) IssueComment(w http.ResponseWriter, r *http.Request) { 1258 user := s.auth.GetUser(r) 1259 - f, err := fullyResolvedRepo(r) 1260 if err != nil { 1261 log.Println("failed to get repo and knot", err) 1262 return ··· 1315 1316 func (s *State) EditIssueComment(w http.ResponseWriter, r *http.Request) { 1317 user := s.auth.GetUser(r) 1318 - f, err := fullyResolvedRepo(r) 1319 if err != nil { 1320 log.Println("failed to get repo and knot", err) 1321 return ··· 1440 1441 func (s *State) DeleteIssueComment(w http.ResponseWriter, r *http.Request) { 1442 user := s.auth.GetUser(r) 1443 - f, err := fullyResolvedRepo(r) 1444 if err != nil { 1445 log.Println("failed to get repo and knot", err) 1446 return ··· 1539 } 1540 1541 user := s.auth.GetUser(r) 1542 - f, err := fullyResolvedRepo(r) 1543 if err != nil { 1544 log.Println("failed to get repo and knot", err) 1545 return ··· 1579 func (s *State) NewIssue(w http.ResponseWriter, r *http.Request) { 1580 user := s.auth.GetUser(r) 1581 1582 - f, err := fullyResolvedRepo(r) 1583 if err != nil { 1584 log.Println("failed to get repo and knot", err) 1585 return ··· 1661 1662 func (s *State) ForkRepo(w http.ResponseWriter, r *http.Request) { 1663 user := s.auth.GetUser(r) 1664 - f, err := fullyResolvedRepo(r) 1665 if err != nil { 1666 log.Printf("failed to resolve source repo: %v", err) 1667 return
··· 34 35 func (s *State) RepoIndex(w http.ResponseWriter, r *http.Request) { 36 ref := chi.URLParam(r, "ref") 37 + f, err := s.fullyResolvedRepo(r) 38 if err != nil { 39 log.Println("failed to fully resolve repo", err) 40 return ··· 93 } 94 95 func (s *State) RepoLog(w http.ResponseWriter, r *http.Request) { 96 + f, err := s.fullyResolvedRepo(r) 97 if err != nil { 98 log.Println("failed to fully resolve repo", err) 99 return ··· 144 } 145 146 func (s *State) RepoDescriptionEdit(w http.ResponseWriter, r *http.Request) { 147 + f, err := s.fullyResolvedRepo(r) 148 if err != nil { 149 log.Println("failed to get repo and knot", err) 150 w.WriteHeader(http.StatusBadRequest) ··· 159 } 160 161 func (s *State) RepoDescription(w http.ResponseWriter, r *http.Request) { 162 + f, err := s.fullyResolvedRepo(r) 163 if err != nil { 164 log.Println("failed to get repo and knot", err) 165 w.WriteHeader(http.StatusBadRequest) ··· 238 } 239 240 func (s *State) RepoCommit(w http.ResponseWriter, r *http.Request) { 241 + f, err := s.fullyResolvedRepo(r) 242 if err != nil { 243 log.Println("failed to fully resolve repo", err) 244 return ··· 278 } 279 280 func (s *State) RepoTree(w http.ResponseWriter, r *http.Request) { 281 + f, err := s.fullyResolvedRepo(r) 282 if err != nil { 283 log.Println("failed to fully resolve repo", err) 284 return ··· 309 return 310 } 311 312 + if result.Parent == treePath { 313 + fmt.Println("here") 314 + http.Redirect(w, r, fmt.Sprintf("/%s/%s/blob/%s/%s", f.OwnerHandle(), f.RepoName, ref, treePath), http.StatusPermanentRedirect) 315 + return 316 + } 317 + 318 user := s.auth.GetUser(r) 319 320 var breadcrumbs [][]string ··· 340 } 341 342 func (s *State) RepoTags(w http.ResponseWriter, r *http.Request) { 343 + f, err := s.fullyResolvedRepo(r) 344 if err != nil { 345 log.Println("failed to get repo and knot", err) 346 return ··· 380 } 381 382 func (s *State) RepoBranches(w http.ResponseWriter, r *http.Request) { 383 + f, err := s.fullyResolvedRepo(r) 384 if err != nil { 385 log.Println("failed to get repo and knot", err) 386 return ··· 421 } 422 423 func (s *State) RepoBlob(w http.ResponseWriter, r *http.Request) { 424 + f, err := s.fullyResolvedRepo(r) 425 if err != nil { 426 log.Println("failed to get repo and knot", err) 427 return ··· 481 } 482 483 func (s *State) RepoBlobRaw(w http.ResponseWriter, r *http.Request) { 484 + f, err := s.fullyResolvedRepo(r) 485 if err != nil { 486 log.Println("failed to get repo and knot", err) 487 return ··· 525 } 526 527 func (s *State) AddCollaborator(w http.ResponseWriter, r *http.Request) { 528 + f, err := s.fullyResolvedRepo(r) 529 if err != nil { 530 log.Println("failed to get repo and knot", err) 531 return ··· 616 func (s *State) DeleteRepo(w http.ResponseWriter, r *http.Request) { 617 user := s.auth.GetUser(r) 618 619 + f, err := s.fullyResolvedRepo(r) 620 if err != nil { 621 log.Println("failed to get repo and knot", err) 622 return ··· 720 } 721 722 func (s *State) SetDefaultBranch(w http.ResponseWriter, r *http.Request) { 723 + f, err := s.fullyResolvedRepo(r) 724 if err != nil { 725 log.Println("failed to get repo and knot", err) 726 return ··· 759 } 760 761 func (s *State) RepoSettings(w http.ResponseWriter, r *http.Request) { 762 + f, err := s.fullyResolvedRepo(r) 763 if err != nil { 764 log.Println("failed to get repo and knot", err) 765 return ··· 810 } 811 } 812 813 + result, err := us.DefaultBranch(f.OwnerDid(), f.RepoName) 814 if err != nil { 815 log.Println("failed to reach knotserver", err) 816 } else { 817 + defaultBranch = result.Branch 818 } 819 } 820 ··· 833 Knot string 834 OwnerId identity.Identity 835 RepoName string 836 + Ref string 837 RepoAt syntax.ATURI 838 Description string 839 AddedAt string ··· 978 Description: f.Description, 979 IsStarred: isStarred, 980 Knot: knot, 981 + Ref: f.Ref, 982 Roles: RolesInRepo(s, u, f), 983 Stats: db.RepoStats{ 984 StarCount: starCount, ··· 998 999 func (s *State) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { 1000 user := s.auth.GetUser(r) 1001 + f, err := s.fullyResolvedRepo(r) 1002 if err != nil { 1003 log.Println("failed to get repo and knot", err) 1004 return ··· 1052 1053 func (s *State) CloseIssue(w http.ResponseWriter, r *http.Request) { 1054 user := s.auth.GetUser(r) 1055 + f, err := s.fullyResolvedRepo(r) 1056 if err != nil { 1057 log.Println("failed to get repo and knot", err) 1058 return ··· 1124 1125 func (s *State) ReopenIssue(w http.ResponseWriter, r *http.Request) { 1126 user := s.auth.GetUser(r) 1127 + f, err := s.fullyResolvedRepo(r) 1128 if err != nil { 1129 log.Println("failed to get repo and knot", err) 1130 return ··· 1172 1173 func (s *State) NewIssueComment(w http.ResponseWriter, r *http.Request) { 1174 user := s.auth.GetUser(r) 1175 + f, err := s.fullyResolvedRepo(r) 1176 if err != nil { 1177 log.Println("failed to get repo and knot", err) 1178 return ··· 1251 1252 func (s *State) IssueComment(w http.ResponseWriter, r *http.Request) { 1253 user := s.auth.GetUser(r) 1254 + f, err := s.fullyResolvedRepo(r) 1255 if err != nil { 1256 log.Println("failed to get repo and knot", err) 1257 return ··· 1310 1311 func (s *State) EditIssueComment(w http.ResponseWriter, r *http.Request) { 1312 user := s.auth.GetUser(r) 1313 + f, err := s.fullyResolvedRepo(r) 1314 if err != nil { 1315 log.Println("failed to get repo and knot", err) 1316 return ··· 1435 1436 func (s *State) DeleteIssueComment(w http.ResponseWriter, r *http.Request) { 1437 user := s.auth.GetUser(r) 1438 + f, err := s.fullyResolvedRepo(r) 1439 if err != nil { 1440 log.Println("failed to get repo and knot", err) 1441 return ··· 1534 } 1535 1536 user := s.auth.GetUser(r) 1537 + f, err := s.fullyResolvedRepo(r) 1538 if err != nil { 1539 log.Println("failed to get repo and knot", err) 1540 return ··· 1574 func (s *State) NewIssue(w http.ResponseWriter, r *http.Request) { 1575 user := s.auth.GetUser(r) 1576 1577 + f, err := s.fullyResolvedRepo(r) 1578 if err != nil { 1579 log.Println("failed to get repo and knot", err) 1580 return ··· 1656 1657 func (s *State) ForkRepo(w http.ResponseWriter, r *http.Request) { 1658 user := s.auth.GetUser(r) 1659 + f, err := s.fullyResolvedRepo(r) 1660 if err != nil { 1661 log.Printf("failed to resolve source repo: %v", err) 1662 return
+19 -2
appview/state/repo_util.go
··· 17 "tangled.sh/tangled.sh/core/appview/pages" 18 ) 19 20 - func fullyResolvedRepo(r *http.Request) (*FullyResolvedRepo, error) { 21 repoName := chi.URLParam(r, "repo") 22 knot, ok := r.Context().Value("knot").(string) 23 if !ok { 24 log.Println("malformed middleware") ··· 36 return nil, fmt.Errorf("malformed middleware") 37 } 38 39 parsedRepoAt, err := syntax.ParseATURI(repoAt) 40 if err != nil { 41 log.Println("malformed repo at-uri") 42 - return nil, fmt.Errorf("malformed middleware") 43 } 44 45 // pass through values from the middleware ··· 53 RepoAt: parsedRepoAt, 54 Description: description, 55 AddedAt: addedAt, 56 }, nil 57 } 58
··· 17 "tangled.sh/tangled.sh/core/appview/pages" 18 ) 19 20 + func (s *State) fullyResolvedRepo(r *http.Request) (*FullyResolvedRepo, error) { 21 repoName := chi.URLParam(r, "repo") 22 + ref := chi.URLParam(r, "ref") 23 + 24 knot, ok := r.Context().Value("knot").(string) 25 if !ok { 26 log.Println("malformed middleware") ··· 38 return nil, fmt.Errorf("malformed middleware") 39 } 40 41 + if ref == "" { 42 + us, err := NewUnsignedClient(knot, s.config.Dev) 43 + if err != nil { 44 + return nil, fmt.Errorf("failed to setup new signed client: %w", err) 45 + } 46 + 47 + def, err := us.DefaultBranch(id.DID.String(), repoName) 48 + if err != nil { 49 + return nil, fmt.Errorf("failed to get default branch: %w", err) 50 + } 51 + 52 + ref = def.Branch 53 + } 54 + 55 parsedRepoAt, err := syntax.ParseATURI(repoAt) 56 if err != nil { 57 log.Println("malformed repo at-uri") 58 + return nil, fmt.Errorf("malformed middleware: %w", err) 59 } 60 61 // pass through values from the middleware ··· 69 RepoAt: parsedRepoAt, 70 Description: description, 71 AddedAt: addedAt, 72 + Ref: ref, 73 }, nil 74 } 75
+13 -2
appview/state/signer.go
··· 336 return us.client.Do(req) 337 } 338 339 - func (us *UnsignedClient) DefaultBranch(ownerDid, repoName string) (*http.Response, error) { 340 const ( 341 Method = "GET" 342 ) ··· 348 return nil, err 349 } 350 351 - return us.client.Do(req) 352 } 353 354 func (us *UnsignedClient) Capabilities() (*types.Capabilities, error) {
··· 336 return us.client.Do(req) 337 } 338 339 + func (us *UnsignedClient) DefaultBranch(ownerDid, repoName string) (*types.RepoDefaultBranchResponse, error) { 340 const ( 341 Method = "GET" 342 ) ··· 348 return nil, err 349 } 350 351 + resp, err := us.client.Do(req) 352 + if err != nil { 353 + return nil, err 354 + } 355 + defer resp.Body.Close() 356 + 357 + var branchResponse types.RepoDefaultBranchResponse 358 + if err := json.NewDecoder(resp.Body).Decode(&branchResponse); err != nil { 359 + return nil, err 360 + } 361 + 362 + return &branchResponse, nil 363 } 364 365 func (us *UnsignedClient) Capabilities() (*types.Capabilities, error) {
+1 -1
go.mod
··· 25 github.com/resend/resend-go/v2 v2.15.0 26 github.com/sethvargo/go-envconfig v1.1.0 27 github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e 28 - github.com/yuin/goldmark v1.4.13 29 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 30 ) 31
··· 25 github.com/resend/resend-go/v2 v2.15.0 26 github.com/sethvargo/go-envconfig v1.1.0 27 github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e 28 + github.com/yuin/goldmark v1.7.8 29 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 30 ) 31
+2 -1
go.sum
··· 262 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 263 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 264 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 265 - github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= 266 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 267 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA= 268 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8= 269 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=
··· 262 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 263 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 264 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 265 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 266 + github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= 267 + github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= 268 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA= 269 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8= 270 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=