Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview: repo: retrieve fork info on repo page load

authored by

BrookJeynes and committed by
Tangled
1dc5d2cd a597918f

+110 -24
+1
appview/pages/pages.go
··· 424 424 CommitsTrunc []*object.Commit 425 425 TagsTrunc []*types.TagReference 426 426 BranchesTrunc []types.Branch 427 + ForkInfo ForkInfo 427 428 types.RepoIndexResponse 428 429 HTMLReadme template.HTML 429 430 Raw bool
+105 -24
appview/state/repo.go
··· 25 25 "tangled.sh/tangled.sh/core/appview/pages/markup" 26 26 "tangled.sh/tangled.sh/core/appview/pages/repoinfo" 27 27 "tangled.sh/tangled.sh/core/appview/pagination" 28 + "tangled.sh/tangled.sh/core/knotserver" 28 29 "tangled.sh/tangled.sh/core/types" 29 30 30 31 "github.com/bluesky-social/indigo/atproto/data" ··· 124 123 user := s.oauth.GetUser(r) 125 124 repoInfo := f.RepoInfo(s, user) 126 125 127 - secret, err := db.GetRegistrationKey(s.db, f.Knot) 126 + forkInfo, err := GetForkInfo(repoInfo, s, f, us, w, user) 128 127 if err != nil { 129 - log.Printf("failed to get registration key for %s: %s", f.Knot, err) 130 - s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 128 + log.Printf("Failed to fetch fork information: %v", err) 129 + return 131 130 } 132 - 133 - // update the hidden tracking branch to latest 134 - signedClient, err := knotclient.NewSignedClient(f.Knot, secret, s.config.Core.Dev) 135 - if err != nil { 136 - log.Printf("failed to create signed client for %s: %s", f.Knot, err) 137 - s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 138 - } 139 - 140 - newHiddenRefResp, err := signedClient.NewHiddenRef(user.Did, repoInfo.Name, f.Ref, f.Ref) 141 - if err != nil || newHiddenRefResp.StatusCode != http.StatusNoContent { 142 - log.Printf("failed to update tracking branch: %s", err) 143 - s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 144 - } 145 - 146 - hiddenRef := fmt.Sprintf("hidden/%s/%s", f.Ref, f.Ref) 147 - comparison, err := us.Compare(user.Did, repoInfo.Name, f.Ref, hiddenRef) 148 - if err != nil { 149 - log.Printf("failed to compare branches: %s", err) 150 - s.pages.Notice(w, "resubmit-error", err.Error()) 151 - } 152 - log.Println(comparison) 153 131 154 132 s.pages.RepoIndexPage(w, pages.RepoIndexParams{ 155 133 LoggedInUser: user, ··· 137 157 RepoIndexResponse: result, 138 158 CommitsTrunc: commitsTrunc, 139 159 TagsTrunc: tagsTrunc, 160 + ForkInfo: *forkInfo, 140 161 BranchesTrunc: branchesTrunc, 141 162 EmailToDidOrHandle: EmailToDidOrHandle(s, emails), 142 163 }) 143 164 return 165 + } 166 + 167 + func GetForkInfo( 168 + repoInfo repoinfo.RepoInfo, 169 + s *State, 170 + f *FullyResolvedRepo, 171 + us *knotclient.UnsignedClient, 172 + w http.ResponseWriter, 173 + user *oauth.User, 174 + ) (*pages.ForkInfo, error) { 175 + forkInfo := pages.ForkInfo{ 176 + IsFork: repoInfo.Source != nil, 177 + Status: pages.UpToDate, 178 + } 179 + 180 + secret, err := db.GetRegistrationKey(s.db, f.Knot) 181 + if err != nil { 182 + log.Printf("failed to get registration key for %s: %s", f.Knot, err) 183 + s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 184 + } 185 + 186 + if !forkInfo.IsFork { 187 + forkInfo.IsFork = false 188 + return &forkInfo, nil 189 + } 190 + 191 + resp, err := us.Branches(repoInfo.Source.Did, repoInfo.Source.Name) 192 + if err != nil { 193 + log.Println("failed to reach knotserver", err) 194 + return nil, err 195 + } 196 + 197 + body, err := io.ReadAll(resp.Body) 198 + if err != nil { 199 + log.Printf("Error reading forkResponse forkBody: %v", err) 200 + return nil, err 201 + } 202 + 203 + var result types.RepoBranchesResponse 204 + err = json.Unmarshal(body, &result) 205 + if err != nil { 206 + log.Println("failed to parse forkResponse:", err) 207 + return nil, err 208 + } 209 + 210 + var contains = false 211 + for _, branch := range result.Branches { 212 + if branch.Name == f.Ref { 213 + contains = true 214 + break 215 + } 216 + } 217 + 218 + if contains == false { 219 + forkInfo.Status = pages.MissingBranch 220 + return &forkInfo, nil 221 + } 222 + 223 + signedClient, err := knotclient.NewSignedClient(f.Knot, secret, s.config.Core.Dev) 224 + if err != nil { 225 + log.Printf("failed to create signed client for %s: %s", f.Knot, err) 226 + return nil, err 227 + } 228 + 229 + newHiddenRefResp, err := signedClient.NewHiddenRef(user.Did, repoInfo.Name, f.Ref, f.Ref) 230 + if err != nil || newHiddenRefResp.StatusCode != http.StatusNoContent { 231 + log.Printf("failed to update tracking branch: %s", err) 232 + return nil, err 233 + } 234 + 235 + hiddenRef := fmt.Sprintf("hidden/%s/%s", f.Ref, f.Ref) 236 + comparison, err := us.Compare(user.Did, repoInfo.Name, f.Ref, hiddenRef) 237 + if err != nil { 238 + log.Printf("failed to compare branches '%s' and '%s': %s", f.Ref, hiddenRef, err) 239 + return nil, err 240 + } 241 + 242 + if len(comparison.FormatPatch) == 0 { 243 + return &forkInfo, nil 244 + } 245 + 246 + var isAncestor types.AncestorCheckResponse 247 + forkSyncableResp, err := signedClient.RepoForkSyncable(user.Did, string(f.RepoAt), repoInfo.Name, f.Ref, hiddenRef) 248 + if err != nil { 249 + log.Printf("failed to check if fork is syncable: %s", err) 250 + return nil, err 251 + } 252 + 253 + if err := json.NewDecoder(forkSyncableResp.Body).Decode(&isAncestor); err != nil { 254 + log.Printf("failed to decode 'isAncestor': %s", err) 255 + return nil, err 256 + } 257 + 258 + if isAncestor.IsAncestor { 259 + forkInfo.Status = pages.FastForwardable 260 + } else { 261 + forkInfo.Status = pages.Conflict 262 + } 263 + 264 + return &forkInfo, nil 144 265 } 145 266 146 267 func (s *State) RepoLog(w http.ResponseWriter, r *http.Request) {
+4
types/repo.go
··· 90 90 Lines int `json:"lines,omitempty"` 91 91 SizeHint uint64 `json:"size_hint,omitempty"` 92 92 } 93 + 94 + type AncestorCheckResponse struct { 95 + IsAncestor bool `json:"isAncestor"` 96 + }