forked from tangled.org/core
this repo has no description

appview: state: add RepoCompare{,Diff} handlers

authored by anirudh.fi and committed by Tangled df75814b 26c62f52

Changed files
+197
appview
pages
templates
repo
compare
state
+28
appview/pages/pages.go
··· 857 857 return p.executePlain("repo/pulls/fragments/pullNewComment", w, params) 858 858 } 859 859 860 + type RepoCompareParams struct { 861 + LoggedInUser *oauth.User 862 + RepoInfo repoinfo.RepoInfo 863 + Forks []db.Repo 864 + Branches []types.Branch 865 + Tags []*types.TagReference 866 + 867 + Active string 868 + } 869 + 870 + func (p *Pages) RepoCompare(w io.Writer, params RepoCompareParams) error { 871 + params.Active = "overview" 872 + return p.executeRepo("repo/compare/new", w, params) 873 + } 874 + 875 + type RepoCompareDiffParams struct { 876 + LoggedInUser *oauth.User 877 + RepoInfo repoinfo.RepoInfo 878 + FormatPatch types.RepoFormatPatchResponse 879 + 880 + Active string 881 + } 882 + 883 + func (p *Pages) RepoCompareDiff(w io.Writer, params RepoCompareDiffParams) error { 884 + params.Active = "overview" 885 + return p.executeRepo("repo/compare/new", w, params) 886 + } 887 + 860 888 func (p *Pages) Static() http.Handler { 861 889 if p.dev { 862 890 return http.StripPrefix("/static/", http.FileServer(http.Dir("appview/pages/static")))
+74
appview/pages/templates/repo/compare/new.html
··· 1 + {{ define "title" }}new comparison{{ end }} 2 + 3 + {{ define "repoContent" }} 4 + <h2 class="font-bold text-sm mb-4 uppercase dark:text-white"> 5 + Compare changes 6 + </h2> 7 + <p>Choose any two refs to compare.</p> 8 + 9 + <div class="flex items-center gap-2 py-4"> 10 + <div> 11 + base: 12 + <select 13 + class="p-1 border max-w-32 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700" 14 + > 15 + <optgroup 16 + label="branches ({{ len .Branches }})" 17 + class="bold text-sm" 18 + > 19 + {{ range .Branches }} 20 + <option 21 + value="{{ .Reference.Name }}" 22 + class="py-1" 23 + {{ if .IsDefault }} 24 + selected 25 + {{ end }} 26 + > 27 + {{ .Reference.Name }} 28 + </option> 29 + {{ end }} 30 + </optgroup> 31 + <optgroup label="tags ({{ len .Tags }})" class="bold text-sm"> 32 + {{ range .Tags }} 33 + <option value="{{ .Reference.Name }}" class="py-1"> 34 + {{ .Reference.Name }} 35 + </option> 36 + {{ else }} 37 + <option class="py-1" disabled>no tags found</option> 38 + {{ end }} 39 + </optgroup> 40 + </select> 41 + </div> 42 + {{ i "arrow-left" "w-4 h-4" }} 43 + <div> 44 + compare: 45 + <select 46 + class="p-1 border max-w-32 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700" 47 + > 48 + <optgroup 49 + label="branches ({{ len .Branches }})" 50 + class="bold text-sm" 51 + > 52 + {{ range .Branches }} 53 + <option value="{{ .Reference.Name }}" class="py-1"> 54 + {{ .Reference.Name }} 55 + </option> 56 + {{ end }} 57 + </optgroup> 58 + <optgroup label="tags ({{ len .Tags }})" class="bold text-sm"> 59 + {{ range .Tags }} 60 + <option value="{{ .Reference.Name }}" class="py-1"> 61 + {{ .Reference.Name }} 62 + </option> 63 + {{ else }} 64 + <option class="py-1" disabled>no tags found</option> 65 + {{ end }} 66 + </optgroup> 67 + </select> 68 + </div> 69 + </div> 70 + {{ end }} 71 + 72 + {{ define "repoAfter" }} 73 + <div id="compare-diff"></div> 74 + {{ end }}
+84
appview/state/repo.go
··· 2054 2054 return 2055 2055 } 2056 2056 } 2057 + 2058 + func (s *State) RepoCompare(w http.ResponseWriter, r *http.Request) { 2059 + user := s.oauth.GetUser(r) 2060 + f, err := s.fullyResolvedRepo(r) 2061 + if err != nil { 2062 + log.Println("failed to get repo and knot", err) 2063 + return 2064 + } 2065 + 2066 + us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 2067 + if err != nil { 2068 + log.Printf("failed to create unsigned client for %s", f.Knot) 2069 + s.pages.Error503(w) 2070 + return 2071 + } 2072 + 2073 + branches, err := us.Branches(f.OwnerDid(), f.RepoName) 2074 + if err != nil { 2075 + s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2076 + log.Println("failed to reach knotserver", err) 2077 + return 2078 + } 2079 + 2080 + tags, err := us.Tags(f.OwnerDid(), f.RepoName) 2081 + if err != nil { 2082 + s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2083 + log.Println("failed to reach knotserver", err) 2084 + return 2085 + } 2086 + 2087 + forks, err := db.GetForksByDid(s.db, user.Did) 2088 + if err != nil { 2089 + s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2090 + log.Println("failed to get forks", err) 2091 + return 2092 + } 2093 + 2094 + s.pages.RepoCompare(w, pages.RepoCompareParams{ 2095 + LoggedInUser: user, 2096 + RepoInfo: f.RepoInfo(s, user), 2097 + Forks: forks, 2098 + Branches: branches.Branches, 2099 + Tags: tags.Tags, 2100 + }) 2101 + } 2102 + 2103 + func (s *State) RepoCompareDiff(w http.ResponseWriter, r *http.Request) { 2104 + f, err := s.fullyResolvedRepo(r) 2105 + if err != nil { 2106 + log.Println("failed to get repo and knot", err) 2107 + return 2108 + } 2109 + user := s.oauth.GetUser(r) 2110 + 2111 + rest := chi.URLParam(r, "*") // master...feature/xyz 2112 + parts := strings.SplitN(rest, "...", 2) 2113 + if len(parts) != 2 { 2114 + s.pages.Notice(w, "compare-error", "Invalid ref format.") 2115 + return 2116 + } 2117 + 2118 + ref1 := parts[0] 2119 + ref2 := parts[1] 2120 + 2121 + us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev) 2122 + if err != nil { 2123 + s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2124 + log.Println("failed to reach knotserver", err) 2125 + return 2126 + } 2127 + 2128 + formatPatch, err := us.Compare(f.OwnerDid(), f.RepoName, ref1, ref2) 2129 + if err != nil { 2130 + s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2131 + log.Println("failed to compare", err) 2132 + return 2133 + } 2134 + 2135 + s.pages.RepoCompareDiff(w, pages.RepoCompareDiffParams{ 2136 + LoggedInUser: user, 2137 + RepoInfo: f.RepoInfo(s, user), 2138 + FormatPatch: *formatPatch, 2139 + }) 2140 + }
+11
appview/state/router.go
··· 118 118 }) 119 119 }) 120 120 121 + r.Route("/compare", func(r chi.Router) { 122 + r.Get("/", s.RepoCompare) 123 + 124 + // we have to wildcard here since we want to support GitHub's compare syntax 125 + // /compare/{ref1}...{ref2} 126 + // for example: 127 + // /compare/master...some/feature 128 + // /compare/master...example.com:another/feature <- this is a fork 129 + r.Get("/*", s.RepoCompareDiff) 130 + }) 131 + 121 132 r.Route("/pulls", func(r chi.Router) { 122 133 r.Get("/", s.RepoPulls) 123 134 r.With(middleware.AuthMiddleware(s.oauth)).Route("/new", func(r chi.Router) {