-2
.github/workflows/release.yaml
-2
.github/workflows/release.yaml
+40
-3
README.md
+40
-3
README.md
···
22
22
atr show -t post
23
23
24
24
# use jq query language
25
-
atr show -q .displayName
25
+
atr show -q .body.displayName
26
+
27
+
# use jmespath query language
28
+
atr show -q body.displayName
26
29
27
30
# Search with grep:
28
31
atr show -t post | grep love
29
32
30
33
# Repositories can also be read via pipe:
31
-
curl -sL "https://xrpc.link/r/atproto.com" | atr show
34
+
curl -sL "https://enoki.us-east.host.bsky.network/xrpc/com.atproto.sync.getRepo?did=did:plc:ewvi7nxzyoun6zhxrhs64oiz" | atr show
35
+
curl -sL "xrpc.link/r/atproto.com" | atr show
32
36
33
37
# FYI xrpc.link is shortcut domain which redirecting to
34
38
# relevant /xrpc/... endpoints
35
39
```
36
40
41
+
Example output:
42
+
```bash
43
+
~> curl -sL "https://enoki.us-east.host.bsky.network/xrpc/com.atproto.sync.getRepo?did=did:plc:ewvi7nxzyoun6zhxrhs64oiz" | atr i
44
+
45
+
(pipe):
46
+
DID: did:plc:ewvi7nxzyoun6zhxrhs64oiz Repo Version: 3
47
+
Head: bafyreiapeyhetsiuz6jcybcmgxw7k45imuu22shmbhybccq4vef57fc4mi
48
+
Sig: d03ed428c77a9e4964560f575426f81ed694861c93372b866d77b3b1f814a39b4d27033fa86593e194dfe07278a96aa1a9b76f1b2f7ff8d4313130b557177fb1
49
+
Size: 566 kB Blocks: 1,837 Commits: 1 Objects: 1,434
50
+
Profile:
51
+
Display Name: AT Protocol Developers
52
+
Description: Social networking technology created by Bluesky.
53
+
54
+
Developer-focused account. Follow @bsky.app for general announcements!
55
+
56
+
Bluesky API docs: docs.bsky.app
57
+
AT Protocol specs: atproto.com
58
+
Collections:
59
+
app.bsky.actor.profile: 1
60
+
app.bsky.feed.generator: 2
61
+
app.bsky.feed.like: 686
62
+
app.bsky.feed.post: 150
63
+
app.bsky.feed.repost: 541
64
+
app.bsky.feed.threadgate: 1
65
+
app.bsky.graph.follow: 21
66
+
app.bsky.graph.list: 1
67
+
app.bsky.graph.listitem: 29
68
+
app.bsky.graph.starterpack: 1
69
+
chat.bsky.actor.declaration: 1
70
+
Last 5 commits:
71
+
bafyreiapeyhetsiuz6jcybcmgxw7k45imuu22shmbhybccq4vef57fc4mi
72
+
```
73
+
37
74
## License
38
75
39
-
MIT
76
+
MIT
+2
atr.go
+2
atr.go
+6
-2
cli/context.go
+6
-2
cli/context.go
+13
-2
cli/print.go
+13
-2
cli/print.go
···
6
6
"log"
7
7
"os"
8
8
9
+
"github.com/atscan/atr/repo"
9
10
jsoniter "github.com/json-iterator/go"
10
11
)
11
12
12
-
func Print(v interface{}) error {
13
+
type ObjectOutput struct {
14
+
Did string `json:"did"`
15
+
Rkey string `json:"rkey"`
16
+
Cid string `json:"cid"`
17
+
Body interface{} `json:"body"`
18
+
Match interface{} `json:"-"`
19
+
}
20
+
21
+
func Print(v interface{}, ri repo.RepoItem, rs repo.RepoSnapshot) error {
22
+
13
23
json, err := jsoniter.Marshal(v)
14
24
if err != nil {
15
25
log.Fatal(err)
···
22
32
return nil
23
33
}
24
34
25
-
func PrettyPrint(v interface{}, hg func(io.Writer, string)) error {
35
+
func PrettyPrint(v interface{}, ri repo.RepoItem, rs repo.RepoSnapshot, hg func(io.Writer, string)) error {
36
+
26
37
json, err := jsoniter.MarshalIndent(v, "", " ")
27
38
if err != nil {
28
39
log.Fatal(err)
+60
-4
cmd/atr-inspect.go
+60
-4
cmd/atr-inspect.go
···
1
1
package cmd
2
2
3
3
import (
4
+
"context"
5
+
"encoding/hex"
4
6
"fmt"
5
7
"os"
8
+
"sort"
9
+
"strings"
6
10
7
11
"github.com/atscan/atr/cli"
8
12
"github.com/atscan/atr/engine"
···
13
17
)
14
18
15
19
func init() {
16
-
rootCmd.AddCommand(InspectCmd)
20
+
rootCmd.AddCommand(LsCmd)
17
21
}
18
22
19
-
var InspectCmd = &cobra.Command{
23
+
var LsCmd = &cobra.Command{
20
24
Use: "inspect",
21
25
Aliases: []string{"i"},
22
26
Short: "Inspect repo(s)",
···
26
30
WorkingDir: workingDir,
27
31
Args: args,
28
32
}
29
-
33
+
fmt.Println("")
30
34
walk := func(ss repo.RepoSnapshot, err error) {
31
35
if ss.Root.String() == "b" {
32
36
return
···
36
40
}
37
41
yellow := color.New(color.FgYellow).SprintFunc()
38
42
cyan := color.New(color.FgCyan).SprintFunc()
39
-
fmt.Printf("%v:\n Head: %s\n Size: %s Items: %v\n\n", yellow(ss.File), cyan(ss.Root.String()), cyan(humanize.Bytes(uint64(ss.Size))), cyan(humanize.Comma(int64(len(ss.Items)))))
43
+
boldCyan := color.New(color.FgCyan, color.Bold).SprintFunc()
44
+
green := color.New(color.FgGreen).SprintFunc()
45
+
46
+
fmt.Printf("%v:\n", yellow(ss.File))
47
+
fmt.Printf(" DID: %s Repo Version: %v\n", boldCyan(ss.Repo.SignedCommit().Did), cyan(ss.Repo.SignedCommit().Version))
48
+
fmt.Printf(" Head: %s\n", cyan(ss.Root.String()))
49
+
fmt.Printf(" Sig: %s\n", cyan(hex.EncodeToString(ss.Repo.SignedCommit().Sig)))
50
+
51
+
stats, _ := ss.GetCollectionStats("")
52
+
keys := make([]string, 0, len(stats))
53
+
total := 0
54
+
for k := range stats {
55
+
keys = append(keys, k)
56
+
total += stats[k]
57
+
}
58
+
sort.Strings(keys)
59
+
cp, _ := ss.Repo.GetCommitsPath(-1)
60
+
_, v, _ := ss.Repo.GetRecord(context.TODO(), "app.bsky.actor.profile/self")
61
+
62
+
dn := v["displayName"]
63
+
if dn != nil {
64
+
dn = boldCyan(dn)
65
+
} else {
66
+
dn = "(empty)"
67
+
}
68
+
desc := v["description"]
69
+
if desc != nil {
70
+
desc = cyan(strings.Replace(desc.(string), "\n", "\n ", -1))
71
+
} else {
72
+
desc = "(empty)"
73
+
}
74
+
75
+
fmt.Printf(" Size: %s Blocks: %v Commits: %v Objects: %v\n", cyan(humanize.Bytes(uint64(ss.Size))), cyan(humanize.Comma(int64(ss.Repo.Blocks))), cyan(humanize.Comma(int64(len(cp)))), cyan(humanize.Comma(int64(total))))
76
+
fmt.Printf(" Profile:\n")
77
+
fmt.Printf(" Display Name: %v\n", dn)
78
+
fmt.Printf(" Description: %v\n", desc)
79
+
80
+
fmt.Printf(" Collections:\n")
81
+
for _, k := range keys {
82
+
fmt.Printf(" %s: %v\n", green(k), cyan(humanize.Comma(int64(stats[k]))))
83
+
}
84
+
fmt.Printf(" Last 5 commits:\n")
85
+
for i, cid := range cp {
86
+
fmt.Printf(" %v\n", cyan(cid.String()))
87
+
if i >= 5 {
88
+
break
89
+
}
90
+
}
91
+
if len(cp) > 5 {
92
+
fmt.Printf(" %s\n", cyan("..."))
93
+
}
94
+
95
+
fmt.Println("")
40
96
}
41
97
42
98
stat, _ := os.Stdin.Stat()
+71
cmd/atr-log.go
+71
cmd/atr-log.go
···
1
+
package cmd
2
+
3
+
import (
4
+
"fmt"
5
+
"os"
6
+
7
+
"github.com/atscan/atr/cli"
8
+
"github.com/atscan/atr/engine"
9
+
"github.com/atscan/atr/repo"
10
+
"github.com/fatih/color"
11
+
"github.com/spf13/cobra"
12
+
)
13
+
14
+
var (
15
+
LogRaw bool
16
+
)
17
+
18
+
func init() {
19
+
rootCmd.AddCommand(LogCmd)
20
+
LogCmd.Flags().BoolVar(&LogRaw, "raw", false, "Do not use colors (faster)")
21
+
}
22
+
23
+
var LogCmd = &cobra.Command{
24
+
Use: "log [target] [--raw]",
25
+
Aliases: []string{"l"},
26
+
Short: "Show commit history (path)",
27
+
Long: ``,
28
+
Run: func(cmd *cobra.Command, args []string) {
29
+
ctx := cli.Context{
30
+
WorkingDir: workingDir,
31
+
Args: args,
32
+
Raw: Raw,
33
+
}
34
+
walk := func(ss repo.RepoSnapshot, err error) {
35
+
if ss.Root.String() == "b" {
36
+
return
37
+
}
38
+
cp, _ := ss.Repo.GetCommitsPath(-1)
39
+
//cp = util.ReverseCidSlice(cp)
40
+
41
+
if LogRaw {
42
+
for _, cid := range cp {
43
+
fmt.Printf("%v\n", cid.String())
44
+
}
45
+
} else {
46
+
yellow := color.New(color.FgYellow).SprintFunc()
47
+
cyan := color.New(color.FgCyan).SprintFunc()
48
+
49
+
fmt.Printf("[%v]\n", yellow(ss.File))
50
+
for i, cid := range cp {
51
+
/*stats, _ := ss.GetCollectionStats(cid.String())
52
+
53
+
sum := 0
54
+
for _, v := range stats {
55
+
sum += v
56
+
}*/
57
+
fmt.Printf("%v [#%v]\n", cyan(cid.String()), len(cp)-i)
58
+
}
59
+
}
60
+
}
61
+
62
+
stat, _ := os.Stdin.Stat()
63
+
if (stat.Mode() & os.ModeCharDevice) == 0 {
64
+
// data is being piped to stdin
65
+
engine.WalkStream(&ctx, os.Stdin, walk)
66
+
} else {
67
+
//stdin is from a terminal
68
+
engine.WalkFiles(&ctx, walk)
69
+
}
70
+
},
71
+
}
+37
-13
cmd/atr-show.go
+37
-13
cmd/atr-show.go
···
5
5
"os"
6
6
"os/exec"
7
7
"regexp"
8
+
"runtime"
8
9
"strings"
9
10
10
11
"github.com/atscan/atr/cli"
···
21
22
QueryJmes string
22
23
Type string
23
24
Raw bool
25
+
Root string
26
+
GoBack int
24
27
)
25
28
26
29
func init() {
27
30
rootCmd.AddCommand(ShowCmd)
31
+
ShowCmd.Flags().StringVarP(&Root, "root", "r", "", "Use specific root")
32
+
ShowCmd.Flags().IntVarP(&GoBack, "back", "b", 0, "Go back (n) commits")
28
33
ShowCmd.Flags().StringVarP(&Type, "type", "t", "", "Filter by item type")
29
34
ShowCmd.Flags().StringVarP(&Query, "query", "q", "", "Query results (jq)")
30
35
ShowCmd.Flags().StringVarP(&QueryJmes, "query-jmes", "x", "", "Query results (jmespath)")
···
40
45
ctx := cli.Context{
41
46
WorkingDir: workingDir,
42
47
Args: args,
48
+
Raw: Raw,
43
49
}
44
50
45
51
//q := ctx.Args().First()
···
64
70
queryJmes = jc
65
71
}
66
72
67
-
eo, err := exec.Command("defaults", "read", "-g", "AppleInterfaceStyle").Output()
68
-
if err != nil {
69
-
log.Fatal(err)
70
-
}
71
73
style := "paraiso-dark"
72
-
if strings.Index(string(eo), "Dark") != 0 {
73
-
style = "paraiso-light"
74
+
if runtime.GOOS == "darwin" {
75
+
eo, err := exec.Command("defaults", "read", "-g", "AppleInterfaceStyle").Output()
76
+
if err != nil {
77
+
log.Fatal(err)
78
+
}
79
+
if strings.Index(string(eo), "Dark") != 0 {
80
+
style = "paraiso-light"
81
+
}
74
82
}
75
83
hg := cli.Highlight(style)
76
84
77
85
walk := func(ss repo.RepoSnapshot, err error) {
78
86
87
+
rr := Root
88
+
if GoBack > 0 {
89
+
gb, _ := ss.Repo.GetCommitsPath(GoBack)
90
+
rr = gb[len(gb)-1].String()
91
+
92
+
}
93
+
ss.LoadItems(rr)
94
+
79
95
for _, e := range ss.Items {
80
96
tf := Type
81
97
if tf != "" {
···
83
99
continue
84
100
}
85
101
}
86
-
var out interface{}
102
+
103
+
out := cli.ObjectOutput{Did: ss.Repo.SignedCommit().Did, Cid: e.Cid.String(), Rkey: e.Path, Body: e.Body}
104
+
87
105
if q != "" || qq != "" {
88
-
json, err := jsoniter.Marshal(e.Body)
106
+
json, err := jsoniter.Marshal(out)
89
107
if err != nil {
90
108
log.Fatal("jsoniter error:", err)
91
109
continue
···
110
128
if v == nil {
111
129
continue
112
130
}
113
-
out = v
131
+
out.Match = v
114
132
}
115
133
}
116
134
if qq != "" {
···
118
136
if err != nil {
119
137
log.Fatalln("jmespath error:", err)
120
138
}
121
-
out = r
139
+
out.Match = r
122
140
}
141
+
}
142
+
143
+
var ro interface{}
144
+
if out.Match != nil {
145
+
ro = out.Match
123
146
} else {
124
-
out = e.Body
147
+
ro = out
125
148
}
149
+
126
150
stat, _ := os.Stdout.Stat()
127
151
if !Raw && (stat.Mode()&os.ModeCharDevice) != 0 {
128
-
cli.PrettyPrint(out, hg)
152
+
cli.PrettyPrint(ro, e, ss, hg)
129
153
} else {
130
-
cli.Print(out)
154
+
cli.Print(ro, e, ss)
131
155
}
132
156
}
133
157
}
+71
-23
engine/io.go
+71
-23
engine/io.go
···
8
8
"log"
9
9
"os"
10
10
"strings"
11
+
"time"
11
12
13
+
"github.com/atscan/atr/cli"
12
14
"github.com/atscan/atr/repo"
13
-
"github.com/ipfs/go-cid"
14
15
"github.com/klauspost/compress/zstd"
16
+
"github.com/schollz/progressbar/v3"
15
17
)
16
18
17
-
func Load(fn string) (repo.RepoSnapshot, error) {
19
+
func Load(ctx *cli.Context, fn string) (repo.RepoSnapshot, error) {
18
20
var ss repo.RepoSnapshot
19
21
var err error
20
22
if strings.HasSuffix(fn, ".car.zst") {
21
-
ss, err = LoadCompressed(fn)
23
+
ss, err = LoadCompressed(ctx, fn)
22
24
} else if strings.HasSuffix(fn, ".car") {
23
-
ss, err = LoadRaw(fn)
25
+
ss, err = LoadRaw(ctx, fn)
24
26
}
25
27
if err != nil {
26
28
log.Fatal("Cannot load: ", fn)
···
30
32
return ss, nil
31
33
}
32
34
33
-
func LoadRaw(fn string) (repo.RepoSnapshot, error) {
35
+
func LoadRaw(ctx *cli.Context, fn string) (repo.RepoSnapshot, error) {
36
+
stat, err := os.Stat(fn)
37
+
if err != nil {
38
+
return repo.RepoSnapshot{}, err
39
+
}
34
40
dat, err := os.Open(fn)
41
+
if err != nil {
42
+
return repo.RepoSnapshot{}, err
43
+
}
35
44
defer dat.Close()
36
45
37
46
if err != nil {
38
47
return repo.RepoSnapshot{}, err
39
48
}
40
-
return LoadFromStream(dat)
49
+
return LoadFromStream(ctx, dat, stat.Size())
41
50
}
42
51
43
-
func LoadCompressed(fn string) (repo.RepoSnapshot, error) {
52
+
func LoadCompressed(ctx *cli.Context, fn string) (repo.RepoSnapshot, error) {
44
53
dat, err := os.Open(fn)
54
+
if err != nil {
55
+
return repo.RepoSnapshot{}, err
56
+
}
45
57
defer dat.Close()
46
58
47
59
if err != nil {
48
60
return repo.RepoSnapshot{}, err
49
61
}
50
62
decoder, _ := zstd.NewReader(dat)
51
-
return LoadFromStream(decoder)
63
+
return LoadFromStream(ctx, decoder, -1)
64
+
}
65
+
66
+
func LoadFromStream(ctx *cli.Context, input io.Reader, sz int64) (repo.RepoSnapshot, error) {
67
+
ss, err := LoadRepoFromStream(ctx, input, sz)
68
+
if err != nil {
69
+
return ss, err
70
+
}
71
+
72
+
ss.Root = ss.Repo.Head()
73
+
74
+
return ss, nil
52
75
}
53
76
54
-
func LoadFromStream(input io.Reader) (repo.RepoSnapshot, error) {
77
+
func LoadRepoFromStream(ctx *cli.Context, input io.Reader, sz int64) (repo.RepoSnapshot, error) {
55
78
rctx := context.TODO()
56
79
ss := repo.RepoSnapshot{}
57
80
81
+
var bar *progressbar.ProgressBar
82
+
if sz > 150_000_000 && !ctx.Raw {
83
+
bar = progressbar.NewOptions(int(sz),
84
+
progressbar.OptionSetDescription("loading"),
85
+
progressbar.OptionSetWriter(os.Stderr),
86
+
progressbar.OptionShowBytes(true),
87
+
//progressbar.OptionSetWidth(10),
88
+
progressbar.OptionThrottle(35*time.Millisecond),
89
+
progressbar.OptionShowCount(),
90
+
//progressbar.OptionOnCompletion(func() {
91
+
//}),
92
+
//progressbar.OptionSpinnerType(14),
93
+
//progressbar.OptionFullWidth(),
94
+
//progressbar.OptionUseANSICodes(true),
95
+
progressbar.OptionSetRenderBlankState(false),
96
+
/*progressbar.OptionSetTheme(progressbar.Theme{
97
+
Saucer: "=",
98
+
SaucerHead: ">",
99
+
SaucerPadding: " ",
100
+
BarStart: "[",
101
+
BarEnd: "]",
102
+
}),*/
103
+
)
104
+
ctx.ProgressBar = bar
105
+
}
106
+
58
107
buf := new(bytes.Buffer)
59
-
size, err := io.Copy(buf, input)
108
+
var err error
109
+
var size int64
110
+
if bar != nil {
111
+
size, err = io.Copy(io.MultiWriter(buf, bar), input)
112
+
} else {
113
+
size, err = io.Copy(buf, input)
114
+
}
60
115
if err != nil {
61
116
log.Fatal(err)
62
117
}
63
118
ss.Size = int(size)
64
119
120
+
if bar != nil {
121
+
defer bar.Finish()
122
+
defer bar.Clear()
123
+
}
124
+
65
125
r, err := repo.ReadRepoFromCar(rctx, buf)
66
126
if err != nil {
67
127
return ss, err
68
128
}
69
-
ss.Root = r.Head()
70
-
var out []repo.RepoItem
71
-
if err := r.ForEach(rctx, "", func(k string, v cid.Cid) error {
72
-
_, rec, err := r.GetRecord(rctx, k)
73
-
if err != nil {
74
-
log.Println("Cannot get record:", v.String())
75
-
}
76
-
out = append(out, repo.RepoItem{Cid: v, Path: k, Body: rec})
77
-
ss.Items = out
78
-
return nil
79
-
}); err != nil {
80
-
return ss, err
81
-
}
129
+
ss.Repo = *r
82
130
return ss, nil
83
131
}
+3
-3
engine/walk.go
+3
-3
engine/walk.go
···
31
31
return err
32
32
}
33
33
if !info.IsDir() {
34
-
cb(Load(dir))
34
+
cb(Load(ctx, dir))
35
35
return nil
36
36
}
37
37
err = filepath.Walk(dir,
···
39
39
if err != nil {
40
40
return err
41
41
}
42
-
cb(Load(fn))
42
+
cb(Load(ctx, fn))
43
43
return nil
44
44
})
45
45
if err != nil {
···
49
49
}
50
50
51
51
func WalkStream(ctx *cli.Context, input io.Reader, cb func(repo.RepoSnapshot, error)) error {
52
-
ss, err := LoadFromStream(input)
52
+
ss, err := LoadFromStream(ctx, input, -1)
53
53
if err != nil {
54
54
log.Println("Cannot load from stream:", err)
55
55
return nil
+19
-14
go.mod
+19
-14
go.mod
···
4
4
5
5
require (
6
6
github.com/alecthomas/chroma v0.10.0
7
-
github.com/bluesky-social/indigo v0.0.0-20230714174244-57d75d8cfc65
7
+
github.com/bluesky-social/indigo v0.0.0-20230718161430-1e5d9abdee8f
8
8
github.com/dustin/go-humanize v1.0.1
9
9
github.com/fatih/color v1.15.0
10
10
github.com/fxamacker/cbor/v2 v2.4.0
11
+
github.com/ipfs/boxo v0.10.2
11
12
github.com/ipfs/go-cid v0.4.1
12
13
github.com/ipfs/go-datastore v0.6.0
13
-
github.com/ipfs/go-ipfs-blockstore v1.3.0
14
14
github.com/ipfs/go-ipld-cbor v0.0.7-0.20230126201833-a73d038d90bc
15
15
github.com/ipld/go-car/v2 v2.10.1
16
16
github.com/itchyny/gojq v0.12.13
17
17
github.com/jmespath/go-jmespath v0.4.0
18
18
github.com/json-iterator/go v1.1.12
19
19
github.com/klauspost/compress v1.16.7
20
+
github.com/schollz/progressbar/v3 v3.13.1
20
21
github.com/spf13/cobra v1.7.0
21
-
github.com/whyrusleeping/cbor-gen v0.0.0-20230331140348-1f892b517e70
22
+
github.com/whyrusleeping/cbor-gen v0.0.0-20230418232409-daab9ece03a0
22
23
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
23
24
)
24
25
25
26
require (
26
-
github.com/dlclark/regexp2 v1.4.0 // indirect
27
+
github.com/dlclark/regexp2 v1.10.0 // indirect
27
28
github.com/gogo/protobuf v1.3.2 // indirect
28
29
github.com/google/uuid v1.3.0 // indirect
29
30
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
30
31
github.com/hashicorp/go-hclog v1.2.0 // indirect
31
-
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
32
+
github.com/hashicorp/go-retryablehttp v0.7.4 // indirect
32
33
github.com/hashicorp/golang-lru v0.5.4 // indirect
33
34
github.com/inconshreveable/mousetrap v1.1.0 // indirect
34
35
github.com/ipfs/bbloom v0.0.4 // indirect
35
36
github.com/ipfs/go-block-format v0.1.2 // indirect
36
-
github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect
37
-
github.com/ipfs/go-ipfs-util v0.0.2 // indirect
37
+
github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect
38
+
github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect
39
+
github.com/ipfs/go-ipfs-util v0.0.3 // indirect
38
40
github.com/ipfs/go-ipld-format v0.5.0 // indirect
39
41
github.com/ipfs/go-log v1.0.5 // indirect
40
42
github.com/ipfs/go-log/v2 v2.5.1 // indirect
···
42
44
github.com/ipld/go-ipld-prime v0.20.0 // indirect
43
45
github.com/itchyny/timefmt-go v0.1.5 // indirect
44
46
github.com/jbenet/goprocess v0.1.4 // indirect
45
-
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
47
+
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
46
48
github.com/mattn/go-colorable v0.1.13 // indirect
47
49
github.com/mattn/go-isatty v0.0.19 // indirect
48
-
github.com/minio/sha256-simd v1.0.0 // indirect
50
+
github.com/mattn/go-runewidth v0.0.14 // indirect
51
+
github.com/minio/sha256-simd v1.0.1 // indirect
52
+
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
49
53
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
50
54
github.com/modern-go/reflect2 v1.0.2 // indirect
51
55
github.com/mr-tron/base58 v1.2.0 // indirect
···
57
61
github.com/multiformats/go-varint v0.0.7 // indirect
58
62
github.com/opentracing/opentracing-go v1.2.0 // indirect
59
63
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect
60
-
github.com/pkg/errors v0.9.1 // indirect
61
64
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f // indirect
65
+
github.com/rivo/uniseg v0.4.4 // indirect
62
66
github.com/spaolacci/murmur3 v1.1.0 // indirect
63
67
github.com/spf13/pflag v1.0.5 // indirect
64
68
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect
65
69
github.com/x448/float16 v0.8.4 // indirect
66
-
go.uber.org/atomic v1.10.0 // indirect
70
+
go.uber.org/atomic v1.11.0 // indirect
67
71
go.uber.org/multierr v1.11.0 // indirect
68
72
go.uber.org/zap v1.24.0 // indirect
69
-
golang.org/x/crypto v0.9.0 // indirect
70
-
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
73
+
golang.org/x/crypto v0.11.0 // indirect
74
+
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
71
75
golang.org/x/sys v0.10.0 // indirect
72
-
lukechampine.com/blake3 v1.1.7 // indirect
76
+
golang.org/x/term v0.10.0 // indirect
77
+
lukechampine.com/blake3 v1.2.1 // indirect
73
78
)
+45
-39
go.sum
+45
-39
go.sum
···
1
1
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2
2
github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=
3
3
github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
4
-
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
5
4
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
6
-
github.com/bluesky-social/indigo v0.0.0-20230714174244-57d75d8cfc65 h1:0z5rF7oA9eqqoAFoiHTfioBK8U4hzMmyGMoajEqJVFE=
7
-
github.com/bluesky-social/indigo v0.0.0-20230714174244-57d75d8cfc65/go.mod h1:oDI5NiD0XzShv5VITWyUJNP3pSh4prTDEzhKbkdKORA=
5
+
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
6
+
github.com/bluesky-social/indigo v0.0.0-20230718161430-1e5d9abdee8f h1:UyXR9qPzchWhuGLam3UizuAmweGRmlLnq0fgKaT4Q2Y=
7
+
github.com/bluesky-social/indigo v0.0.0-20230718161430-1e5d9abdee8f/go.mod h1:zhrvkTF/VhT/QxOvNVbc3B1w5pKugta0g08+H4YcMlU=
8
8
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
9
9
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
10
10
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11
11
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
12
12
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
13
-
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
14
13
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
14
+
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
15
+
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
15
16
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
16
17
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
17
18
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
···
27
28
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
28
29
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
29
30
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
30
-
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
31
31
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
32
32
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
33
-
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
34
33
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
34
+
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
35
35
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
36
36
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
37
37
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
38
38
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
39
39
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
40
-
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
41
-
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
40
+
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
41
+
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
42
42
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
43
43
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
44
44
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
45
45
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
46
46
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
47
47
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
48
+
github.com/ipfs/boxo v0.10.2 h1:kspw9HmMyKzLQxpKk417sF69i6iuf50AXtRjFqCYyL4=
49
+
github.com/ipfs/boxo v0.10.2/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8=
48
50
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
49
51
github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo=
50
52
github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE=
51
-
github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog=
52
53
github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
53
54
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
54
55
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
55
-
github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk=
56
56
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
57
57
github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
58
58
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
59
-
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
60
-
github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM=
61
-
github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE=
59
+
github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ=
60
+
github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE=
62
61
github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8=
63
-
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
64
-
github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q=
65
-
github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU=
66
-
github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8=
67
-
github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ=
62
+
github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw=
63
+
github.com/ipfs/go-ipfs-ds-help v1.1.1/go.mod h1:75vrVCkSdSFidJscs8n4W+77AtTpCIAdDGAwjitJMIo=
64
+
github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0=
65
+
github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs=
68
66
github.com/ipfs/go-ipld-cbor v0.0.7-0.20230126201833-a73d038d90bc h1:eUEo764smNy0EVRuMTSmirmuh552Mf2aBjfpDcLnDa8=
69
67
github.com/ipfs/go-ipld-cbor v0.0.7-0.20230126201833-a73d038d90bc/go.mod h1:X7SgEIwC4COC5OWfcepZBWafO5kA1Rmt9ZsLLbhihQk=
70
68
github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds=
···
98
96
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
99
97
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
100
98
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
99
+
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
101
100
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
102
101
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
103
102
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
104
103
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
105
-
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
106
-
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
107
-
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
108
-
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
104
+
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
105
+
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
109
106
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
110
-
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
111
107
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
112
108
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
113
109
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
···
120
116
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
121
117
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
122
118
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
119
+
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
123
120
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
124
121
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
122
+
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
123
+
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
125
124
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
126
125
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
127
-
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
128
-
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
126
+
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
127
+
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
128
+
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
129
+
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
129
130
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
130
131
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
131
132
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
···
141
142
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
142
143
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
143
144
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
144
-
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
145
145
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
146
146
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
147
147
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
···
159
159
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw=
160
160
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
161
161
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
162
-
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
163
162
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
164
163
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
165
164
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f h1:VXTQfuJj9vKR4TCkEuWIckKvdHFeJH/huIFJ9/cXOB0=
166
165
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
166
+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
167
+
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
168
+
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
167
169
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
168
170
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
169
171
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
170
172
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
173
+
github.com/schollz/progressbar/v3 v3.13.1 h1:o8rySDYiQ59Mwzy2FELeHY5ZARXZTVJC7iHD6PEFUiE=
174
+
github.com/schollz/progressbar/v3 v3.13.1/go.mod h1:xvrbki8kfT1fzWzBT/UZd9L6GA+jdL7HAgq2RFnO6fQ=
171
175
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
172
176
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
173
177
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
···
191
195
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
192
196
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0=
193
197
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ=
194
-
github.com/whyrusleeping/cbor-gen v0.0.0-20230331140348-1f892b517e70 h1:iNBzUKTsJc9RqStEVX2VYgVHATTU39IuB7g0e8OPWXU=
195
-
github.com/whyrusleeping/cbor-gen v0.0.0-20230331140348-1f892b517e70/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
198
+
github.com/whyrusleeping/cbor-gen v0.0.0-20230418232409-daab9ece03a0 h1:XYEgH2nJgsrcrj32p+SAbx6T3s/6QknOXezXtz7kzbg=
199
+
github.com/whyrusleeping/cbor-gen v0.0.0-20230418232409-daab9ece03a0/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
196
200
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
197
201
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
198
202
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
···
201
205
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
202
206
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
203
207
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
204
-
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
205
-
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
208
+
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
209
+
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
206
210
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
207
211
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
208
212
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
···
219
223
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
220
224
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
221
225
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
222
-
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
223
-
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
224
-
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
225
-
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
226
+
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
227
+
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
228
+
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
229
+
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
226
230
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
227
231
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
228
232
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
···
247
251
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
248
252
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
249
253
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
250
-
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
251
254
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
255
+
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
252
256
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
253
257
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
254
258
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
255
259
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
260
+
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
261
+
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
262
+
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
256
263
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
257
264
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
258
265
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
···
275
282
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
276
283
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
277
284
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
278
-
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
279
285
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
280
286
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
281
287
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
···
285
291
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
286
292
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
287
293
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
288
-
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
289
-
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
294
+
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
295
+
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
-16
repo/ext.go
-16
repo/ext.go
+63
-14
repo/repo.go
+63
-14
repo/repo.go
···
9
9
10
10
"github.com/bluesky-social/indigo/mst"
11
11
"github.com/bluesky-social/indigo/util"
12
+
blockstore "github.com/ipfs/boxo/blockstore"
12
13
"github.com/ipfs/go-cid"
13
14
"github.com/ipfs/go-datastore"
14
-
blockstore "github.com/ipfs/go-ipfs-blockstore"
15
15
cbor "github.com/ipfs/go-ipld-cbor"
16
16
"github.com/ipld/go-car/v2"
17
17
)
18
18
19
19
// current version of repo currently implemented
20
-
const ATP_REPO_VERSION int64 = 2
20
+
const ATP_REPO_VERSION int64 = 3
21
21
22
22
type SignedCommit struct {
23
23
Did string `cborgen:"did"`
···
35
35
}
36
36
37
37
type Repo struct {
38
+
Blocks int
39
+
38
40
sc SignedCommit
39
41
cst cbor.IpldStore
40
42
bs blockstore.Blockstore
···
67
69
return buf.Bytes(), nil
68
70
}*/
69
71
70
-
func IngestRepo(ctx context.Context, bs blockstore.Blockstore, r io.Reader) (cid.Cid, error) {
72
+
func IngestRepo(ctx context.Context, bs blockstore.Blockstore, r io.Reader) (cid.Cid, int, error) {
71
73
br, err := car.NewBlockReader(r)
72
74
if err != nil {
73
-
return cid.Undef, err
75
+
return cid.Undef, 0, err
74
76
}
75
77
78
+
size := 0
76
79
for {
77
80
blk, err := br.Next()
78
81
if err != nil {
79
82
if err == io.EOF {
80
83
break
81
84
}
82
-
return cid.Undef, err
85
+
return cid.Undef, size, err
83
86
}
84
87
85
88
if err := bs.Put(ctx, blk); err != nil {
86
-
return cid.Undef, err
89
+
return cid.Undef, size, err
87
90
}
91
+
size++
88
92
}
89
93
90
-
return br.Roots[0], nil
94
+
return br.Roots[0], size, nil
91
95
}
92
96
93
97
func ReadRepoFromCar(ctx context.Context, r io.Reader) (*Repo, error) {
94
98
bs := blockstore.NewBlockstore(datastore.NewMapDatastore())
95
-
root, err := IngestRepo(ctx, bs, r)
99
+
root, size, err := IngestRepo(ctx, bs, r)
96
100
if err != nil {
97
101
return nil, err
98
102
}
99
103
100
-
return OpenRepo(ctx, bs, root, false)
104
+
return OpenRepo(ctx, bs, root, size)
101
105
}
102
106
103
-
func OpenRepo(ctx context.Context, bs blockstore.Blockstore, root cid.Cid, fullRepo bool) (*Repo, error) {
107
+
func OpenRepo(ctx context.Context, bs blockstore.Blockstore, root cid.Cid, size int) (*Repo, error) {
104
108
cst := util.CborStore(bs)
105
109
106
110
var sc SignedCommit
···
108
112
return nil, fmt.Errorf("loading root from blockstore: %w", err)
109
113
}
110
114
111
-
if sc.Version != ATP_REPO_VERSION {
115
+
if sc.Version > ATP_REPO_VERSION {
112
116
return nil, fmt.Errorf("unsupported repo version: %d", sc.Version)
113
117
}
114
118
···
117
121
bs: bs,
118
122
cst: cst,
119
123
repoCid: root,
124
+
Blocks: size,
120
125
}, nil
121
126
}
122
127
128
+
func (r *Repo) GetCommitsPath(len int) ([]cid.Cid, error) {
129
+
path := []cid.Cid{}
130
+
path = append(path, r.repoCid)
131
+
if r.sc.Prev != nil {
132
+
getParentCommits(r, *r.sc.Prev, &path, len-1)
133
+
}
134
+
return path, nil
135
+
}
136
+
137
+
func getParentCommits(r *Repo, c cid.Cid, p *[]cid.Cid, len int) ([]cid.Cid, error) {
138
+
var sc SignedCommit
139
+
ctx := context.TODO()
140
+
if err := r.cst.Get(ctx, c, &sc); err != nil {
141
+
return nil, fmt.Errorf("loading root from blockstore: %w", err)
142
+
}
143
+
*p = append(*p, c)
144
+
if len == 0 {
145
+
return nil, nil
146
+
} else {
147
+
len--
148
+
}
149
+
if sc.Prev != nil {
150
+
return getParentCommits(r, *sc.Prev, p, len)
151
+
}
152
+
return nil, nil
153
+
}
154
+
123
155
func (r *Repo) Head() cid.Cid {
124
156
return r.repoCid
125
157
}
126
158
159
+
func (r *Repo) SignedCommit() SignedCommit {
160
+
return r.sc
161
+
}
162
+
163
+
func (r *Repo) MerkleSearchTree() *mst.MerkleSearchTree {
164
+
return r.mst
165
+
}
166
+
167
+
func (r *Repo) BlockStore() blockstore.Blockstore {
168
+
return r.bs
169
+
}
170
+
127
171
func (r *Repo) getMst(ctx context.Context) (*mst.MerkleSearchTree, error) {
128
172
if r.mst != nil {
129
173
return r.mst, nil
···
134
178
return t, nil
135
179
}
136
180
181
+
func (r *Repo) MST() *mst.MerkleSearchTree {
182
+
mst, _ := r.getMst(context.TODO())
183
+
return mst
184
+
}
185
+
137
186
var ErrDoneIterating = fmt.Errorf("done iterating")
138
187
139
188
func (r *Repo) ForEach(ctx context.Context, prefix string, cb func(k string, v cid.Cid) error) error {
140
-
t := mst.LoadMST(r.cst, r.sc.Data)
189
+
t, _ := r.getMst(ctx)
141
190
142
191
if err := t.WalkLeavesFrom(ctx, prefix, cb); err != nil {
143
192
if err != ErrDoneIterating {
···
148
197
return nil
149
198
}
150
199
151
-
func (r *Repo) GetRecord(ctx context.Context, rpath string) (cid.Cid, interface{}, error) {
200
+
func (r *Repo) GetRecord(ctx context.Context, rpath string) (cid.Cid, map[string]interface{}, error) {
152
201
mst, err := r.getMst(ctx)
153
202
if err != nil {
154
203
return cid.Undef, nil, fmt.Errorf("getting repo mst: %w", err)
···
163
212
if err != nil {
164
213
return cid.Undef, nil, err
165
214
}
166
-
var v interface{}
215
+
var v map[string]interface{}
167
216
cbor2.Unmarshal(blk.RawData(), &v)
168
217
169
218
return cc, v, nil
+84
repo/snapshot.go
+84
repo/snapshot.go
···
1
+
package repo
2
+
3
+
import (
4
+
"context"
5
+
"log"
6
+
"strings"
7
+
8
+
cid "github.com/ipfs/go-cid"
9
+
)
10
+
11
+
type RepoItem struct {
12
+
Cid cid.Cid
13
+
Path string
14
+
Body interface{}
15
+
}
16
+
17
+
type RepoSnapshot struct {
18
+
Root cid.Cid
19
+
File string
20
+
Size int
21
+
Items []RepoItem
22
+
Repo Repo
23
+
}
24
+
25
+
func (ss *RepoSnapshot) GetCollectionStats(root string) (map[string]int, error) {
26
+
rctx := context.TODO()
27
+
28
+
rr := ss.Repo
29
+
if root != "" && root != "b" {
30
+
cid, err := cid.Parse(root)
31
+
if err != nil {
32
+
log.Fatalf("cannot parse CID: %s", root)
33
+
}
34
+
cr, err := OpenRepo(rctx, rr.BlockStore(), cid, 0)
35
+
if err != nil {
36
+
log.Fatal("cannot open repo")
37
+
}
38
+
rr = *cr
39
+
}
40
+
stats := make(map[string]int)
41
+
if err := rr.ForEach(rctx, "", func(k string, v cid.Cid) error {
42
+
col := strings.Split(k, "/")[0]
43
+
_, ok := stats[col]
44
+
if !ok {
45
+
stats[col] = 0
46
+
}
47
+
stats[col]++
48
+
return nil
49
+
}); err != nil {
50
+
return nil, err
51
+
}
52
+
return stats, nil
53
+
}
54
+
55
+
func (ss *RepoSnapshot) LoadItems(root string) error {
56
+
rctx := context.TODO()
57
+
58
+
rr := ss.Repo
59
+
if root != "" && root != "b" {
60
+
cid, err := cid.Parse(root)
61
+
if err != nil {
62
+
log.Fatalf("cannot parse CID: %s", root)
63
+
}
64
+
cr, err := OpenRepo(rctx, rr.BlockStore(), cid, 0)
65
+
if err != nil {
66
+
log.Fatal("cannot open repo")
67
+
}
68
+
rr = *cr
69
+
}
70
+
71
+
var out []RepoItem
72
+
if err := rr.ForEach(rctx, "", func(k string, v cid.Cid) error {
73
+
_, rec, err := rr.GetRecord(rctx, k)
74
+
if err != nil {
75
+
log.Println("Cannot get record:", v.String())
76
+
}
77
+
out = append(out, RepoItem{Cid: v, Path: k, Body: rec})
78
+
ss.Items = out
79
+
return nil
80
+
}); err != nil {
81
+
return err
82
+
}
83
+
return nil
84
+
}