Monorepo for Tangled tangled.org

knotserver/xrpc: add list repo endpoint #903

closed opened by julien.rbrt.fr targeting master from julien.rbrt.fr/tangled-core: julien/listrepo

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.

Labels

None yet.

assignee

None yet.

Participants 2
AT URI
at://did:plc:7kpq3n7brenbgyp2gx36hl6x/sh.tangled.repo.pull/3maelm6pqks22
+259 -13
Diff #0
+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
··· 45 github.com/urfave/cli/v3 v3.3.3 46 github.com/whyrusleeping/cbor-gen v0.3.1 47 github.com/yuin/goldmark v1.7.13 48 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc 49 gitlab.com/staticnoise/goldmark-callout v0.0.0-20240609120641-6366b799e4ab 50 - golang.org/x/crypto v0.40.0 51 golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b 52 golang.org/x/image v0.31.0 53 - golang.org/x/net v0.42.0 54 - golang.org/x/sync v0.17.0 55 golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da 56 gopkg.in/yaml.v3 v3.0.1 57 ) ··· 96 github.com/containerd/errdefs v1.0.0 // indirect 97 github.com/containerd/errdefs/pkg v0.3.0 // indirect 98 github.com/containerd/log v0.1.0 // indirect 99 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 100 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 101 github.com/distribution/reference v0.6.0 // indirect ··· 183 github.com/prometheus/common v0.64.0 // indirect 184 github.com/prometheus/procfs v0.16.1 // indirect 185 github.com/rivo/uniseg v0.4.7 // indirect 186 github.com/ryanuber/go-glob v1.0.0 // indirect 187 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect 188 github.com/spaolacci/murmur3 v1.1.0 // indirect 189 github.com/vmihailenco/go-tinylfu v0.2.2 // indirect 190 github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect 191 github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 192 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect 193 - github.com/yuin/goldmark-emoji v1.0.6 // indirect 194 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect 195 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect 196 go.etcd.io/bbolt v1.4.0 // indirect ··· 204 go.uber.org/atomic v1.11.0 // indirect 205 go.uber.org/multierr v1.11.0 // indirect 206 go.uber.org/zap v1.27.0 // indirect 207 - golang.org/x/sys v0.34.0 // indirect 208 golang.org/x/text v0.29.0 // indirect 209 golang.org/x/time v0.12.0 // indirect 210 google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect 211 google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect 212 google.golang.org/grpc v1.73.0 // indirect ··· 228 229 // from bluesky-social/indigo 230 replace github.com/gocql/gocql => github.com/scylladb/gocql v1.14.4
··· 45 github.com/urfave/cli/v3 v3.3.3 46 github.com/whyrusleeping/cbor-gen v0.3.1 47 github.com/yuin/goldmark v1.7.13 48 + github.com/yuin/goldmark-emoji v1.0.6 49 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc 50 gitlab.com/staticnoise/goldmark-callout v0.0.0-20240609120641-6366b799e4ab 51 + golang.org/x/crypto v0.41.0 52 golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b 53 golang.org/x/image v0.31.0 54 + golang.org/x/net v0.43.0 55 golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da 56 gopkg.in/yaml.v3 v3.0.1 57 ) ··· 96 github.com/containerd/errdefs v1.0.0 // indirect 97 github.com/containerd/errdefs/pkg v0.3.0 // indirect 98 github.com/containerd/log v0.1.0 // indirect 99 + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect 100 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 101 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 102 github.com/distribution/reference v0.6.0 // indirect ··· 184 github.com/prometheus/common v0.64.0 // indirect 185 github.com/prometheus/procfs v0.16.1 // indirect 186 github.com/rivo/uniseg v0.4.7 // indirect 187 + github.com/russross/blackfriday/v2 v2.1.0 // indirect 188 github.com/ryanuber/go-glob v1.0.0 // indirect 189 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect 190 github.com/spaolacci/murmur3 v1.1.0 // indirect 191 + github.com/urfave/cli/v2 v2.27.5 // indirect 192 github.com/vmihailenco/go-tinylfu v0.2.2 // indirect 193 github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect 194 github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 195 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect 196 + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect 197 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect 198 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect 199 go.etcd.io/bbolt v1.4.0 // indirect ··· 207 go.uber.org/atomic v1.11.0 // indirect 208 go.uber.org/multierr v1.11.0 // indirect 209 go.uber.org/zap v1.27.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 213 golang.org/x/text v0.29.0 // indirect 214 golang.org/x/time v0.12.0 // indirect 215 + golang.org/x/tools v0.36.0 // indirect 216 google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect 217 google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect 218 google.golang.org/grpc v1.73.0 // indirect ··· 234 235 // from bluesky-social/indigo 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
··· 118 github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= 119 github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= 120 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 121 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 122 github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= 123 github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= ··· 449 github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= 450 github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 451 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 452 github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= 453 github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= 454 github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= ··· 482 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 483 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 484 github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= 485 github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I= 486 github.com/urfave/cli/v3 v3.3.3/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= 487 github.com/vmihailenco/go-tinylfu v0.2.2 h1:H1eiG6HM36iniK6+21n9LLpzx1G9R3DJa2UjUjbynsI= ··· 497 github.com/whyrusleeping/cbor-gen v0.3.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= 498 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= 499 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= 500 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 501 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 502 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= ··· 558 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 559 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= 560 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= 563 golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= 564 golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= 565 golang.org/x/image v0.31.0 h1:mLChjE2MV6g1S7oqbXC0/UcKijjm5fnJLUYKIYrLESA= ··· 574 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= 575 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 576 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 577 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 578 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 579 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= ··· 594 golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= 595 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 596 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= 599 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 600 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 601 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= ··· 635 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 636 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 637 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= 640 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 641 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 642 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= ··· 646 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 647 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 648 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= 651 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 652 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 653 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= ··· 679 golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= 680 golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= 681 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 682 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 683 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 684 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
··· 118 github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= 119 github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= 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= 123 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 124 github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= 125 github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= ··· 451 github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= 452 github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 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= 456 github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= 457 github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= 458 github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= ··· 486 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 487 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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= 491 github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I= 492 github.com/urfave/cli/v3 v3.3.3/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= 493 github.com/vmihailenco/go-tinylfu v0.2.2 h1:H1eiG6HM36iniK6+21n9LLpzx1G9R3DJa2UjUjbynsI= ··· 503 github.com/whyrusleeping/cbor-gen v0.3.1/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= 504 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= 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= 508 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 509 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 510 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= ··· 566 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 567 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= 568 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 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= 571 golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= 572 golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= 573 golang.org/x/image v0.31.0 h1:mLChjE2MV6g1S7oqbXC0/UcKijjm5fnJLUYKIYrLESA= ··· 582 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= 583 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= 587 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 588 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 589 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= ··· 604 golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= 605 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 606 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 607 + golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= 608 + golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= 609 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 610 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 611 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= ··· 645 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 646 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 647 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 648 + golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= 649 + golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 650 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 651 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 652 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= ··· 656 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 657 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 658 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= 659 + golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= 660 + golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= 661 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 662 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 663 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= ··· 689 golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= 690 golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= 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= 694 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 695 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 696 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+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
··· 73 74 // service query endpoints (no auth required) 75 r.Get("/"+tangled.OwnerNSID, x.Owner) 76 77 return r 78 }
··· 73 74 // service query endpoints (no auth required) 75 r.Get("/"+tangled.OwnerNSID, x.Owner) 76 + r.Get("/"+tangled.RepoListReposNSID, x.ListRepos) 77 78 return r 79 }
+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
sign up or login to add to the discussion
3 commits
expand
feat(knotserver): add list repo endpoint
use lexgen
chore: revert to main go.mod
expand 1 comment

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!

closed without merging
2 commits
expand
feat(knotserver): add list repo endpoint
use lexgen
expand 0 comments
julien.rbrt.fr submitted #0
2 commits
expand
feat(knotserver): add list repo endpoint
use lexgen
expand 0 comments