Signed-off-by: Seongmin Lee git@boltless.me
ERROR
appview/issues/issues.go
ERROR
appview/issues/issues.go
Failed to calculate interdiff for this file.
ERROR
appview/middleware/middleware.go
ERROR
appview/middleware/middleware.go
Failed to calculate interdiff for this file.
ERROR
appview/pages/repoinfo/repoinfo.go
ERROR
appview/pages/repoinfo/repoinfo.go
Failed to calculate interdiff for this file.
ERROR
appview/pulls/pulls.go
ERROR
appview/pulls/pulls.go
Failed to calculate interdiff for this file.
ERROR
appview/repo/blob.go
ERROR
appview/repo/blob.go
Failed to calculate interdiff for this file.
ERROR
appview/repo/tree.go
ERROR
appview/repo/tree.go
Failed to calculate interdiff for this file.
ERROR
appview/reporesolver/resolver.go
ERROR
appview/reporesolver/resolver.go
Failed to calculate interdiff for this file.
NEW
appview/repo/artifact.go
NEW
appview/repo/artifact.go
NEW
appview/repo/branches.go
NEW
appview/repo/branches.go
···
29
xrpcc := &indigoxrpc.Client{
30
Host: host,
31
}
32
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
33
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
34
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
35
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
···
29
xrpcc := &indigoxrpc.Client{
30
Host: host,
31
}
32
+
repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
33
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
34
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
35
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
NEW
appview/repo/compare.go
NEW
appview/repo/compare.go
···
36
Host: host,
37
}
38
39
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
40
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
41
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
42
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
···
147
Host: host,
148
}
149
150
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
151
152
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
153
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
···
36
Host: host,
37
}
38
39
+
repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
40
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
41
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
42
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
···
147
Host: host,
148
}
149
150
+
repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
151
152
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
153
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
NEW
appview/repo/feed.go
NEW
appview/repo/feed.go
···
11
"tangled.org/core/appview/db"
12
"tangled.org/core/appview/models"
13
"tangled.org/core/appview/pagination"
14
-
"tangled.org/core/appview/reporesolver"
15
16
"github.com/bluesky-social/indigo/atproto/syntax"
17
"github.com/gorilla/feeds"
18
)
19
20
-
func (rp *Repo) getRepoFeed(ctx context.Context, f *reporesolver.ResolvedRepo) (*feeds.Feed, error) {
21
const feedLimitPerType = 100
22
23
-
pulls, err := db.GetPullsWithLimit(rp.db, feedLimitPerType, db.FilterEq("repo_at", f.RepoAt()))
24
if err != nil {
25
return nil, err
26
}
···
28
issues, err := db.GetIssuesPaginated(
29
rp.db,
30
pagination.Page{Limit: feedLimitPerType},
31
-
db.FilterEq("repo_at", f.RepoAt()),
32
)
33
if err != nil {
34
return nil, err
35
}
36
37
feed := &feeds.Feed{
38
-
Title: fmt.Sprintf("activity feed for %s", f.OwnerSlashRepo()),
39
-
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s", rp.config.Core.AppviewHost, f.OwnerSlashRepo()), Type: "text/html", Rel: "alternate"},
40
Items: make([]*feeds.Item, 0),
41
Updated: time.UnixMilli(0),
42
}
43
44
for _, pull := range pulls {
45
-
items, err := rp.createPullItems(ctx, pull, f)
46
if err != nil {
47
return nil, err
48
}
···
50
}
51
52
for _, issue := range issues {
53
-
item, err := rp.createIssueItem(ctx, issue, f)
54
if err != nil {
55
return nil, err
56
}
···
71
return feed, nil
72
}
73
74
-
func (rp *Repo) createPullItems(ctx context.Context, pull *models.Pull, f *reporesolver.ResolvedRepo) ([]*feeds.Item, error) {
75
owner, err := rp.idResolver.ResolveIdent(ctx, pull.OwnerDid)
76
if err != nil {
77
return nil, err
···
80
var items []*feeds.Item
81
82
state := rp.getPullState(pull)
83
-
description := rp.buildPullDescription(owner.Handle, state, pull, f.OwnerSlashRepo())
84
85
mainItem := &feeds.Item{
86
Title: fmt.Sprintf("[PR #%d] %s", pull.PullId, pull.Title),
87
Description: description,
88
-
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/pulls/%d", rp.config.Core.AppviewHost, f.OwnerSlashRepo(), pull.PullId)},
89
Created: pull.Created,
90
Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)},
91
}
···
98
99
roundItem := &feeds.Item{
100
Title: fmt.Sprintf("[PR #%d] %s (round #%d)", pull.PullId, pull.Title, round.RoundNumber),
101
-
Description: fmt.Sprintf("@%s submitted changes (at round #%d) on PR #%d in %s", owner.Handle, round.RoundNumber, pull.PullId, f.OwnerSlashRepo()),
102
-
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/pulls/%d/round/%d/", rp.config.Core.AppviewHost, f.OwnerSlashRepo(), pull.PullId, round.RoundNumber)},
103
Created: round.Created,
104
Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)},
105
}
···
109
return items, nil
110
}
111
112
-
func (rp *Repo) createIssueItem(ctx context.Context, issue models.Issue, f *reporesolver.ResolvedRepo) (*feeds.Item, error) {
113
owner, err := rp.idResolver.ResolveIdent(ctx, issue.Did)
114
if err != nil {
115
return nil, err
···
122
123
return &feeds.Item{
124
Title: fmt.Sprintf("[Issue #%d] %s", issue.IssueId, issue.Title),
125
-
Description: fmt.Sprintf("@%s %s issue #%d in %s", owner.Handle, state, issue.IssueId, f.OwnerSlashRepo()),
126
-
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/issues/%d", rp.config.Core.AppviewHost, f.OwnerSlashRepo(), issue.IssueId)},
127
Created: issue.Created,
128
Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)},
129
}, nil
···
152
log.Println("failed to fully resolve repo:", err)
153
return
154
}
155
156
-
feed, err := rp.getRepoFeed(r.Context(), f)
157
if err != nil {
158
log.Println("failed to get repo feed:", err)
159
rp.pages.Error500(w)
···
11
"tangled.org/core/appview/db"
12
"tangled.org/core/appview/models"
13
"tangled.org/core/appview/pagination"
14
15
+
"github.com/bluesky-social/indigo/atproto/identity"
16
"github.com/bluesky-social/indigo/atproto/syntax"
17
"github.com/gorilla/feeds"
18
)
19
20
+
func (rp *Repo) getRepoFeed(ctx context.Context, repo *models.Repo, ownerSlashRepo string) (*feeds.Feed, error) {
21
const feedLimitPerType = 100
22
23
+
pulls, err := db.GetPullsWithLimit(rp.db, feedLimitPerType, db.FilterEq("repo_at", repo.RepoAt()))
24
if err != nil {
25
return nil, err
26
}
···
28
issues, err := db.GetIssuesPaginated(
29
rp.db,
30
pagination.Page{Limit: feedLimitPerType},
31
+
db.FilterEq("repo_at", repo.RepoAt()),
32
)
33
if err != nil {
34
return nil, err
35
}
36
37
feed := &feeds.Feed{
38
+
Title: fmt.Sprintf("activity feed for @%s", ownerSlashRepo),
39
+
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s", rp.config.Core.AppviewHost, ownerSlashRepo), Type: "text/html", Rel: "alternate"},
40
Items: make([]*feeds.Item, 0),
41
Updated: time.UnixMilli(0),
42
}
43
44
for _, pull := range pulls {
45
+
items, err := rp.createPullItems(ctx, pull, repo, ownerSlashRepo)
46
if err != nil {
47
return nil, err
48
}
···
50
}
51
52
for _, issue := range issues {
53
+
item, err := rp.createIssueItem(ctx, issue, repo, ownerSlashRepo)
54
if err != nil {
55
return nil, err
56
}
···
71
return feed, nil
72
}
73
74
+
func (rp *Repo) createPullItems(ctx context.Context, pull *models.Pull, repo *models.Repo, ownerSlashRepo string) ([]*feeds.Item, error) {
75
owner, err := rp.idResolver.ResolveIdent(ctx, pull.OwnerDid)
76
if err != nil {
77
return nil, err
···
80
var items []*feeds.Item
81
82
state := rp.getPullState(pull)
83
+
description := rp.buildPullDescription(owner.Handle, state, pull, ownerSlashRepo)
84
85
mainItem := &feeds.Item{
86
Title: fmt.Sprintf("[PR #%d] %s", pull.PullId, pull.Title),
87
Description: description,
88
+
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/pulls/%d", rp.config.Core.AppviewHost, ownerSlashRepo, pull.PullId)},
89
Created: pull.Created,
90
Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)},
91
}
···
98
99
roundItem := &feeds.Item{
100
Title: fmt.Sprintf("[PR #%d] %s (round #%d)", pull.PullId, pull.Title, round.RoundNumber),
101
+
Description: fmt.Sprintf("@%s submitted changes (at round #%d) on PR #%d in @%s", owner.Handle, round.RoundNumber, pull.PullId, ownerSlashRepo),
102
+
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/pulls/%d/round/%d/", rp.config.Core.AppviewHost, ownerSlashRepo, pull.PullId, round.RoundNumber)},
103
Created: round.Created,
104
Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)},
105
}
···
109
return items, nil
110
}
111
112
+
func (rp *Repo) createIssueItem(ctx context.Context, issue models.Issue, repo *models.Repo, ownerSlashRepo string) (*feeds.Item, error) {
113
owner, err := rp.idResolver.ResolveIdent(ctx, issue.Did)
114
if err != nil {
115
return nil, err
···
122
123
return &feeds.Item{
124
Title: fmt.Sprintf("[Issue #%d] %s", issue.IssueId, issue.Title),
125
+
Description: fmt.Sprintf("@%s %s issue #%d in @%s", owner.Handle, state, issue.IssueId, ownerSlashRepo),
126
+
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/issues/%d", rp.config.Core.AppviewHost, ownerSlashRepo, issue.IssueId)},
127
Created: issue.Created,
128
Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)},
129
}, nil
···
152
log.Println("failed to fully resolve repo:", err)
153
return
154
}
155
+
repoOwnerId, ok := r.Context().Value("resolvedId").(identity.Identity)
156
+
if !ok || repoOwnerId.Handle.IsInvalidHandle() {
157
+
log.Println("failed to get resolved repo owner id")
158
+
return
159
+
}
160
+
ownerSlashRepo := repoOwnerId.Handle.String() + "/" + f.Name
161
162
+
feed, err := rp.getRepoFeed(r.Context(), &f.Repo, ownerSlashRepo)
163
if err != nil {
164
log.Println("failed to get repo feed:", err)
165
rp.pages.Error500(w)
NEW
appview/repo/index.go
NEW
appview/repo/index.go
···
179
180
if err != nil || langs == nil {
181
// non-fatal, fetch langs from ks via XRPC
182
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
183
ls, err := tangled.RepoLanguages(ctx, xrpcc, currentRef, repo)
184
if err != nil {
185
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
···
256
257
// buildIndexResponse creates a RepoIndexResponse by combining multiple xrpc calls in parallel
258
func (rp *Repo) buildIndexResponse(ctx context.Context, xrpcc *indigoxrpc.Client, f *reporesolver.ResolvedRepo, ref string) (*types.RepoIndexResponse, error) {
259
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
260
261
// first get branches to determine the ref if not specified
262
branchesBytes, err := tangled.RepoBranches(ctx, xrpcc, "", 0, repo)
···
179
180
if err != nil || langs == nil {
181
// non-fatal, fetch langs from ks via XRPC
182
+
repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
183
ls, err := tangled.RepoLanguages(ctx, xrpcc, currentRef, repo)
184
if err != nil {
185
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
···
256
257
// buildIndexResponse creates a RepoIndexResponse by combining multiple xrpc calls in parallel
258
func (rp *Repo) buildIndexResponse(ctx context.Context, xrpcc *indigoxrpc.Client, f *reporesolver.ResolvedRepo, ref string) (*types.RepoIndexResponse, error) {
259
+
repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
260
261
// first get branches to determine the ref if not specified
262
branchesBytes, err := tangled.RepoBranches(ctx, xrpcc, "", 0, repo)
NEW
appview/repo/log.go
NEW
appview/repo/log.go
···
57
cursor = strconv.Itoa(offset)
58
}
59
60
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
61
xrpcBytes, err := tangled.RepoLog(r.Context(), xrpcc, cursor, limit, "", ref, repo)
62
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
63
l.Error("failed to call XRPC repo.log", "err", xrpcerr)
···
174
Host: host,
175
}
176
177
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
178
xrpcBytes, err := tangled.RepoDiff(r.Context(), xrpcc, ref, repo)
179
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
180
l.Error("failed to call XRPC repo.diff", "err", xrpcerr)
···
57
cursor = strconv.Itoa(offset)
58
}
59
60
+
repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
61
xrpcBytes, err := tangled.RepoLog(r.Context(), xrpcc, cursor, limit, "", ref, repo)
62
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
63
l.Error("failed to call XRPC repo.log", "err", xrpcerr)
···
174
Host: host,
175
}
176
177
+
repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
178
xrpcBytes, err := tangled.RepoDiff(r.Context(), xrpcc, ref, repo)
179
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
180
l.Error("failed to call XRPC repo.diff", "err", xrpcerr)
NEW
appview/repo/repo.go
NEW
appview/repo/repo.go
···
864
r.Context(),
865
client,
866
&tangled.RepoDelete_Input{
867
-
Did: f.OwnerDid(),
868
Name: f.Name,
869
Rkey: f.Rkey,
870
},
···
902
l.Info("removed collaborators")
903
904
// remove repo RBAC
905
-
err = rp.enforcer.RemoveRepo(f.OwnerDid(), f.Knot, f.DidSlashRepo())
906
if err != nil {
907
rp.pages.Notice(w, noticeId, "Failed to update RBAC rules")
908
return
909
}
910
911
// remove repo from db
912
-
err = db.RemoveRepo(tx, f.OwnerDid(), f.Name)
913
if err != nil {
914
rp.pages.Notice(w, noticeId, "Failed to update appview")
915
return
···
930
return
931
}
932
933
-
rp.pages.HxRedirect(w, fmt.Sprintf("/%s", f.OwnerDid()))
934
}
935
936
func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) {
···
1058
uri = "http"
1059
}
1060
1061
-
forkSourceUrl := fmt.Sprintf("%s://%s/%s/%s", uri, f.Knot, f.OwnerDid(), f.Repo.Name)
1062
l = l.With("cloneUrl", forkSourceUrl)
1063
1064
sourceAt := f.RepoAt().String()
···
864
r.Context(),
865
client,
866
&tangled.RepoDelete_Input{
867
+
Did: f.Did,
868
Name: f.Name,
869
Rkey: f.Rkey,
870
},
···
902
l.Info("removed collaborators")
903
904
// remove repo RBAC
905
+
err = rp.enforcer.RemoveRepo(f.Did, f.Knot, f.DidSlashRepo())
906
if err != nil {
907
rp.pages.Notice(w, noticeId, "Failed to update RBAC rules")
908
return
909
}
910
911
// remove repo from db
912
+
err = db.RemoveRepo(tx, f.Did, f.Name)
913
if err != nil {
914
rp.pages.Notice(w, noticeId, "Failed to update appview")
915
return
···
930
return
931
}
932
933
+
rp.pages.HxRedirect(w, fmt.Sprintf("/%s", f.Did))
934
}
935
936
func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) {
···
1058
uri = "http"
1059
}
1060
1061
+
forkSourceUrl := fmt.Sprintf("%s://%s/%s/%s", uri, f.Knot, f.Did, f.Repo.Name)
1062
l = l.With("cloneUrl", forkSourceUrl)
1063
1064
sourceAt := f.RepoAt().String()
NEW
appview/repo/settings.go
NEW
appview/repo/settings.go
···
194
Host: host,
195
}
196
197
-
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
198
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
199
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
200
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
···
292
user := rp.oauth.GetUser(r)
293
294
// all spindles that the repo owner is a member of
295
-
spindles, err := rp.enforcer.GetSpindlesForUser(f.OwnerDid())
296
if err != nil {
297
l.Error("failed to fetch spindles", "err", err)
298
return
···
194
Host: host,
195
}
196
197
+
repo := fmt.Sprintf("%s/%s", f.Did, f.Name)
198
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
199
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
200
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
···
292
user := rp.oauth.GetUser(r)
293
294
// all spindles that the repo owner is a member of
295
+
spindles, err := rp.enforcer.GetSpindlesForUser(f.Did)
296
if err != nil {
297
l.Error("failed to fetch spindles", "err", err)
298
return