Add a list user and repo endpoint on the knot. It is useful when browsing the knot directly and not requiring indexing it via another service.
+51
api/tangled/repolistRepos.go
+51
api/tangled/repolistRepos.go
···
1
+
// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
2
+
3
+
package tangled
4
+
5
+
// schema: sh.tangled.repo.listRepos
6
+
7
+
import (
8
+
"context"
9
+
10
+
"github.com/bluesky-social/indigo/lex/util"
11
+
)
12
+
13
+
const (
14
+
RepoListReposNSID = "sh.tangled.repo.listRepos"
15
+
)
16
+
17
+
// RepoListRepos_Output is the output of a sh.tangled.repo.listRepos call.
18
+
type RepoListRepos_Output struct {
19
+
Users []*RepoListRepos_User `json:"users" cborgen:"users"`
20
+
}
21
+
22
+
// RepoListRepos_RepoEntry is a "repoEntry" in the sh.tangled.repo.listRepos schema.
23
+
type RepoListRepos_RepoEntry struct {
24
+
// defaultBranch: Default branch of the repository
25
+
DefaultBranch *string `json:"defaultBranch,omitempty" cborgen:"defaultBranch,omitempty"`
26
+
// did: DID of the repository owner
27
+
Did string `json:"did" cborgen:"did"`
28
+
// fullPath: Full path to the repository
29
+
FullPath string `json:"fullPath" cborgen:"fullPath"`
30
+
// name: Repository name
31
+
Name string `json:"name" cborgen:"name"`
32
+
}
33
+
34
+
// RepoListRepos_User is a "user" in the sh.tangled.repo.listRepos schema.
35
+
type RepoListRepos_User struct {
36
+
// did: DID of the user
37
+
Did string `json:"did" cborgen:"did"`
38
+
Repos []*RepoListRepos_RepoEntry `json:"repos" cborgen:"repos"`
39
+
}
40
+
41
+
// RepoListRepos calls the XRPC method "sh.tangled.repo.listRepos".
42
+
func RepoListRepos(ctx context.Context, c util.LexClient) (*RepoListRepos_Output, error) {
43
+
var out RepoListRepos_Output
44
+
45
+
params := map[string]interface{}{}
46
+
if err := c.LexDo(ctx, util.Query, "", "sh.tangled.repo.listRepos", params, nil, &out); err != nil {
47
+
return nil, err
48
+
}
49
+
50
+
return &out, nil
51
+
}
+13
-5
go.mod
+13
-5
go.mod
···
45
45
github.com/urfave/cli/v3 v3.3.3
46
46
github.com/whyrusleeping/cbor-gen v0.3.1
47
47
github.com/yuin/goldmark v1.7.13
48
+
github.com/yuin/goldmark-emoji v1.0.6
48
49
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
49
50
gitlab.com/staticnoise/goldmark-callout v0.0.0-20240609120641-6366b799e4ab
50
-
golang.org/x/crypto v0.40.0
51
+
golang.org/x/crypto v0.41.0
51
52
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
52
53
golang.org/x/image v0.31.0
53
-
golang.org/x/net v0.42.0
54
-
golang.org/x/sync v0.17.0
54
+
golang.org/x/net v0.43.0
55
55
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da
56
56
gopkg.in/yaml.v3 v3.0.1
57
57
)
···
96
96
github.com/containerd/errdefs v1.0.0 // indirect
97
97
github.com/containerd/errdefs/pkg v0.3.0 // indirect
98
98
github.com/containerd/log v0.1.0 // indirect
99
+
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
99
100
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
100
101
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
101
102
github.com/distribution/reference v0.6.0 // indirect
···
183
184
github.com/prometheus/common v0.64.0 // indirect
184
185
github.com/prometheus/procfs v0.16.1 // indirect
185
186
github.com/rivo/uniseg v0.4.7 // indirect
187
+
github.com/russross/blackfriday/v2 v2.1.0 // indirect
186
188
github.com/ryanuber/go-glob v1.0.0 // indirect
187
189
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
188
190
github.com/spaolacci/murmur3 v1.1.0 // indirect
191
+
github.com/urfave/cli/v2 v2.27.5 // indirect
189
192
github.com/vmihailenco/go-tinylfu v0.2.2 // indirect
190
193
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
191
194
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
192
195
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
193
-
github.com/yuin/goldmark-emoji v1.0.6 // indirect
196
+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
194
197
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
195
198
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
196
199
go.etcd.io/bbolt v1.4.0 // indirect
···
204
207
go.uber.org/atomic v1.11.0 // indirect
205
208
go.uber.org/multierr v1.11.0 // indirect
206
209
go.uber.org/zap v1.27.0 // indirect
207
-
golang.org/x/sys v0.34.0 // indirect
210
+
golang.org/x/mod v0.27.0 // indirect
211
+
golang.org/x/sync v0.17.0 // indirect
212
+
golang.org/x/sys v0.35.0 // indirect
208
213
golang.org/x/text v0.29.0 // indirect
209
214
golang.org/x/time v0.12.0 // indirect
215
+
golang.org/x/tools v0.36.0 // indirect
210
216
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
211
217
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
212
218
google.golang.org/grpc v1.73.0 // indirect
···
228
234
229
235
// from bluesky-social/indigo
230
236
replace github.com/gocql/gocql => github.com/scylladb/gocql v1.14.4
237
+
238
+
tool github.com/bluesky-social/indigo/cmd/lexgen
+20
-8
go.sum
+20
-8
go.sum
···
118
118
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
119
119
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
120
120
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
121
+
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
122
+
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
121
123
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
122
124
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
123
125
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
···
449
451
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
450
452
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
451
453
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
454
+
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
455
+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
452
456
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
453
457
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
454
458
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
···
482
486
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
483
487
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
484
488
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
489
+
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
490
+
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
485
491
github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I=
486
492
github.com/urfave/cli/v3 v3.3.3/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo=
487
493
github.com/vmihailenco/go-tinylfu v0.2.2 h1:H1eiG6HM36iniK6+21n9LLpzx1G9R3DJa2UjUjbynsI=
···
497
503
github.com/whyrusleeping/cbor-gen v0.3.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so=
498
504
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
499
505
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
506
+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
507
+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
500
508
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
501
509
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
502
510
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
···
558
566
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
559
567
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
560
568
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
561
-
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
562
-
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
569
+
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
570
+
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
563
571
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
564
572
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
565
573
golang.org/x/image v0.31.0 h1:mLChjE2MV6g1S7oqbXC0/UcKijjm5fnJLUYKIYrLESA=
···
574
582
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
575
583
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
576
584
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
585
+
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
586
+
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
577
587
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
578
588
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
579
589
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
···
594
604
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
595
605
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
596
606
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
597
-
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
598
-
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
607
+
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
608
+
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
599
609
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
600
610
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
601
611
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
···
635
645
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
636
646
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
637
647
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
638
-
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
639
-
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
648
+
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
649
+
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
640
650
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
641
651
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
642
652
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
···
646
656
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
647
657
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
648
658
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
649
-
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
650
-
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
659
+
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
660
+
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
651
661
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
652
662
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
653
663
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
···
679
689
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
680
690
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
681
691
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
692
+
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
693
+
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
682
694
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
683
695
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
684
696
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+103
knotserver/xrpc/list_repos.go
+103
knotserver/xrpc/list_repos.go
···
1
+
package xrpc
2
+
3
+
import (
4
+
"net/http"
5
+
"os"
6
+
"path/filepath"
7
+
"strings"
8
+
9
+
securejoin "github.com/cyphar/filepath-securejoin"
10
+
"tangled.org/core/api/tangled"
11
+
"tangled.org/core/knotserver/git"
12
+
xrpcerr "tangled.org/core/xrpc/errors"
13
+
)
14
+
15
+
// ListRepos lists all users (DIDs) and their repositories by scanning the repository directory
16
+
func (x *Xrpc) ListRepos(w http.ResponseWriter, r *http.Request) {
17
+
scanPath := x.Config.Repo.ScanPath
18
+
19
+
didEntries, err := os.ReadDir(scanPath)
20
+
if err != nil {
21
+
x.Logger.Error("failed to read scan path", "error", err, "path", scanPath)
22
+
writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError)
23
+
return
24
+
}
25
+
26
+
var users []*tangled.RepoListRepos_User
27
+
28
+
for _, didEntry := range didEntries {
29
+
if !didEntry.IsDir() {
30
+
continue
31
+
}
32
+
33
+
did := didEntry.Name()
34
+
35
+
// Validate DID format (basic check)
36
+
if !strings.HasPrefix(did, "did:") {
37
+
continue
38
+
}
39
+
40
+
didPath, err := securejoin.SecureJoin(scanPath, did)
41
+
if err != nil {
42
+
x.Logger.Warn("failed to join path for did", "did", did, "error", err)
43
+
continue
44
+
}
45
+
46
+
// Read repositories for this DID
47
+
repoEntries, err := os.ReadDir(didPath)
48
+
if err != nil {
49
+
x.Logger.Warn("failed to read did directory", "did", did, "error", err)
50
+
continue
51
+
}
52
+
53
+
var repos []*tangled.RepoListRepos_RepoEntry
54
+
55
+
for _, repoEntry := range repoEntries {
56
+
if !repoEntry.IsDir() {
57
+
continue
58
+
}
59
+
60
+
repoName := repoEntry.Name()
61
+
62
+
// Check if it's a valid git repository
63
+
repoPath, err := securejoin.SecureJoin(didPath, repoName)
64
+
if err != nil {
65
+
continue
66
+
}
67
+
68
+
repo, err := git.PlainOpen(repoPath)
69
+
if err != nil {
70
+
// Not a valid git repository, skip
71
+
continue
72
+
}
73
+
74
+
// Get default branch
75
+
defaultBranch := "master"
76
+
branch, err := repo.FindMainBranch()
77
+
if err == nil {
78
+
defaultBranch = branch
79
+
}
80
+
81
+
repos = append(repos, &tangled.RepoListRepos_RepoEntry{
82
+
Name: repoName,
83
+
Did: did,
84
+
FullPath: filepath.Join(did, repoName),
85
+
DefaultBranch: &defaultBranch,
86
+
})
87
+
}
88
+
89
+
// Only add user if they have repositories
90
+
if len(repos) > 0 {
91
+
users = append(users, &tangled.RepoListRepos_User{
92
+
Did: did,
93
+
Repos: repos,
94
+
})
95
+
}
96
+
}
97
+
98
+
response := tangled.RepoListRepos_Output{
99
+
Users: users,
100
+
}
101
+
102
+
writeJson(w, response)
103
+
}
+1
knotserver/xrpc/xrpc.go
+1
knotserver/xrpc/xrpc.go
+71
lexicons/repo/listRepos.json
+71
lexicons/repo/listRepos.json
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "sh.tangled.repo.listRepos",
4
+
"defs": {
5
+
"main": {
6
+
"type": "query",
7
+
"description": "Lists all users (DIDs) and their repositories",
8
+
"parameters": {
9
+
"type": "params",
10
+
"properties": {}
11
+
},
12
+
"output": {
13
+
"encoding": "application/json",
14
+
"schema": {
15
+
"type": "object",
16
+
"required": ["users"],
17
+
"properties": {
18
+
"users": {
19
+
"type": "array",
20
+
"items": {
21
+
"type": "ref",
22
+
"ref": "#user"
23
+
}
24
+
}
25
+
}
26
+
}
27
+
}
28
+
},
29
+
"user": {
30
+
"type": "object",
31
+
"required": ["did", "repos"],
32
+
"properties": {
33
+
"did": {
34
+
"type": "string",
35
+
"format": "did",
36
+
"description": "DID of the user"
37
+
},
38
+
"repos": {
39
+
"type": "array",
40
+
"items": {
41
+
"type": "ref",
42
+
"ref": "#repoEntry"
43
+
}
44
+
}
45
+
}
46
+
},
47
+
"repoEntry": {
48
+
"type": "object",
49
+
"required": ["name", "did", "fullPath"],
50
+
"properties": {
51
+
"name": {
52
+
"type": "string",
53
+
"description": "Repository name"
54
+
},
55
+
"did": {
56
+
"type": "string",
57
+
"format": "did",
58
+
"description": "DID of the repository owner"
59
+
},
60
+
"fullPath": {
61
+
"type": "string",
62
+
"description": "Full path to the repository"
63
+
},
64
+
"defaultBranch": {
65
+
"type": "string",
66
+
"description": "Default branch of the repository"
67
+
}
68
+
}
69
+
}
70
+
}
71
+
}
History
3 rounds
1 comment
expand 1 comment
closed without merging
julien.rbrt.fr
submitted
#1
expand 0 comments
julien.rbrt.fr
submitted
#0
we have some reworks around this planned, along with refining our knotserver APIs, so ill be closing this in favor of future changes. one of the things is that we will be backfilling repo info in knots using tap, and subsequently, all XRPC APIs can speak ATURIs instead of
did/repo-name.i really do appreciate the effort gone into this!