@cryptotaxi247 / kubo / commits / fc865bea5

refactor: migrate away from cheggaaa/pb v1 (#11322)

* refactor: migrate away from cheggaaa/pb v1 * updated changelogs * fix: add space after comment slashes for consistency * refactor: share terminal detection in cmdenv Replace three duplicate TTY checks (get.go, dag/export.go, dag/stat.go) with `cmdenv.IsTerminal(*os.File)` backed by `mattn/go-isatty`. The helper uses `IsTerminal || IsCygwinTerminal`, which also detects MSYS2 and Git Bash on Windows. Those terminals expose stdio as a named pipe rather than a character device, so the previous `ModeCharDevice` check suppressed the progress bar on real terminals. - core/commands/cmdenv/tty.go: new helper - core/commands/{add,cat,get}.go: drop local isStderrTTY - core/commands/dag/{export,stat}.go: drop inline stat() block - go.mod: promote mattn/go-isatty to direct (was indirect via pb/v3) * refactor: cmdenv.ShouldShowProgress helper Collapse the explicit-flag-or-TTY-default logic at four call sites (`cat`, `get`, `dag export`, `dag stat`) into a single helper. * refactor: dedupe `ipfs add` progress template The full bar template (counters, bar, speed, percent, ETA) was inlined at two call sites in add.go. Move it to a file-level const. * fix: progress bar shows MiB/s, not MiB p/s pb v3's speed element defaults to suffix "%s p/s", so even with pb.Bytes set, `ipfs add`, `ipfs cat`, `ipfs get`, and `ipfs dag export` rendered the rate as "713.04 MiB p/s" instead of "713.04 MiB/s". Pass explicit format args to the speed and rtime template elements: rate now renders as "MiB/s", and the unknown-state fallback reads "?/s" / "ETA ?" instead of bare "?". The four templates move to package-level consts. * docs: rewrite v0.42 progress bar entry Describe only the user-visible changes; skip library-migration detail and intermediate-state claims that never shipped. * chore: drop unused pb v1 dependabot ignore The `github.com/cheggaaa/pb` (v1) module path is no longer in `go.mod` after the migration to `pb/v3`, so the ignore rule never fires. * fix(dag): unify --progress help text Match the wording used by `add`, `cat`, and `get`: "Stream progress data. Defaults to true when stderr is a terminal." * fix(add): finalize progress bar after upload Call `bar.Finish()` and a final `bar.Write()` after the progress loop. Without it, fast adds (under ~500ms, where pb/v3's EWMA never accumulates a speed sample) render `?/s ... ETA ?` in the last frame. Finishing the bar switches the speed element to its absolute-rate branch (total/elapsed), so the final frame now reads e.g. `792.04 MiB/s 100.00% 100ms`. * test(cmdenv): cover ShouldShowProgress Exercise the explicit-true, explicit-false, unset, and non-bool paths. Unset and non-bool fall back to IsTerminal(os.Stderr), which the test compares against directly so it works in both TTY and CI environments. * refactor: share full progress bar template Move the "total known" pb/v3 template to cmdenv.ProgressBarFullTemplate so add.go and get.go reference the same string instead of keeping byte-identical local copies. The add init template and dag/export streaming template stay local because each is single-use and shaped differently. --------- Co-authored-by: Marcin Rataj <lidel@lidel.org>

Vin :) committed May 25, 2026 at 17:54 UTC fc865bea508da76dbf2701e3e621de1232cf20f4
12 files changed +164 -101
core/commands/add.go
+29 -21
@@ -13,7 +13,7 @@ import (
13 "github.com/ipfs/kubo/core/commands/cmdenv"
14 "github.com/ipfs/kubo/core/commands/cmdutils"
15
16 - "github.com/cheggaaa/pb"
16 + "github.com/cheggaaa/pb/v3"
17 "github.com/ipfs/boxo/files"
18 uio "github.com/ipfs/boxo/ipld/unixfs/io"
19 mfs "github.com/ipfs/boxo/mfs"
@@ -76,6 +76,11 @@ const (
76
77 const (
78 adderOutChanSize = 8
79 +
80 + // pb/v3 template used before the upload total is known: only the
81 + // running byte counter and current speed. Swapped for
82 + // cmdenv.ProgressBarFullTemplate once size discovery reports.
83 + progressBarInitTemplate = `{{counters . }} {{speed . "%s/s" "?/s"}}`
84 )
85
86 var AddCmd = &cmds.Command{
@@ -252,7 +257,7 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#import
257 cmds.BoolOption(quietOptionName, "q", "Write minimal output."),
258 cmds.BoolOption(quieterOptionName, "Q", "Write only final hash."),
259 cmds.BoolOption(silentOptionName, "Write no output."),
255 - cmds.BoolOption(progressOptionName, "p", "Stream progress data."),
260 + cmds.BoolOption(progressOptionName, "p", "Stream progress data. Defaults to true when stderr is a terminal."),
261 // Basic Add Behavior
262 cmds.BoolOption(onlyHashOptionName, "n", "Only chunk and hash - do not write to disk."),
263 cmds.BoolOption(wrapOptionName, "w", "Wrap files with a directory object."),
@@ -292,10 +297,10 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#import
297 silent, _ := req.Options[silentOptionName].(bool)
298
299 if !quiet && !silent {
295 - // ipfs cli progress bar defaults to true unless quiet or silent is used
300 + // default to showing progress only when stderr is a terminal
301 _, found := req.Options[progressOptionName].(bool)
302 if !found {
298 - req.Options[progressOptionName] = true
303 + req.Options[progressOptionName] = cmdenv.IsTerminal(os.Stderr)
304 }
305 }
306
@@ -732,11 +737,8 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#import
737
738 var bar *pb.ProgressBar
739 if progress {
735 - bar = pb.New64(0).SetUnits(pb.U_BYTES)
736 - bar.ManualUpdate = true
737 - bar.ShowTimeLeft = false
738 - bar.ShowPercent = false
739 - bar.Output = os.Stderr
740 + bar = pb.New64(0).Set(pb.Bytes, true).Set(pb.Static, true).SetWriter(os.Stderr)
741 + bar.SetTemplateString(progressBarInitTemplate)
742 bar.Start()
743 }
744
@@ -786,18 +788,17 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#import
788 }
789 lastBytes = output.Bytes
790 delta := prevFiles + lastBytes - totalProgress
789 - totalProgress = bar.Add64(delta)
791 + bar.Add64(delta)
792 + totalProgress = bar.Current()
793 }
794
795 if progress {
793 - bar.Update()
796 + bar.Write()
797 }
798 case size := <-sizeChan:
799 if progress {
797 - bar.Total = size
798 - bar.ShowPercent = true
799 - bar.ShowBar = true
800 - bar.ShowTimeLeft = true
800 + bar.SetTotal(size)
801 + bar.SetTemplateString(cmdenv.ProgressBarFullTemplate)
802 }
803 case <-req.Context.Done():
804 // don't set or print error here, that happens in the goroutine below
@@ -805,12 +806,19 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#import
806 }
807 }
808
808 - if progress && bar.Total == 0 && bar.Get() != 0 {
809 - bar.Total = bar.Get()
810 - bar.ShowPercent = true
811 - bar.ShowBar = true
812 - bar.ShowTimeLeft = true
813 - bar.Update()
809 + if progress {
810 + // If size discovery never reported, treat the
811 + // observed bytes as the total so the final frame
812 + // renders the bar and percent.
813 + if bar.Total() == 0 && bar.Current() != 0 {
814 + bar.SetTotal(bar.Current())
815 + bar.SetTemplateString(cmdenv.ProgressBarFullTemplate)
816 + }
817 + // Finish first so the speed element switches to
818 + // the absolute-rate branch (total/elapsed) when
819 + // EWMA never accumulated a sample on fast adds.
820 + bar.Finish()
821 + bar.Write()
822 }
823 }
824
core/commands/cat.go
+3 -5
@@ -10,7 +10,7 @@ import (
10 "github.com/ipfs/kubo/core/commands/cmdenv"
11 "github.com/ipfs/kubo/core/commands/cmdutils"
12
13 - "github.com/cheggaaa/pb"
13 + "github.com/cheggaaa/pb/v3"
14 "github.com/ipfs/boxo/files"
15 cmds "github.com/ipfs/go-ipfs-cmds"
16 iface "github.com/ipfs/kubo/core/coreiface"
@@ -34,7 +34,7 @@ var CatCmd = &cmds.Command{
34 Options: []cmds.Option{
35 cmds.Int64Option(offsetOptionName, "o", "Byte offset to begin reading from."),
36 cmds.Int64Option(lengthOptionName, "l", "Maximum number of bytes to read."),
37 - cmds.BoolOption(progressOptionName, "p", "Stream progress data.").WithDefault(true),
37 + cmds.BoolOption(progressOptionName, "p", "Stream progress data. Defaults to true when stderr is a terminal."),
38 },
39 Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
40 api, err := cmdenv.GetApi(env, req)
@@ -101,9 +101,7 @@ var CatCmd = &cmds.Command{
101 case io.Reader:
102 reader := val
103
104 - req := res.Request()
105 - progress, _ := req.Options[progressOptionName].(bool)
106 - if progress {
104 + if cmdenv.ShouldShowProgress(res.Request(), progressOptionName) {
105 var bar *pb.ProgressBar
106 bar, reader = progressBarForReader(os.Stderr, val, int64(res.Length()))
107 bar.Start()
core/commands/cmdenv/progress.go new
+24
@@ -0,0 +1,24 @@
1 +package cmdenv
2 +
3 +import (
4 + "os"
5 +
6 + cmds "github.com/ipfs/go-ipfs-cmds"
7 +)
8 +
9 +// ProgressBarFullTemplate is the pb/v3 template used by transfer
10 +// commands once the total byte count is known: byte counter, bar,
11 +// speed, percent, and ETA. Explicit format args override pb's
12 +// defaults so the rate renders as "MiB/s" (not "MiB p/s") and the
13 +// remaining time falls back to "ETA ?" while speed is unknown.
14 +const ProgressBarFullTemplate = `{{counters . }} {{bar . }} {{speed . "%s/s" "?/s"}} {{percent . }} {{rtime . "ETA %s" "%s" "ETA ?"}}`
15 +
16 +// ShouldShowProgress reports whether a progress bar should be rendered
17 +// based on a boolean option. An explicit `--<flag>=true|false` always
18 +// wins; when unset, it defaults to whether stderr is a terminal.
19 +func ShouldShowProgress(req *cmds.Request, flag string) bool {
20 + if v, ok := req.Options[flag].(bool); ok {
21 + return v
22 + }
23 + return IsTerminal(os.Stderr)
24 +}
core/commands/cmdenv/progress_test.go new
+46
@@ -0,0 +1,46 @@
1 +package cmdenv
2 +
3 +import (
4 + "os"
5 + "testing"
6 +
7 + cmds "github.com/ipfs/go-ipfs-cmds"
8 +)
9 +
10 +func TestShouldShowProgress(t *testing.T) {
11 + const flag = "progress"
12 + makeReq := func(opts map[string]any) *cmds.Request {
13 + if opts == nil {
14 + opts = map[string]any{}
15 + }
16 + return &cmds.Request{Options: opts}
17 + }
18 +
19 + t.Run("explicit true wins regardless of TTY", func(t *testing.T) {
20 + if !ShouldShowProgress(makeReq(map[string]any{flag: true}), flag) {
21 + t.Error("expected true for --progress=true")
22 + }
23 + })
24 +
25 + t.Run("explicit false wins regardless of TTY", func(t *testing.T) {
26 + if ShouldShowProgress(makeReq(map[string]any{flag: false}), flag) {
27 + t.Error("expected false for --progress=false")
28 + }
29 + })
30 +
31 + t.Run("unset defaults to IsTerminal(stderr)", func(t *testing.T) {
32 + got := ShouldShowProgress(makeReq(nil), flag)
33 + want := IsTerminal(os.Stderr)
34 + if got != want {
35 + t.Errorf("ShouldShowProgress(unset) = %v, want IsTerminal(os.Stderr) = %v", got, want)
36 + }
37 + })
38 +
39 + t.Run("non-bool value treated as unset", func(t *testing.T) {
40 + got := ShouldShowProgress(makeReq(map[string]any{flag: "yes"}), flag)
41 + want := IsTerminal(os.Stderr)
42 + if got != want {
43 + t.Errorf("ShouldShowProgress(non-bool) = %v, want IsTerminal(os.Stderr) = %v", got, want)
44 + }
45 + })
46 +}
core/commands/cmdenv/tty.go new
+14
@@ -0,0 +1,14 @@
1 +package cmdenv
2 +
3 +import (
4 + "os"
5 +
6 + "github.com/mattn/go-isatty"
7 +)
8 +
9 +// IsTerminal reports whether f is connected to a terminal,
10 +// including MSYS/Cygwin-style terminals on Windows.
11 +func IsTerminal(f *os.File) bool {
12 + fd := f.Fd()
13 + return isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd)
14 +}
core/commands/dag/dag.go
+2 -2
@@ -286,7 +286,7 @@ CAR file follows the CARv1 format: https://ipld.io/specs/transport/car/carv1/
286 cmds.StringArg("root", true, false, "CID of a root to recursively export").EnableStdin(),
287 },
288 Options: []cmds.Option{
289 - cmds.BoolOption(progressOptionName, "p", "Display progress on CLI. Defaults to true when STDERR is a TTY."),
289 + cmds.BoolOption(progressOptionName, "p", "Stream progress data. Defaults to true when stderr is a terminal."),
290 },
291 Run: dagExport,
292 PostRun: cmds.PostRunMap{
@@ -352,7 +352,7 @@ Note: This command skips duplicate blocks in reporting both size and the number
352 cmds.StringArg("root", true, true, "CID of a DAG root to get statistics for").EnableStdin(),
353 },
354 Options: []cmds.Option{
355 - cmds.BoolOption(progressOptionName, "p", "Show progress on stderr. Auto-detected if stderr is a terminal."),
355 + cmds.BoolOption(progressOptionName, "p", "Stream progress data. Defaults to true when stderr is a terminal."),
356 },
357 Run: dagStat,
358 Type: DagStatSummary{},
core/commands/dag/export.go
+11 -20
@@ -8,7 +8,7 @@ import (
8 "os"
9 "time"
10
11 - "github.com/cheggaaa/pb"
11 + "github.com/cheggaaa/pb/v3"
12 cid "github.com/ipfs/go-cid"
13 cmds "github.com/ipfs/go-ipfs-cmds"
14 ipld "github.com/ipfs/go-ipld-format"
@@ -20,6 +20,13 @@ import (
20 selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
21 )
22
23 +// pb/v3 template for `ipfs dag export`: byte counter, speed, and
24 +// elapsed time. No bar/percent/ETA because the total size of the
25 +// CAR stream is not known up front. The explicit "%s/s" speed
26 +// format overrides pb's default "p/s" suffix so the rate renders
27 +// as "MiB/s".
28 +const progressBarTemplate = `{{counters . }} {{speed . "%s/s" "?/s"}} {{etime . }}`
29 +
30 func dagExport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
31 // Accept CID or a content path
32 p, err := cmdutils.PathOrCidPath(req.Arguments[0])
@@ -99,28 +106,12 @@ func dagExport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment
106 }
107
108 func finishCLIExport(res cmds.Response, re cmds.ResponseEmitter) error {
102 - var showProgress bool
103 - val, specified := res.Request().Options[progressOptionName]
104 - if !specified {
105 - // default based on TTY availability
106 - errStat, _ := os.Stderr.Stat()
107 - if (errStat.Mode() & os.ModeCharDevice) != 0 {
108 - showProgress = true
109 - }
110 - } else if val.(bool) {
111 - showProgress = true
112 - }
113 -
114 - // simple passthrough, no progress
115 - if !showProgress {
109 + if !cmdenv.ShouldShowProgress(res.Request(), progressOptionName) {
110 return cmds.Copy(re, res)
111 }
112
119 - bar := pb.New64(0).SetUnits(pb.U_BYTES)
120 - bar.Output = os.Stderr
121 - bar.ShowSpeed = true
122 - bar.ShowElapsedTime = true
123 - bar.RefreshRate = 500 * time.Millisecond
113 + bar := pb.New64(0).Set(pb.Bytes, true).SetWriter(os.Stderr).SetRefreshRate(500 * time.Millisecond)
114 + bar.SetTemplateString(progressBarTemplate)
115 bar.Start()
116
117 var processedOneResponse bool
core/commands/dag/stat.go
+1 -11
@@ -95,17 +95,7 @@ func dagStat(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment)
95 }
96
97 func finishCLIStat(res cmds.Response, re cmds.ResponseEmitter) error {
98 - // Determine whether to show progress based on TTY detection or explicit flag
99 - var showProgress bool
100 - val, specified := res.Request().Options[progressOptionName]
101 - if !specified {
102 - // Auto-detect: show progress only if stderr is a TTY
103 - if errStat, err := os.Stderr.Stat(); err == nil {
104 - showProgress = (errStat.Mode() & os.ModeCharDevice) != 0
105 - }
106 - } else {
107 - showProgress = val.(bool)
108 - }
98 + showProgress := cmdenv.ShouldShowProgress(res.Request(), progressOptionName)
99
100 var dagStats *DagStatSummary
101 for {
core/commands/get.go
+7 -19
@@ -16,7 +16,7 @@ import (
16 "github.com/ipfs/kubo/core/commands/cmdutils"
17 "github.com/ipfs/kubo/core/commands/e"
18
19 - "github.com/cheggaaa/pb"
19 + "github.com/cheggaaa/pb/v3"
20 "github.com/ipfs/boxo/files"
21 "github.com/ipfs/boxo/tar"
22 cmds "github.com/ipfs/go-ipfs-cmds"
@@ -58,7 +58,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
58 cmds.BoolOption(archiveOptionName, "a", "Output a TAR archive."),
59 cmds.BoolOption(compressOptionName, "C", "Compress the output with GZIP compression."),
60 cmds.IntOption(compressionLevelOptionName, "l", "The level of compression (1-9)."),
61 - cmds.BoolOption(progressOptionName, "p", "Stream progress data.").WithDefault(true),
61 + cmds.BoolOption(progressOptionName, "p", "Stream progress data. Defaults to true when stderr is a terminal."),
62 },
63 PreRun: func(req *cmds.Request, env cmds.Environment) error {
64 _, err := getCompressOptions(req)
@@ -140,7 +140,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
140 }
141
142 archive, _ := req.Options[archiveOptionName].(bool)
143 - progress, _ := req.Options[progressOptionName].(bool)
143 + showProgress := cmdenv.ShouldShowProgress(req, progressOptionName)
144
145 gw := getWriter{
146 Out: os.Stdout,
@@ -148,7 +148,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
148 Archive: archive,
149 Compression: cmplvl,
150 Size: int64(res.Length()),
151 - Progress: progress,
151 + Progress: showProgress,
152 }
153
154 return gw.Write(outReader, outPath)
@@ -177,19 +177,7 @@ func progressBarForReader(out io.Writer, r io.Reader, l int64) (*pb.ProgressBar,
177 }
178
179 func makeProgressBar(out io.Writer, l int64) *pb.ProgressBar {
180 - // setup bar reader
181 - // TODO: get total length of files
182 - bar := pb.New64(l).SetUnits(pb.U_BYTES)
183 - bar.Output = out
184 -
185 - // the progress bar lib doesn't give us a way to get the width of the output,
186 - // so as a hack we just use a callback to measure the output, then get rid of it
187 - bar.Callback = func(line string) {
188 - terminalWidth := len(line)
189 - bar.Callback = nil
190 - log.Infof("terminal width: %v\n", terminalWidth)
191 - }
192 - return bar
180 + return pb.New64(l).Set(pb.Bytes, true).SetTemplateString(cmdenv.ProgressBarFullTemplate).SetWriter(out)
181 }
182
183 func getOutPath(req *cmds.Request) string {
@@ -260,8 +248,8 @@ func (gw *getWriter) writeExtracted(r io.Reader, fpath string) error {
248 bar := makeProgressBar(gw.Err, gw.Size)
249 bar.Start()
250 defer bar.Finish()
263 - defer bar.Set64(gw.Size)
264 - progressCb = bar.Add64
251 + defer bar.SetCurrent(gw.Size)
252 + progressCb = func(n int64) int64 { bar.Add64(n); return bar.Current() }
253 }
254
255 extractor := &tar.Extractor{Path: fpath, Progress: progressCb}
docs/changelogs/v0.42.md
+8
@@ -17,6 +17,7 @@ This release was brought to you by the [Shipyard](https://ipshipyard.com/) team.
17 - [🐛 Reliable shutdown and container health checks](#-reliable-shutdown-and-container-health-checks)
18 - [🚨 ERROR log for listeners blocked by `Swarm.AddrFilters` or `Addresses.NoAnnounce`](#-error-log-for-listeners-blocked-by-swarmaddrfilters-or-addressesnoannounce)
19 - [📊 OpenTelemetry: scope info now exposed as labels](#-opentelemetry-scope-info-now-exposed-as-labels)
20 + - [🔧 Cleaner progress bars](#-cleaner-progress-bars)
21 - [📦️ Dependency updates](#-dependency-updates)
22 - [📝 Changelog](#-changelog)
23 - [👨‍👩‍👧‍👦 Contributors](#-contributors)
@@ -89,11 +90,18 @@ Kubo now logs an ERROR when an [`Addresses.Swarm`](https://github.com/ipfs/kubo/
90
91 The Prometheus endpoint no longer emits the `otel_scope_info` metric. Each metric now carries `otel_scope_name`, `otel_scope_version`, and `otel_scope_schema_url` labels identifying the instrumentation library that produced it. Update dashboards or queries that read `otel_scope_info` to consume these labels instead. See [`docs/metrics.md`](https://github.com/ipfs/kubo/blob/master/docs/metrics.md) for details.
92
93 +#### 🔧 Cleaner progress bars
94 +
95 +`ipfs add`, `ipfs cat`, and `ipfs get` now hide their progress bar when stderr is piped or redirected, so a command like `ipfs add file 2> log.txt` no longer fills the log with progress-bar noise. Pass `--progress=true` to force the bar on, or `--progress=false` to hide it.
96 +
97 +`ipfs dag export` and `ipfs dag stat` now correctly recognize MSYS2 and Git Bash terminals on Windows. Previously the bar was suppressed there even when running interactively.
98 +
99 #### 📦️ Dependency updates
100
101 - update `go-libp2p-pubsub` to [v0.16.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.16.0)
102 - update `go-libp2p-kad-dht` to [b73e1e8](https://github.com/libp2p/go-libp2p-kad-dht/commit/b73e1e814f5f82e3554d350e61e33cae551084f6) (post-v0.39.2, includes [#1251](https://github.com/libp2p/go-libp2p-kad-dht/pull/1251) and [#1252](https://github.com/libp2p/go-libp2p-kad-dht/pull/1252))
103 - update `go-fuse/v2` to [v2.10.1](https://github.com/hanwen/go-fuse/releases/tag/v2.10.1)
104 +- update `cheggaaa/pb` to [v3.1.7](https://github.com/cheggaaa/pb/releases/tag/v3.1.7)
105
106 ### 📝 Changelog
107
go.mod
+7 -6
@@ -9,7 +9,7 @@ require (
9 github.com/caddyserver/certmagic v0.23.0
10 github.com/cenkalti/backoff/v4 v4.3.0
11 github.com/ceramicnetwork/go-dag-jose v0.1.1
12 - github.com/cheggaaa/pb v1.0.29
12 + github.com/cheggaaa/pb/v3 v3.1.7
13 github.com/cockroachdb/pebble/v2 v2.1.5
14 github.com/coreos/go-systemd/v22 v22.7.0
15 github.com/dustin/go-humanize v1.0.1
@@ -60,6 +60,7 @@ require (
60 github.com/libp2p/go-libp2p-routing-helpers v0.7.5
61 github.com/libp2p/go-libp2p-testing v0.12.0
62 github.com/libp2p/go-socket-activation v0.1.1
63 + github.com/mattn/go-isatty v0.0.22
64 github.com/miekg/dns v1.1.72
65 github.com/multiformats/go-multiaddr v0.16.1
66 github.com/multiformats/go-multiaddr-dns v0.5.0
@@ -104,6 +105,7 @@ require (
105 github.com/Jorropo/jsync v1.0.1 // indirect
106 github.com/RaduBerinde/axisds v0.1.0 // indirect
107 github.com/RaduBerinde/btreemap v0.0.0-20250419174037-3d62b7205d54 // indirect
108 + github.com/VividCortex/ewma v1.2.0 // indirect
109 github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
110 github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect
111 github.com/benbjohnson/clock v1.3.5 // indirect
@@ -127,7 +129,7 @@ require (
129 github.com/dgraph-io/ristretto v0.0.2 // indirect
130 github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
131 github.com/dunglas/httpsfv v1.1.0 // indirect
130 - github.com/fatih/color v1.15.0 // indirect
132 + github.com/fatih/color v1.18.0 // indirect
133 github.com/felixge/httpsnoop v1.0.4 // indirect
134 github.com/filecoin-project/go-clock v0.1.0 // indirect
135 github.com/flynn/noise v1.1.0 // indirect
@@ -179,9 +181,8 @@ require (
181 github.com/libp2p/go-yamux/v5 v5.0.1 // indirect
182 github.com/libp2p/zeroconf/v2 v2.2.0 // indirect
183 github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
182 - github.com/mattn/go-colorable v0.1.13 // indirect
183 - github.com/mattn/go-isatty v0.0.22 // indirect
184 - github.com/mattn/go-runewidth v0.0.15 // indirect
184 + github.com/mattn/go-colorable v0.1.14 // indirect
185 + github.com/mattn/go-runewidth v0.0.16 // indirect
186 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
187 github.com/mholt/acmez/v3 v3.1.2 // indirect
188 github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
@@ -225,7 +226,7 @@ require (
226 github.com/quic-go/qpack v0.6.0 // indirect
227 github.com/quic-go/quic-go v0.59.0 // indirect
228 github.com/quic-go/webtransport-go v0.10.0 // indirect
228 - github.com/rivo/uniseg v0.4.4 // indirect
229 + github.com/rivo/uniseg v0.4.7 // indirect
230 github.com/rogpeppe/go-internal v1.14.1 // indirect
231 github.com/rs/cors v1.11.1 // indirect
232 github.com/slok/go-http-metrics v0.13.0 // indirect
go.sum
+12 -17
@@ -58,6 +58,8 @@ github.com/RaduBerinde/axisds v0.1.0 h1:YItk/RmU5nvlsv/awo2Fjx97Mfpt4JfgtEVAGPrL
58 github.com/RaduBerinde/axisds v0.1.0/go.mod h1:UHGJonU9z4YYGKJxSaC6/TNcLOBptpmM5m2Cksbnw0Y=
59 github.com/RaduBerinde/btreemap v0.0.0-20250419174037-3d62b7205d54 h1:bsU8Tzxr/PNz75ayvCnxKZWEYdLMPDkUgticP4a4Bvk=
60 github.com/RaduBerinde/btreemap v0.0.0-20250419174037-3d62b7205d54/go.mod h1:0tr7FllbE9gJkHq7CVeeDDFAFKQVy5RnCSSNBOvdqbc=
61 +github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
62 +github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
63 github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f h1:JjxwchlOepwsUWcQwD2mLUAGE9aCp0/ehy6yCHFBOvo=
64 github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f/go.mod h1:tMDTce/yLLN/SK8gMOxQfnyeMeCg8KGzp0D1cbECEeo=
65 github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
@@ -116,8 +118,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
118 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
119 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
120 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
119 -github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo=
120 -github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30=
121 +github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI=
122 +github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ=
123 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
124 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
125 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -194,9 +196,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
196 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A=
197 github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg=
198 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
197 -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
198 -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
199 -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
199 +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
200 +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
201 github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
202 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
203 github.com/filecoin-project/go-clock v0.1.0 h1:SFbYIM75M8NnFm1yMHhN9Ahy3W5bEZV9gd6MPfXbKVU=
@@ -591,20 +592,15 @@ github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8
592 github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
593 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
594 github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
594 -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
595 -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
596 -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
595 +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
596 +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
597 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
598 github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
599 github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
600 -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
601 -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
602 -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
600 github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
601 github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
605 -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
606 -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
607 -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
602 +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
603 +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
604 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
605 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
606 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -815,8 +811,8 @@ github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRC
811 github.com/quic-go/webtransport-go v0.10.0 h1:LqXXPOXuETY5Xe8ITdGisBzTYmUOy5eSj+9n4hLTjHI=
812 github.com/quic-go/webtransport-go v0.10.0/go.mod h1:LeGIXr5BQKE3UsynwVBeQrU1TPrbh73MGoC6jd+V7ow=
813 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
818 -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
819 -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
814 +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
815 +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
816 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
817 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
818 github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
@@ -1230,7 +1226,6 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc
1226 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1227 golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1228 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1233 -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1229 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1230 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1231 golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=