mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
fix: ipfs pin ls <cid> --names (#10970)
* fix: use CheckIfPinnedWithType for pin ls with names updates to use CheckIfPinnedWithType method from https://github.com/ipfs/boxo/pull/1035, enabling efficient pin name retrieval for 'ipfs pin ls <cid> --names' - uses new CheckIfPinnedWithType from boxo for type-specific pin checks - pin names are now returned when listing specific CIDs with --names flag * test: add CLI tests for pin ls with names tests cover: - pin ls with specific CIDs returning names - pin ls without CID listing all pins with names - pin ls with --type and --names combinations - JSON output with and without names - pin update preserving names - error cases (invalid CID, unpinned CID) * docs: add pin name improvements to v0.38 changelog covers fix for ipfs pin ls --names with specific CIDs and RPC pin name leak fix * fix(rpc): support pin names in Add() passes the Name field from PinAddSettings to the API request adds test to verify pin names work via RPC * test: add coverage for pin names functionality - test special characters, unicode, long names - test concurrent operations - test persistence across daemon restarts - test garbage collection preservation - fix indirect pin test logic * chore: boxo@main with boxo#1039 * fix(pin): improve pin ls robustness and validation - add nil check for n.Pinning with early fail-fast validation - use pin.StringToMode() for consistent type validation - add edge case tests for invalid types and unpinned CIDs
This commit is contained in:
parent
1f66101321
commit
d37b92bfcd
@ -52,8 +52,12 @@ func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOp
|
||||
return err
|
||||
}
|
||||
|
||||
return api.core().Request("pin/add", p.String()).
|
||||
Option("recursive", options.Recursive).Exec(ctx, nil)
|
||||
req := api.core().Request("pin/add", p.String()).
|
||||
Option("recursive", options.Recursive)
|
||||
if options.Name != "" {
|
||||
req = req.Option("name", options.Name)
|
||||
}
|
||||
return req.Exec(ctx, nil)
|
||||
}
|
||||
|
||||
type pinLsObject struct {
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
bserv "github.com/ipfs/boxo/blockservice"
|
||||
offline "github.com/ipfs/boxo/exchange/offline"
|
||||
dag "github.com/ipfs/boxo/ipld/merkledag"
|
||||
pin "github.com/ipfs/boxo/pinning/pinner"
|
||||
verifcid "github.com/ipfs/boxo/verifcid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cidenc "github.com/ipfs/go-cidutil/cidenc"
|
||||
@ -370,16 +371,23 @@ Example:
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := cmdenv.GetNode(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if n.Pinning == nil {
|
||||
return fmt.Errorf("pinning service not available")
|
||||
}
|
||||
|
||||
typeStr, _ := req.Options[pinTypeOptionName].(string)
|
||||
stream, _ := req.Options[pinStreamOptionName].(bool)
|
||||
displayNames, _ := req.Options[pinNamesOptionName].(bool)
|
||||
name, _ := req.Options[pinNameOptionName].(string)
|
||||
|
||||
switch typeStr {
|
||||
case "all", "direct", "indirect", "recursive":
|
||||
default:
|
||||
err = fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr)
|
||||
return err
|
||||
mode, ok := pin.StringToMode(typeStr)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr)
|
||||
}
|
||||
|
||||
// For backward compatibility, we accumulate the pins in the same output type as before.
|
||||
@ -397,7 +405,7 @@ Example:
|
||||
}
|
||||
|
||||
if len(req.Arguments) > 0 {
|
||||
err = pinLsKeys(req, typeStr, api, emit)
|
||||
err = pinLsKeys(req, mode, displayNames || name != "", n.Pinning, api, emit)
|
||||
} else {
|
||||
err = pinLsAll(req, typeStr, displayNames || name != "", name, api, emit)
|
||||
}
|
||||
@ -482,23 +490,14 @@ type PinLsObject struct {
|
||||
Type string `json:",omitempty"`
|
||||
}
|
||||
|
||||
func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error {
|
||||
func pinLsKeys(req *cmds.Request, mode pin.Mode, displayNames bool, pinner pin.Pinner, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error {
|
||||
enc, err := cmdenv.GetCidEncoder(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch typeStr {
|
||||
case "all", "direct", "indirect", "recursive":
|
||||
default:
|
||||
return fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr)
|
||||
}
|
||||
|
||||
opt, err := options.Pin.IsPinned.Type(typeStr)
|
||||
if err != nil {
|
||||
panic("unhandled pin type")
|
||||
}
|
||||
|
||||
// Collect CIDs to check
|
||||
cids := make([]cid.Cid, 0, len(req.Arguments))
|
||||
for _, p := range req.Arguments {
|
||||
p, err := cmdutils.PathOrCidPath(p)
|
||||
if err != nil {
|
||||
@ -510,25 +509,31 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu
|
||||
return err
|
||||
}
|
||||
|
||||
pinType, pinned, err := api.Pin().IsPinned(req.Context, rp, opt)
|
||||
if err != nil {
|
||||
return err
|
||||
cids = append(cids, rp.RootCid())
|
||||
}
|
||||
|
||||
// Check pins using the new type-specific method
|
||||
pinned, err := pinner.CheckIfPinnedWithType(req.Context, mode, displayNames, cids...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Process results
|
||||
for i, p := range pinned {
|
||||
if !p.Pinned() {
|
||||
return fmt.Errorf("path '%s' is not pinned", req.Arguments[i])
|
||||
}
|
||||
|
||||
if !pinned {
|
||||
return fmt.Errorf("path '%s' is not pinned", p)
|
||||
}
|
||||
|
||||
switch pinType {
|
||||
case "direct", "indirect", "recursive", "internal":
|
||||
default:
|
||||
pinType = "indirect through " + pinType
|
||||
pinType, _ := pin.ModeToString(p.Mode)
|
||||
if p.Mode == pin.Indirect && p.Via.Defined() {
|
||||
pinType = "indirect through " + enc.Encode(p.Via)
|
||||
}
|
||||
|
||||
err = emit(PinLsOutputWrapper{
|
||||
PinLsObject: PinLsObject{
|
||||
Type: pinType,
|
||||
Cid: enc.Encode(rp.RootCid()),
|
||||
Cid: enc.Encode(cids[i]),
|
||||
Name: p.Name,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
@ -545,11 +550,9 @@ func pinLsAll(req *cmds.Request, typeStr string, detailed bool, name string, api
|
||||
return err
|
||||
}
|
||||
|
||||
switch typeStr {
|
||||
case "all", "direct", "indirect", "recursive":
|
||||
default:
|
||||
err = fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr)
|
||||
return err
|
||||
_, ok := pin.StringToMode(typeStr)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr)
|
||||
}
|
||||
|
||||
opt, err := options.Pin.Ls.Type(typeStr)
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
iface "github.com/ipfs/kubo/core/coreiface"
|
||||
opt "github.com/ipfs/kubo/core/coreiface/options"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func (tp *TestSuite) TestPin(t *testing.T) {
|
||||
@ -28,6 +29,7 @@ func (tp *TestSuite) TestPin(t *testing.T) {
|
||||
t.Run("TestPinLsIndirect", tp.TestPinLsIndirect)
|
||||
t.Run("TestPinLsPrecedence", tp.TestPinLsPrecedence)
|
||||
t.Run("TestPinIsPinned", tp.TestPinIsPinned)
|
||||
t.Run("TestPinNames", tp.TestPinNames)
|
||||
}
|
||||
|
||||
func (tp *TestSuite) TestPinAdd(t *testing.T) {
|
||||
@ -580,6 +582,145 @@ func assertIsPinned(t *testing.T, ctx context.Context, api iface.CoreAPI, p path
|
||||
}
|
||||
}
|
||||
|
||||
func (tp *TestSuite) TestPinNames(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
api, err := tp.makeAPI(t, ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create test content
|
||||
p1, err := api.Unixfs().Add(ctx, strFile("content1")())
|
||||
require.NoError(t, err)
|
||||
|
||||
p2, err := api.Unixfs().Add(ctx, strFile("content2")())
|
||||
require.NoError(t, err)
|
||||
|
||||
p3, err := api.Unixfs().Add(ctx, strFile("content3")())
|
||||
require.NoError(t, err)
|
||||
|
||||
p4, err := api.Unixfs().Add(ctx, strFile("content4")())
|
||||
require.NoError(t, err)
|
||||
|
||||
// Test 1: Pin with name
|
||||
err = api.Pin().Add(ctx, p1, opt.Pin.Name("test-pin-1"))
|
||||
require.NoError(t, err, "failed to add pin with name")
|
||||
|
||||
// Test 2: Pin without name
|
||||
err = api.Pin().Add(ctx, p2)
|
||||
require.NoError(t, err, "failed to add pin without name")
|
||||
|
||||
// Test 3: List pins with detailed option to get names
|
||||
pins := make(chan iface.Pin)
|
||||
go func() {
|
||||
err = api.Pin().Ls(ctx, pins, opt.Pin.Ls.Detailed(true))
|
||||
}()
|
||||
|
||||
pinMap := make(map[string]string)
|
||||
for pin := range pins {
|
||||
pinMap[pin.Path().String()] = pin.Name()
|
||||
}
|
||||
require.NoError(t, err, "failed to list pins with names")
|
||||
|
||||
// Verify pin names
|
||||
name1, ok := pinMap[p1.String()]
|
||||
require.True(t, ok, "pin for %s not found", p1)
|
||||
require.Equal(t, "test-pin-1", name1, "unexpected pin name for %s", p1)
|
||||
|
||||
name2, ok := pinMap[p2.String()]
|
||||
require.True(t, ok, "pin for %s not found", p2)
|
||||
require.Empty(t, name2, "expected empty pin name for %s, got '%s'", p2, name2)
|
||||
|
||||
// Test 4: Pin update preserves name
|
||||
err = api.Pin().Add(ctx, p3, opt.Pin.Name("updatable-pin"))
|
||||
require.NoError(t, err, "failed to add pin with name for update test")
|
||||
|
||||
err = api.Pin().Update(ctx, p3, p4)
|
||||
require.NoError(t, err, "failed to update pin")
|
||||
|
||||
// Verify name was preserved after update
|
||||
pins2 := make(chan iface.Pin)
|
||||
go func() {
|
||||
err = api.Pin().Ls(ctx, pins2, opt.Pin.Ls.Detailed(true))
|
||||
}()
|
||||
|
||||
updatedPinMap := make(map[string]string)
|
||||
for pin := range pins2 {
|
||||
updatedPinMap[pin.Path().String()] = pin.Name()
|
||||
}
|
||||
require.NoError(t, err, "failed to list pins after update")
|
||||
|
||||
// Old pin should not exist
|
||||
_, oldExists := updatedPinMap[p3.String()]
|
||||
require.False(t, oldExists, "old pin %s should not exist after update", p3)
|
||||
|
||||
// New pin should have the preserved name
|
||||
name4, ok := updatedPinMap[p4.String()]
|
||||
require.True(t, ok, "updated pin for %s not found", p4)
|
||||
require.Equal(t, "updatable-pin", name4, "pin name not preserved after update from %s to %s", p3, p4)
|
||||
|
||||
// Test 5: Re-pinning with different name updates the name
|
||||
err = api.Pin().Add(ctx, p1, opt.Pin.Name("new-name-for-p1"))
|
||||
require.NoError(t, err, "failed to re-pin with new name")
|
||||
|
||||
// Verify name was updated
|
||||
pins3 := make(chan iface.Pin)
|
||||
go func() {
|
||||
err = api.Pin().Ls(ctx, pins3, opt.Pin.Ls.Detailed(true))
|
||||
}()
|
||||
|
||||
repinMap := make(map[string]string)
|
||||
for pin := range pins3 {
|
||||
repinMap[pin.Path().String()] = pin.Name()
|
||||
}
|
||||
require.NoError(t, err, "failed to list pins after re-pin")
|
||||
|
||||
rePinnedName, ok := repinMap[p1.String()]
|
||||
require.True(t, ok, "re-pinned content %s not found", p1)
|
||||
require.Equal(t, "new-name-for-p1", rePinnedName, "pin name not updated after re-pinning %s", p1)
|
||||
|
||||
// Test 6: Direct pin with name
|
||||
p5, err := api.Unixfs().Add(ctx, strFile("direct-content")())
|
||||
require.NoError(t, err)
|
||||
|
||||
err = api.Pin().Add(ctx, p5, opt.Pin.Recursive(false), opt.Pin.Name("direct-pin-name"))
|
||||
require.NoError(t, err, "failed to add direct pin with name")
|
||||
|
||||
// Verify direct pin has name
|
||||
directPins := make(chan iface.Pin)
|
||||
typeOpt, err := opt.Pin.Ls.Type("direct")
|
||||
require.NoError(t, err, "failed to create type option")
|
||||
go func() {
|
||||
err = api.Pin().Ls(ctx, directPins, typeOpt, opt.Pin.Ls.Detailed(true))
|
||||
}()
|
||||
|
||||
directPinMap := make(map[string]string)
|
||||
for pin := range directPins {
|
||||
directPinMap[pin.Path().String()] = pin.Name()
|
||||
}
|
||||
require.NoError(t, err, "failed to list direct pins")
|
||||
|
||||
directName, ok := directPinMap[p5.String()]
|
||||
require.True(t, ok, "direct pin %s not found", p5)
|
||||
require.Equal(t, "direct-pin-name", directName, "unexpected name for direct pin %s", p5)
|
||||
|
||||
// Test 7: List without detailed option doesn't return names
|
||||
pinsNoDetails := make(chan iface.Pin)
|
||||
go func() {
|
||||
err = api.Pin().Ls(ctx, pinsNoDetails)
|
||||
}()
|
||||
|
||||
noDetailsMap := make(map[string]string)
|
||||
for pin := range pinsNoDetails {
|
||||
noDetailsMap[pin.Path().String()] = pin.Name()
|
||||
}
|
||||
require.NoError(t, err, "failed to list pins without detailed option")
|
||||
|
||||
// All names should be empty without detailed option
|
||||
for path, name := range noDetailsMap {
|
||||
require.Empty(t, name, "expected empty name for %s without detailed option, got '%s'", path, name)
|
||||
}
|
||||
}
|
||||
|
||||
func assertNotPinned(t *testing.T, ctx context.Context, api iface.CoreAPI, p path.Path) {
|
||||
t.Helper()
|
||||
|
||||
|
||||
@ -64,6 +64,10 @@ Gateway error pages now provide more actionable information during content retri
|
||||
> - **Enhanced error details**: Timeout errors now display the retrieval phase where failure occurred (e.g., "connecting to providers", "fetching data") and up to 3 peer IDs that were attempted but couldn't deliver the content, making it easier to diagnose network or provider issues.
|
||||
> - **Retry button on all error pages**: Every gateway error page now includes a retry button for quick page refresh without manual URL re-entry.
|
||||
|
||||
#### 📌 Pin name improvements
|
||||
|
||||
`ipfs pin ls <cid> --names` now correctly returns pin names for specific CIDs ([#10649](https://github.com/ipfs/kubo/issues/10649), [boxo#1035](https://github.com/ipfs/boxo/pull/1035)), and RPC no longer incorrectly returns names from other pins ([#10966](https://github.com/ipfs/kubo/pull/10966)).
|
||||
|
||||
#### 🛠️ Identity CID size enforcement and `ipfs files write` fixes
|
||||
|
||||
**Identity CID size limits are now enforced**
|
||||
|
||||
@ -7,7 +7,7 @@ go 1.25
|
||||
replace github.com/ipfs/kubo => ./../../..
|
||||
|
||||
require (
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f
|
||||
github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
|
||||
github.com/libp2p/go-libp2p v0.43.0
|
||||
github.com/multiformats/go-multiaddr v0.16.1
|
||||
@ -73,10 +73,10 @@ require (
|
||||
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 // indirect
|
||||
github.com/ipfs/bbloom v0.0.4 // indirect
|
||||
github.com/ipfs/go-bitfield v1.1.0 // indirect
|
||||
github.com/ipfs/go-block-format v0.2.2 // indirect
|
||||
github.com/ipfs/go-block-format v0.2.3 // indirect
|
||||
github.com/ipfs/go-cid v0.5.0 // indirect
|
||||
github.com/ipfs/go-cidutil v0.1.0 // indirect
|
||||
github.com/ipfs/go-datastore v0.8.4 // indirect
|
||||
github.com/ipfs/go-datastore v0.9.0 // indirect
|
||||
github.com/ipfs/go-ds-badger v0.3.4 // indirect
|
||||
github.com/ipfs/go-ds-flatfs v0.5.5 // indirect
|
||||
github.com/ipfs/go-ds-leveldb v0.5.2 // indirect
|
||||
@ -88,14 +88,14 @@ require (
|
||||
github.com/ipfs/go-ipfs-pq v0.0.3 // indirect
|
||||
github.com/ipfs/go-ipfs-redirects-file v0.1.2 // indirect
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1 // indirect
|
||||
github.com/ipfs/go-ipld-format v0.6.2 // indirect
|
||||
github.com/ipfs/go-ipld-format v0.6.3 // indirect
|
||||
github.com/ipfs/go-ipld-git v0.1.1 // indirect
|
||||
github.com/ipfs/go-ipld-legacy v0.2.2 // indirect
|
||||
github.com/ipfs/go-log/v2 v2.8.1 // indirect
|
||||
github.com/ipfs/go-metrics-interface v0.3.0 // indirect
|
||||
github.com/ipfs/go-peertaskqueue v0.8.2 // indirect
|
||||
github.com/ipfs/go-test v0.2.3 // indirect
|
||||
github.com/ipfs/go-unixfsnode v1.10.1 // indirect
|
||||
github.com/ipfs/go-unixfsnode v1.10.2 // indirect
|
||||
github.com/ipld/go-car/v2 v2.15.0 // indirect
|
||||
github.com/ipld/go-codec-dagpb v1.7.0 // indirect
|
||||
github.com/ipld/go-ipld-prime v0.21.0 // indirect
|
||||
@ -209,15 +209,16 @@ require (
|
||||
go.uber.org/zap/exp v0.3.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect
|
||||
golang.org/x/mod v0.27.0 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/crypto v0.42.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect
|
||||
golang.org/x/mod v0.28.0 // indirect
|
||||
golang.org/x/net v0.44.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
golang.org/x/tools v0.37.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
gonum.org/v1/gonum v0.16.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
|
||||
@ -289,13 +289,13 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd
|
||||
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3 h1:qp8w52Rf5eEOrNFZ1VdLSOU3kA5N2EGMNv0xZAACSfs=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3/go.mod h1:YbQ2GM5GolkfJ8qB29RL+cXgFEa/HsDrHeHSB+fOrlY=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f h1:In4WBnF9sysZwHV6bYTdnLtyRMOQTtvW1leZzxP4bbg=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f/go.mod h1:uhaF0DGnbgEiXDTmD249jCGbxVkMm6+Ew85q6Uub7lo=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk=
|
||||
github.com/ipfs/go-block-format v0.2.2 h1:uecCTgRwDIXyZPgYspaLXoMiMmxQpSx2aq34eNc4YvQ=
|
||||
github.com/ipfs/go-block-format v0.2.2/go.mod h1:vmuefuWU6b+9kIU0vZJgpiJt1yicQz9baHXE8qR+KB8=
|
||||
github.com/ipfs/go-block-format v0.2.3 h1:mpCuDaNXJ4wrBJLrtEaGFGXkferrw5eqVvzaHhtFKQk=
|
||||
github.com/ipfs/go-block-format v0.2.3/go.mod h1:WJaQmPAKhD3LspLixqlqNFxiZ3BZ3xgqxxoSR/76pnA=
|
||||
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||
github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M=
|
||||
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
||||
@ -305,8 +305,8 @@ github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q
|
||||
github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA=
|
||||
github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||
github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
|
||||
github.com/ipfs/go-datastore v0.8.4 h1:vXEsd76T3KIOSKXizjhmS3ICGMl+oOSjpLSxE3v8/Wc=
|
||||
github.com/ipfs/go-datastore v0.8.4/go.mod h1:uT77w/XEGrvJWwHgdrMr8bqCN6ZTW9gzmi+3uK+ouHg=
|
||||
github.com/ipfs/go-datastore v0.9.0 h1:WocriPOayqalEsueHv6SdD4nPVl4rYMfYGLD4bqCZ+w=
|
||||
github.com/ipfs/go-datastore v0.9.0/go.mod h1:uT77w/XEGrvJWwHgdrMr8bqCN6ZTW9gzmi+3uK+ouHg=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk=
|
||||
@ -340,8 +340,8 @@ github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyB
|
||||
github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ=
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1 h1:H05yEJbK/hxg0uf2AJhyerBDbjOuHX4yi+1U/ogRa7E=
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1/go.mod h1:x9Zbeq8CoE5R2WicYgBMcr/9mnkQ0lHddYWJP2sMV3A=
|
||||
github.com/ipfs/go-ipld-format v0.6.2 h1:bPZQ+A05ol0b3lsJSl0bLvwbuQ+HQbSsdGTy4xtYUkU=
|
||||
github.com/ipfs/go-ipld-format v0.6.2/go.mod h1:nni2xFdHKx5lxvXJ6brt/pndtGxKAE+FPR1rg4jTkyk=
|
||||
github.com/ipfs/go-ipld-format v0.6.3 h1:9/lurLDTotJpZSuL++gh3sTdmcFhVkCwsgx2+rAh4j8=
|
||||
github.com/ipfs/go-ipld-format v0.6.3/go.mod h1:74ilVN12NXVMIV+SrBAyC05UJRk0jVvGqdmrcYZvCBk=
|
||||
github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y=
|
||||
github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI=
|
||||
github.com/ipfs/go-ipld-legacy v0.2.2 h1:DThbqCPVLpWBcGtU23KDLiY2YRZZnTkXQyfz8aOfBkQ=
|
||||
@ -357,8 +357,8 @@ github.com/ipfs/go-peertaskqueue v0.8.2 h1:PaHFRaVFdxQk1Qo3OKiHPYjmmusQy7gKQUaL8
|
||||
github.com/ipfs/go-peertaskqueue v0.8.2/go.mod h1:L6QPvou0346c2qPJNiJa6BvOibxDfaiPlqHInmzg0FA=
|
||||
github.com/ipfs/go-test v0.2.3 h1:Z/jXNAReQFtCYyn7bsv/ZqUwS6E7iIcSpJ2CuzCvnrc=
|
||||
github.com/ipfs/go-test v0.2.3/go.mod h1:QW8vSKkwYvWFwIZQLGQXdkt9Ud76eQXRQ9Ao2H+cA1o=
|
||||
github.com/ipfs/go-unixfsnode v1.10.1 h1:hGKhzuH6NSzZ4y621wGuDspkjXRNG3B+HqhlyTjSwSM=
|
||||
github.com/ipfs/go-unixfsnode v1.10.1/go.mod h1:eguv/otvacjmfSbYvmamc9ssNAzLvRk0+YN30EYeOOY=
|
||||
github.com/ipfs/go-unixfsnode v1.10.2 h1:TREegX1J4X+k1w4AhoDuxxFvVcS9SegMRvrmxF6Tca8=
|
||||
github.com/ipfs/go-unixfsnode v1.10.2/go.mod h1:ImDPTSiKZ+2h4UVdkSDITJHk87bUAp7kX/lgifjRicg=
|
||||
github.com/ipld/go-car/v2 v2.15.0 h1:RxtZcGXFx72zFESl+UUsCNQV2YMcy3gEMYx9M3uio24=
|
||||
github.com/ipld/go-car/v2 v2.15.0/go.mod h1:ovlq/n3xlVJDmoiN3Kd/Z7kIzQbdTIFSwltfOP+qIgk=
|
||||
github.com/ipld/go-codec-dagpb v1.7.0 h1:hpuvQjCSVSLnTnHXn+QAMR0mLmb1gA6wl10LExo2Ts0=
|
||||
@ -840,8 +840,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -850,8 +850,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU=
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@ -874,8 +874,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
|
||||
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -911,8 +911,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -981,6 +981,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8=
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@ -1000,8 +1002,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -1042,8 +1044,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
25
go.mod
25
go.mod
@ -22,11 +22,11 @@ require (
|
||||
github.com/hashicorp/go-version v1.7.0
|
||||
github.com/ipfs-shipyard/nopfs v0.0.14
|
||||
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3
|
||||
github.com/ipfs/go-block-format v0.2.2
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f
|
||||
github.com/ipfs/go-block-format v0.2.3
|
||||
github.com/ipfs/go-cid v0.5.0
|
||||
github.com/ipfs/go-cidutil v0.1.0
|
||||
github.com/ipfs/go-datastore v0.8.4
|
||||
github.com/ipfs/go-datastore v0.9.0
|
||||
github.com/ipfs/go-detect-race v0.0.1
|
||||
github.com/ipfs/go-ds-badger v0.3.4
|
||||
github.com/ipfs/go-ds-flatfs v0.5.5
|
||||
@ -36,14 +36,14 @@ require (
|
||||
github.com/ipfs/go-fs-lock v0.1.1
|
||||
github.com/ipfs/go-ipfs-cmds v0.15.0
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1
|
||||
github.com/ipfs/go-ipld-format v0.6.2
|
||||
github.com/ipfs/go-ipld-format v0.6.3
|
||||
github.com/ipfs/go-ipld-git v0.1.1
|
||||
github.com/ipfs/go-ipld-legacy v0.2.2
|
||||
github.com/ipfs/go-log/v2 v2.8.1
|
||||
github.com/ipfs/go-metrics-interface v0.3.0
|
||||
github.com/ipfs/go-metrics-prometheus v0.1.0
|
||||
github.com/ipfs/go-test v0.2.3
|
||||
github.com/ipfs/go-unixfsnode v1.10.1
|
||||
github.com/ipfs/go-unixfsnode v1.10.2
|
||||
github.com/ipld/go-car/v2 v2.15.0
|
||||
github.com/ipld/go-codec-dagpb v1.7.0
|
||||
github.com/ipld/go-ipld-prime v0.21.0
|
||||
@ -87,9 +87,9 @@ require (
|
||||
go.uber.org/dig v1.19.0
|
||||
go.uber.org/fx v1.24.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.41.0
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b
|
||||
golang.org/x/mod v0.27.0
|
||||
golang.org/x/crypto v0.42.0
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621
|
||||
golang.org/x/mod v0.28.0
|
||||
golang.org/x/sync v0.17.0
|
||||
golang.org/x/sys v0.36.0
|
||||
google.golang.org/protobuf v1.36.9
|
||||
@ -254,12 +254,13 @@ require (
|
||||
go.uber.org/zap/exp v0.3.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/net v0.44.0 // indirect
|
||||
golang.org/x/oauth2 v0.31.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect
|
||||
golang.org/x/term v0.35.0 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
golang.org/x/tools v0.37.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
gonum.org/v1/gonum v0.16.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
|
||||
50
go.sum
50
go.sum
@ -356,13 +356,13 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd
|
||||
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3 h1:qp8w52Rf5eEOrNFZ1VdLSOU3kA5N2EGMNv0xZAACSfs=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3/go.mod h1:YbQ2GM5GolkfJ8qB29RL+cXgFEa/HsDrHeHSB+fOrlY=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f h1:In4WBnF9sysZwHV6bYTdnLtyRMOQTtvW1leZzxP4bbg=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f/go.mod h1:uhaF0DGnbgEiXDTmD249jCGbxVkMm6+Ew85q6Uub7lo=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk=
|
||||
github.com/ipfs/go-block-format v0.2.2 h1:uecCTgRwDIXyZPgYspaLXoMiMmxQpSx2aq34eNc4YvQ=
|
||||
github.com/ipfs/go-block-format v0.2.2/go.mod h1:vmuefuWU6b+9kIU0vZJgpiJt1yicQz9baHXE8qR+KB8=
|
||||
github.com/ipfs/go-block-format v0.2.3 h1:mpCuDaNXJ4wrBJLrtEaGFGXkferrw5eqVvzaHhtFKQk=
|
||||
github.com/ipfs/go-block-format v0.2.3/go.mod h1:WJaQmPAKhD3LspLixqlqNFxiZ3BZ3xgqxxoSR/76pnA=
|
||||
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||
github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M=
|
||||
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
||||
@ -372,8 +372,8 @@ github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q
|
||||
github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA=
|
||||
github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||
github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
|
||||
github.com/ipfs/go-datastore v0.8.4 h1:vXEsd76T3KIOSKXizjhmS3ICGMl+oOSjpLSxE3v8/Wc=
|
||||
github.com/ipfs/go-datastore v0.8.4/go.mod h1:uT77w/XEGrvJWwHgdrMr8bqCN6ZTW9gzmi+3uK+ouHg=
|
||||
github.com/ipfs/go-datastore v0.9.0 h1:WocriPOayqalEsueHv6SdD4nPVl4rYMfYGLD4bqCZ+w=
|
||||
github.com/ipfs/go-datastore v0.9.0/go.mod h1:uT77w/XEGrvJWwHgdrMr8bqCN6ZTW9gzmi+3uK+ouHg=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk=
|
||||
@ -409,8 +409,8 @@ github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyB
|
||||
github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ=
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1 h1:H05yEJbK/hxg0uf2AJhyerBDbjOuHX4yi+1U/ogRa7E=
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1/go.mod h1:x9Zbeq8CoE5R2WicYgBMcr/9mnkQ0lHddYWJP2sMV3A=
|
||||
github.com/ipfs/go-ipld-format v0.6.2 h1:bPZQ+A05ol0b3lsJSl0bLvwbuQ+HQbSsdGTy4xtYUkU=
|
||||
github.com/ipfs/go-ipld-format v0.6.2/go.mod h1:nni2xFdHKx5lxvXJ6brt/pndtGxKAE+FPR1rg4jTkyk=
|
||||
github.com/ipfs/go-ipld-format v0.6.3 h1:9/lurLDTotJpZSuL++gh3sTdmcFhVkCwsgx2+rAh4j8=
|
||||
github.com/ipfs/go-ipld-format v0.6.3/go.mod h1:74ilVN12NXVMIV+SrBAyC05UJRk0jVvGqdmrcYZvCBk=
|
||||
github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y=
|
||||
github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI=
|
||||
github.com/ipfs/go-ipld-legacy v0.2.2 h1:DThbqCPVLpWBcGtU23KDLiY2YRZZnTkXQyfz8aOfBkQ=
|
||||
@ -428,8 +428,8 @@ github.com/ipfs/go-peertaskqueue v0.8.2 h1:PaHFRaVFdxQk1Qo3OKiHPYjmmusQy7gKQUaL8
|
||||
github.com/ipfs/go-peertaskqueue v0.8.2/go.mod h1:L6QPvou0346c2qPJNiJa6BvOibxDfaiPlqHInmzg0FA=
|
||||
github.com/ipfs/go-test v0.2.3 h1:Z/jXNAReQFtCYyn7bsv/ZqUwS6E7iIcSpJ2CuzCvnrc=
|
||||
github.com/ipfs/go-test v0.2.3/go.mod h1:QW8vSKkwYvWFwIZQLGQXdkt9Ud76eQXRQ9Ao2H+cA1o=
|
||||
github.com/ipfs/go-unixfsnode v1.10.1 h1:hGKhzuH6NSzZ4y621wGuDspkjXRNG3B+HqhlyTjSwSM=
|
||||
github.com/ipfs/go-unixfsnode v1.10.1/go.mod h1:eguv/otvacjmfSbYvmamc9ssNAzLvRk0+YN30EYeOOY=
|
||||
github.com/ipfs/go-unixfsnode v1.10.2 h1:TREegX1J4X+k1w4AhoDuxxFvVcS9SegMRvrmxF6Tca8=
|
||||
github.com/ipfs/go-unixfsnode v1.10.2/go.mod h1:ImDPTSiKZ+2h4UVdkSDITJHk87bUAp7kX/lgifjRicg=
|
||||
github.com/ipld/go-car/v2 v2.15.0 h1:RxtZcGXFx72zFESl+UUsCNQV2YMcy3gEMYx9M3uio24=
|
||||
github.com/ipld/go-car/v2 v2.15.0/go.mod h1:ovlq/n3xlVJDmoiN3Kd/Z7kIzQbdTIFSwltfOP+qIgk=
|
||||
github.com/ipld/go-codec-dagpb v1.7.0 h1:hpuvQjCSVSLnTnHXn+QAMR0mLmb1gA6wl10LExo2Ts0=
|
||||
@ -1007,8 +1007,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -1019,8 +1019,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU=
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@ -1044,8 +1044,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
|
||||
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -1097,8 +1097,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -1196,6 +1196,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8=
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@ -1204,8 +1206,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
|
||||
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1217,8 +1219,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -1276,8 +1278,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
534
test/cli/pin_ls_names_test.go
Normal file
534
test/cli/pin_ls_names_test.go
Normal file
@ -0,0 +1,534 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ipfs/kubo/test/cli/harness"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// pinInfo represents the JSON structure for pin ls output
|
||||
type pinInfo struct {
|
||||
Type string `json:"Type"`
|
||||
Name string `json:"Name"`
|
||||
}
|
||||
|
||||
// pinLsJSON represents the JSON output structure for pin ls command
|
||||
type pinLsJSON struct {
|
||||
Keys map[string]pinInfo `json:"Keys"`
|
||||
}
|
||||
|
||||
// Helper function to initialize a test node with daemon
|
||||
func setupTestNode(t *testing.T) *harness.Node {
|
||||
t.Helper()
|
||||
node := harness.NewT(t).NewNode().Init()
|
||||
node.StartDaemon("--offline")
|
||||
return node
|
||||
}
|
||||
|
||||
// Helper function to assert pin name and CID are present in output
|
||||
func assertPinOutput(t *testing.T, output, cid, pinName string) {
|
||||
t.Helper()
|
||||
require.Contains(t, output, pinName, "pin name '%s' not found in output: %s", pinName, output)
|
||||
require.Contains(t, output, cid, "CID %s not found in output: %s", cid, output)
|
||||
}
|
||||
|
||||
// Helper function to assert CID is present but name is not
|
||||
func assertCIDOnly(t *testing.T, output, cid string) {
|
||||
t.Helper()
|
||||
require.Contains(t, output, cid, "CID %s not found in output: %s", cid, output)
|
||||
}
|
||||
|
||||
// Helper function to assert neither CID nor name are present
|
||||
func assertNotPresent(t *testing.T, output, cid, pinName string) {
|
||||
t.Helper()
|
||||
require.NotContains(t, output, cid, "CID %s should not be present in output: %s", cid, output)
|
||||
require.NotContains(t, output, pinName, "pin name '%s' should not be present in output: %s", pinName, output)
|
||||
}
|
||||
|
||||
// Test that pin ls returns names when querying specific CIDs with --names flag
|
||||
func TestPinLsWithNamesForSpecificCIDs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("pin ls with specific CID returns name", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Add content without pinning
|
||||
cidA := node.IPFSAddStr("content A", "--pin=false")
|
||||
cidB := node.IPFSAddStr("content B", "--pin=false")
|
||||
cidC := node.IPFSAddStr("content C", "--pin=false")
|
||||
|
||||
// Pin with names
|
||||
node.IPFS("pin", "add", "--name=pin-a", cidA)
|
||||
node.IPFS("pin", "add", "--name=pin-b", cidB)
|
||||
node.IPFS("pin", "add", cidC) // No name
|
||||
|
||||
// Test: pin ls <cid> --names should return the name
|
||||
res := node.IPFS("pin", "ls", cidA, "--names")
|
||||
assertPinOutput(t, res.Stdout.String(), cidA, "pin-a")
|
||||
|
||||
res = node.IPFS("pin", "ls", cidB, "--names")
|
||||
assertPinOutput(t, res.Stdout.String(), cidB, "pin-b")
|
||||
|
||||
// Test: pin without name should work
|
||||
res = node.IPFS("pin", "ls", cidC, "--names")
|
||||
output := res.Stdout.String()
|
||||
assertCIDOnly(t, output, cidC)
|
||||
require.Contains(t, output, "recursive", "pin type 'recursive' not found for CID %s in output: %s", cidC, output)
|
||||
|
||||
// Test: without --names flag, no names returned
|
||||
res = node.IPFS("pin", "ls", cidA)
|
||||
output = res.Stdout.String()
|
||||
require.NotContains(t, output, "pin-a", "pin name 'pin-a' should not be present without --names flag, but found in: %s", output)
|
||||
assertCIDOnly(t, output, cidA)
|
||||
})
|
||||
|
||||
t.Run("pin ls with multiple CIDs returns names", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Create test content
|
||||
cidA := node.IPFSAddStr("multi A", "--pin=false")
|
||||
cidB := node.IPFSAddStr("multi B", "--pin=false")
|
||||
|
||||
// Pin with names
|
||||
node.IPFS("pin", "add", "--name=multi-pin-a", cidA)
|
||||
node.IPFS("pin", "add", "--name=multi-pin-b", cidB)
|
||||
|
||||
// Test multiple CIDs at once
|
||||
res := node.IPFS("pin", "ls", cidA, cidB, "--names")
|
||||
output := res.Stdout.String()
|
||||
assertPinOutput(t, output, cidA, "multi-pin-a")
|
||||
assertPinOutput(t, output, cidB, "multi-pin-b")
|
||||
})
|
||||
|
||||
t.Run("pin ls without CID lists all pins with names", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Create and pin content with names
|
||||
cidA := node.IPFSAddStr("list all A", "--pin=false")
|
||||
cidB := node.IPFSAddStr("list all B", "--pin=false")
|
||||
cidC := node.IPFSAddStr("list all C", "--pin=false")
|
||||
|
||||
node.IPFS("pin", "add", "--name=all-pin-a", cidA)
|
||||
node.IPFS("pin", "add", "--name=all-pin-b", "--recursive=false", cidB)
|
||||
node.IPFS("pin", "add", cidC) // No name
|
||||
|
||||
// Test: pin ls --names (without CID) should list all pins with their names
|
||||
res := node.IPFS("pin", "ls", "--names")
|
||||
output := res.Stdout.String()
|
||||
|
||||
// Should contain all pins with their names
|
||||
assertPinOutput(t, output, cidA, "all-pin-a")
|
||||
assertPinOutput(t, output, cidB, "all-pin-b")
|
||||
assertCIDOnly(t, output, cidC)
|
||||
|
||||
// Pin C should appear but without a name (just type)
|
||||
lines := strings.Split(output, "\n")
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, cidC) {
|
||||
// Should have CID and type but no name
|
||||
require.Contains(t, line, "recursive", "pin type 'recursive' not found for unnamed pin %s in line: %s", cidC, line)
|
||||
require.NotContains(t, line, "all-pin", "pin name should not be present for unnamed pin %s, but found in line: %s", cidC, line)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("pin ls --type with --names", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Create test content
|
||||
cidDirect := node.IPFSAddStr("direct content", "--pin=false")
|
||||
cidRecursive := node.IPFSAddStr("recursive content", "--pin=false")
|
||||
|
||||
// Create a DAG for indirect testing
|
||||
childCid := node.IPFSAddStr("child for indirect", "--pin=false")
|
||||
parentContent := fmt.Sprintf(`{"link": "/ipfs/%s"}`, childCid)
|
||||
parentCid := node.PipeStrToIPFS(parentContent, "dag", "put", "--input-codec=json", "--store-codec=dag-cbor").Stdout.Trimmed()
|
||||
|
||||
// Pin with different types and names
|
||||
node.IPFS("pin", "add", "--name=direct-pin", "--recursive=false", cidDirect)
|
||||
node.IPFS("pin", "add", "--name=recursive-pin", cidRecursive)
|
||||
node.IPFS("pin", "add", "--name=parent-pin", parentCid)
|
||||
|
||||
// Test: --type=direct --names
|
||||
res := node.IPFS("pin", "ls", "--type=direct", "--names")
|
||||
output := res.Stdout.String()
|
||||
assertPinOutput(t, output, cidDirect, "direct-pin")
|
||||
assertNotPresent(t, output, cidRecursive, "recursive-pin")
|
||||
|
||||
// Test: --type=recursive --names
|
||||
res = node.IPFS("pin", "ls", "--type=recursive", "--names")
|
||||
output = res.Stdout.String()
|
||||
assertPinOutput(t, output, cidRecursive, "recursive-pin")
|
||||
assertPinOutput(t, output, parentCid, "parent-pin")
|
||||
assertNotPresent(t, output, cidDirect, "direct-pin")
|
||||
|
||||
// Test: --type=indirect with proper directory structure
|
||||
// Create a directory with a file for indirect pin testing
|
||||
dirPath := t.TempDir()
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dirPath, "file.txt"), []byte("test content"), 0644))
|
||||
|
||||
// Add directory recursively
|
||||
dirAddRes := node.IPFS("add", "-r", "-q", dirPath)
|
||||
dirCidStr := strings.TrimSpace(dirAddRes.Stdout.Lines()[len(dirAddRes.Stdout.Lines())-1])
|
||||
|
||||
// Add file separately without pinning to get its CID
|
||||
fileAddRes := node.IPFS("add", "-q", "--pin=false", filepath.Join(dirPath, "file.txt"))
|
||||
fileCidStr := strings.TrimSpace(fileAddRes.Stdout.String())
|
||||
|
||||
// Check if file shows as indirect
|
||||
res = node.IPFS("pin", "ls", "--type=indirect", fileCidStr)
|
||||
output = res.Stdout.String()
|
||||
require.Contains(t, output, fileCidStr, "indirect pin CID %s not found in output: %s", fileCidStr, output)
|
||||
require.Contains(t, output, "indirect through "+dirCidStr, "indirect relationship not found for CID %s through %s in output: %s", fileCidStr, dirCidStr, output)
|
||||
|
||||
// Test: --type=all --names
|
||||
res = node.IPFS("pin", "ls", "--type=all", "--names")
|
||||
output = res.Stdout.String()
|
||||
assertPinOutput(t, output, cidDirect, "direct-pin")
|
||||
assertPinOutput(t, output, cidRecursive, "recursive-pin")
|
||||
assertPinOutput(t, output, parentCid, "parent-pin")
|
||||
// Indirect pins are included in --type=all output
|
||||
})
|
||||
|
||||
t.Run("pin ls JSON output with names", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Add and pin content with name
|
||||
cidA := node.IPFSAddStr("json content", "--pin=false")
|
||||
node.IPFS("pin", "add", "--name=json-pin", cidA)
|
||||
|
||||
// Test JSON output with specific CID
|
||||
res := node.IPFS("pin", "ls", cidA, "--names", "--enc=json")
|
||||
var pinOutput pinLsJSON
|
||||
err := json.Unmarshal([]byte(res.Stdout.String()), &pinOutput)
|
||||
require.NoError(t, err, "failed to unmarshal JSON output: %s", res.Stdout.String())
|
||||
|
||||
pinData, ok := pinOutput.Keys[cidA]
|
||||
require.True(t, ok, "CID %s should be in Keys map, got: %+v", cidA, pinOutput.Keys)
|
||||
require.Equal(t, "recursive", pinData.Type, "expected pin type 'recursive', got '%s'", pinData.Type)
|
||||
require.Equal(t, "json-pin", pinData.Name, "expected pin name 'json-pin', got '%s'", pinData.Name)
|
||||
|
||||
// Without names flag
|
||||
res = node.IPFS("pin", "ls", cidA, "--enc=json")
|
||||
err = json.Unmarshal([]byte(res.Stdout.String()), &pinOutput)
|
||||
require.NoError(t, err, "failed to unmarshal JSON output: %s", res.Stdout.String())
|
||||
|
||||
pinData, ok = pinOutput.Keys[cidA]
|
||||
require.True(t, ok, "CID %s should be in Keys map, got: %+v", cidA, pinOutput.Keys)
|
||||
// Name should be empty without --names flag
|
||||
require.Equal(t, "", pinData.Name, "pin name should be empty without --names flag, got '%s'", pinData.Name)
|
||||
|
||||
// Test JSON output without CID (list all)
|
||||
res = node.IPFS("pin", "ls", "--names", "--enc=json")
|
||||
var listOutput pinLsJSON
|
||||
err = json.Unmarshal([]byte(res.Stdout.String()), &listOutput)
|
||||
require.NoError(t, err, "failed to unmarshal JSON list output: %s", res.Stdout.String())
|
||||
// Should have at least one pin (the one we just added)
|
||||
require.NotEmpty(t, listOutput.Keys, "pin list should not be empty")
|
||||
// Check that our pin is in the list
|
||||
pinData, ok = listOutput.Keys[cidA]
|
||||
require.True(t, ok, "our pin with CID %s should be in the list, got: %+v", cidA, listOutput.Keys)
|
||||
require.Equal(t, "json-pin", pinData.Name, "expected pin name 'json-pin' in list, got '%s'", pinData.Name)
|
||||
})
|
||||
|
||||
t.Run("direct and indirect pins with names", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Create a small DAG: parent -> child
|
||||
childCid := node.IPFSAddStr("child content", "--pin=false")
|
||||
|
||||
// Create parent that references child
|
||||
parentContent := fmt.Sprintf(`{"link": "/ipfs/%s"}`, childCid)
|
||||
parentCid := node.PipeStrToIPFS(parentContent, "dag", "put", "--input-codec=json", "--store-codec=dag-cbor").Stdout.Trimmed()
|
||||
|
||||
// Pin child directly with a name
|
||||
node.IPFS("pin", "add", "--name=direct-child", "--recursive=false", childCid)
|
||||
|
||||
// Pin parent recursively with a name
|
||||
node.IPFS("pin", "add", "--name=recursive-parent", parentCid)
|
||||
|
||||
// Check direct pin with specific CID
|
||||
res := node.IPFS("pin", "ls", "--type=direct", childCid, "--names")
|
||||
output := res.Stdout.String()
|
||||
require.Contains(t, output, "direct-child", "pin name 'direct-child' not found in output: %s", output)
|
||||
require.Contains(t, output, "direct", "pin type 'direct' not found in output: %s", output)
|
||||
|
||||
// Check recursive pin with specific CID
|
||||
res = node.IPFS("pin", "ls", "--type=recursive", parentCid, "--names")
|
||||
output = res.Stdout.String()
|
||||
require.Contains(t, output, "recursive-parent", "pin name 'recursive-parent' not found in output: %s", output)
|
||||
require.Contains(t, output, "recursive", "pin type 'recursive' not found in output: %s", output)
|
||||
|
||||
// Child is both directly pinned and indirectly pinned through parent
|
||||
// Both relationships are valid and can be checked
|
||||
})
|
||||
|
||||
t.Run("pin update preserves name", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Create two pieces of content
|
||||
cidOld := node.IPFSAddStr("old content", "--pin=false")
|
||||
cidNew := node.IPFSAddStr("new content", "--pin=false")
|
||||
|
||||
// Pin with name
|
||||
node.IPFS("pin", "add", "--name=my-pin", cidOld)
|
||||
|
||||
// Update pin
|
||||
node.IPFS("pin", "update", cidOld, cidNew)
|
||||
|
||||
// Check that new pin has the same name
|
||||
res := node.IPFS("pin", "ls", cidNew, "--names")
|
||||
require.Contains(t, res.Stdout.String(), "my-pin", "pin name 'my-pin' not preserved after update, output: %s", res.Stdout.String())
|
||||
|
||||
// Old pin should not exist
|
||||
res = node.RunIPFS("pin", "ls", cidOld)
|
||||
require.Equal(t, 1, res.ExitCode(), "expected exit code 1 for unpinned CID, got %d", res.ExitCode())
|
||||
require.Contains(t, res.Stderr.String(), "is not pinned", "expected 'is not pinned' error for old CID %s, got: %s", cidOld, res.Stderr.String())
|
||||
})
|
||||
|
||||
t.Run("pin ls with invalid CID returns error", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := harness.NewT(t).NewNode().Init()
|
||||
|
||||
res := node.RunIPFS("pin", "ls", "invalid-cid")
|
||||
require.Equal(t, 1, res.ExitCode(), "expected exit code 1 for invalid CID, got %d", res.ExitCode())
|
||||
require.Contains(t, res.Stderr.String(), "invalid", "expected 'invalid' in error message, got: %s", res.Stderr.String())
|
||||
})
|
||||
|
||||
t.Run("pin ls with unpinned CID returns error", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Add content without pinning
|
||||
cid := node.IPFSAddStr("unpinned content", "--pin=false")
|
||||
|
||||
res := node.RunIPFS("pin", "ls", cid)
|
||||
require.Equal(t, 1, res.ExitCode(), "expected exit code 1 for unpinned CID, got %d", res.ExitCode())
|
||||
require.Contains(t, res.Stderr.String(), "is not pinned", "expected 'is not pinned' error for CID %s, got: %s", cid, res.Stderr.String())
|
||||
})
|
||||
|
||||
t.Run("pin with special characters in name", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
pinName string
|
||||
}{
|
||||
{"unicode", "test-📌-pin"},
|
||||
{"spaces", "test pin name"},
|
||||
{"special chars", "test!@#$%"},
|
||||
{"path-like", "test/pin/name"},
|
||||
{"dots", "test.pin.name"},
|
||||
{"long name", strings.Repeat("a", 255)},
|
||||
{"empty name", ""},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cid := node.IPFSAddStr("content for "+tc.name, "--pin=false")
|
||||
node.IPFS("pin", "add", "--name="+tc.pinName, cid)
|
||||
|
||||
res := node.IPFS("pin", "ls", cid, "--names")
|
||||
if tc.pinName != "" {
|
||||
require.Contains(t, res.Stdout.String(), tc.pinName,
|
||||
"pin name '%s' not found in output for test case '%s'", tc.pinName, tc.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("concurrent pin operations with names", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Create multiple goroutines adding pins with names
|
||||
numPins := 10
|
||||
done := make(chan struct{}, numPins)
|
||||
|
||||
for i := 0; i < numPins; i++ {
|
||||
go func(idx int) {
|
||||
defer func() { done <- struct{}{} }()
|
||||
|
||||
content := fmt.Sprintf("concurrent content %d", idx)
|
||||
cid := node.IPFSAddStr(content, "--pin=false")
|
||||
pinName := fmt.Sprintf("concurrent-pin-%d", idx)
|
||||
node.IPFS("pin", "add", "--name="+pinName, cid)
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Wait for all goroutines
|
||||
for i := 0; i < numPins; i++ {
|
||||
<-done
|
||||
}
|
||||
|
||||
// Verify all pins have correct names
|
||||
res := node.IPFS("pin", "ls", "--names")
|
||||
output := res.Stdout.String()
|
||||
for i := 0; i < numPins; i++ {
|
||||
pinName := fmt.Sprintf("concurrent-pin-%d", i)
|
||||
require.Contains(t, output, pinName,
|
||||
"concurrent pin name '%s' not found in output", pinName)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("pin rm removes name association", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Add and pin with name
|
||||
cid := node.IPFSAddStr("content to remove", "--pin=false")
|
||||
node.IPFS("pin", "add", "--name=to-be-removed", cid)
|
||||
|
||||
// Verify pin exists with name
|
||||
res := node.IPFS("pin", "ls", cid, "--names")
|
||||
require.Contains(t, res.Stdout.String(), "to-be-removed")
|
||||
|
||||
// Remove pin
|
||||
node.IPFS("pin", "rm", cid)
|
||||
|
||||
// Verify pin and name are gone
|
||||
res = node.RunIPFS("pin", "ls", cid)
|
||||
require.Equal(t, 1, res.ExitCode())
|
||||
require.Contains(t, res.Stderr.String(), "is not pinned")
|
||||
})
|
||||
|
||||
t.Run("garbage collection preserves named pins", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Add content with and without pin names
|
||||
cidNamed := node.IPFSAddStr("named content", "--pin=false")
|
||||
cidUnnamed := node.IPFSAddStr("unnamed content", "--pin=false")
|
||||
cidUnpinned := node.IPFSAddStr("unpinned content", "--pin=false")
|
||||
|
||||
node.IPFS("pin", "add", "--name=important-data", cidNamed)
|
||||
node.IPFS("pin", "add", cidUnnamed)
|
||||
|
||||
// Run garbage collection
|
||||
node.IPFS("repo", "gc")
|
||||
|
||||
// Named and unnamed pins should still exist
|
||||
res := node.IPFS("pin", "ls", cidNamed, "--names")
|
||||
require.Contains(t, res.Stdout.String(), "important-data")
|
||||
|
||||
res = node.IPFS("pin", "ls", cidUnnamed)
|
||||
require.Contains(t, res.Stdout.String(), cidUnnamed)
|
||||
|
||||
// Unpinned content should be gone (cat should fail)
|
||||
res = node.RunIPFS("cat", cidUnpinned)
|
||||
require.NotEqual(t, 0, res.ExitCode(), "unpinned content should be garbage collected")
|
||||
})
|
||||
|
||||
t.Run("pin add with same name can be used for multiple pins", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
|
||||
// Add two different pieces of content
|
||||
cid1 := node.IPFSAddStr("first content", "--pin=false")
|
||||
cid2 := node.IPFSAddStr("second content", "--pin=false")
|
||||
|
||||
// Pin both with the same name - this is allowed
|
||||
node.IPFS("pin", "add", "--name=shared-name", cid1)
|
||||
node.IPFS("pin", "add", "--name=shared-name", cid2)
|
||||
|
||||
// List all pins with names
|
||||
res := node.IPFS("pin", "ls", "--names")
|
||||
output := res.Stdout.String()
|
||||
|
||||
// Both CIDs should be pinned
|
||||
require.Contains(t, output, cid1)
|
||||
require.Contains(t, output, cid2)
|
||||
|
||||
// Both pins can have the same name
|
||||
lines := strings.Split(output, "\n")
|
||||
foundCid1WithName := false
|
||||
foundCid2WithName := false
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, cid1) && strings.Contains(line, "shared-name") {
|
||||
foundCid1WithName = true
|
||||
}
|
||||
if strings.Contains(line, cid2) && strings.Contains(line, "shared-name") {
|
||||
foundCid2WithName = true
|
||||
}
|
||||
}
|
||||
require.True(t, foundCid1WithName, "first pin should have the name")
|
||||
require.True(t, foundCid2WithName, "second pin should have the name")
|
||||
})
|
||||
|
||||
t.Run("pin names persist across daemon restarts", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := harness.NewT(t).NewNode().Init()
|
||||
node.StartDaemon("--offline")
|
||||
|
||||
// Add content with pin name
|
||||
cid := node.IPFSAddStr("persistent content")
|
||||
node.IPFS("pin", "add", "--name=persistent-pin", cid)
|
||||
|
||||
// Restart daemon
|
||||
node.StopDaemon()
|
||||
node.StartDaemon("--offline")
|
||||
|
||||
// Check pin name persisted
|
||||
res := node.IPFS("pin", "ls", cid, "--names")
|
||||
require.Contains(t, res.Stdout.String(), "persistent-pin",
|
||||
"pin name should persist across daemon restarts")
|
||||
|
||||
node.StopDaemon()
|
||||
})
|
||||
}
|
||||
|
||||
// TestPinLsEdgeCases tests edge cases for pin ls command
|
||||
func TestPinLsEdgeCases(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("invalid pin type returns error", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
defer node.StopDaemon()
|
||||
|
||||
// Try to list pins with invalid type
|
||||
res := node.RunIPFS("pin", "ls", "--type=invalid")
|
||||
require.NotEqual(t, 0, res.ExitCode())
|
||||
require.Contains(t, res.Stderr.String(), "invalid type 'invalid'")
|
||||
require.Contains(t, res.Stderr.String(), "must be one of {direct, indirect, recursive, all}")
|
||||
})
|
||||
|
||||
t.Run("non-existent path returns proper error", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
defer node.StopDaemon()
|
||||
|
||||
// Try to list a non-existent CID
|
||||
fakeCID := "QmNonExistent123456789"
|
||||
res := node.RunIPFS("pin", "ls", fakeCID)
|
||||
require.NotEqual(t, 0, res.ExitCode())
|
||||
})
|
||||
|
||||
t.Run("unpinned CID returns not pinned error", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := setupTestNode(t)
|
||||
defer node.StopDaemon()
|
||||
|
||||
// Add content but don't pin it explicitly (it's just in blockstore)
|
||||
unpinnedCID := node.IPFSAddStr("unpinned content", "--pin=false")
|
||||
|
||||
// Try to list specific unpinned CID
|
||||
res := node.RunIPFS("pin", "ls", unpinnedCID)
|
||||
require.NotEqual(t, 0, res.ExitCode())
|
||||
require.Contains(t, res.Stderr.String(), "is not pinned")
|
||||
})
|
||||
}
|
||||
@ -135,18 +135,18 @@ require (
|
||||
github.com/huin/goupnp v1.3.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/ipfs/bbloom v0.0.4 // indirect
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3 // indirect
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f // indirect
|
||||
github.com/ipfs/go-bitfield v1.1.0 // indirect
|
||||
github.com/ipfs/go-block-format v0.2.2 // indirect
|
||||
github.com/ipfs/go-block-format v0.2.3 // indirect
|
||||
github.com/ipfs/go-cid v0.5.0 // indirect
|
||||
github.com/ipfs/go-datastore v0.8.4 // indirect
|
||||
github.com/ipfs/go-datastore v0.9.0 // indirect
|
||||
github.com/ipfs/go-dsqueue v0.0.5 // indirect
|
||||
github.com/ipfs/go-ipfs-redirects-file v0.1.2 // indirect
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1 // indirect
|
||||
github.com/ipfs/go-ipld-format v0.6.2 // indirect
|
||||
github.com/ipfs/go-ipld-format v0.6.3 // indirect
|
||||
github.com/ipfs/go-ipld-legacy v0.2.2 // indirect
|
||||
github.com/ipfs/go-metrics-interface v0.3.0 // indirect
|
||||
github.com/ipfs/go-unixfsnode v1.10.1 // indirect
|
||||
github.com/ipfs/go-unixfsnode v1.10.2 // indirect
|
||||
github.com/ipfs/kubo v0.31.0 // indirect
|
||||
github.com/ipld/go-car/v2 v2.15.0 // indirect
|
||||
github.com/ipld/go-codec-dagpb v1.7.0 // indirect
|
||||
@ -327,17 +327,17 @@ require (
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.uber.org/zap/exp v0.3.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect
|
||||
golang.org/x/crypto v0.42.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect
|
||||
golang.org/x/mod v0.27.0 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/mod v0.28.0 // indirect
|
||||
golang.org/x/net v0.44.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/term v0.35.0 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
golang.org/x/tools v0.37.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
gonum.org/v1/gonum v0.16.0 // indirect
|
||||
google.golang.org/protobuf v1.36.9 // indirect
|
||||
|
||||
@ -332,18 +332,18 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3 h1:qp8w52Rf5eEOrNFZ1VdLSOU3kA5N2EGMNv0xZAACSfs=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250918150710-6fe835c011c3/go.mod h1:YbQ2GM5GolkfJ8qB29RL+cXgFEa/HsDrHeHSB+fOrlY=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f h1:In4WBnF9sysZwHV6bYTdnLtyRMOQTtvW1leZzxP4bbg=
|
||||
github.com/ipfs/boxo v0.34.1-0.20250919000230-031df82b284f/go.mod h1:uhaF0DGnbgEiXDTmD249jCGbxVkMm6+Ew85q6Uub7lo=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-block-format v0.2.2 h1:uecCTgRwDIXyZPgYspaLXoMiMmxQpSx2aq34eNc4YvQ=
|
||||
github.com/ipfs/go-block-format v0.2.2/go.mod h1:vmuefuWU6b+9kIU0vZJgpiJt1yicQz9baHXE8qR+KB8=
|
||||
github.com/ipfs/go-block-format v0.2.3 h1:mpCuDaNXJ4wrBJLrtEaGFGXkferrw5eqVvzaHhtFKQk=
|
||||
github.com/ipfs/go-block-format v0.2.3/go.mod h1:WJaQmPAKhD3LspLixqlqNFxiZ3BZ3xgqxxoSR/76pnA=
|
||||
github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg=
|
||||
github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk=
|
||||
github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q=
|
||||
github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA=
|
||||
github.com/ipfs/go-datastore v0.8.4 h1:vXEsd76T3KIOSKXizjhmS3ICGMl+oOSjpLSxE3v8/Wc=
|
||||
github.com/ipfs/go-datastore v0.8.4/go.mod h1:uT77w/XEGrvJWwHgdrMr8bqCN6ZTW9gzmi+3uK+ouHg=
|
||||
github.com/ipfs/go-datastore v0.9.0 h1:WocriPOayqalEsueHv6SdD4nPVl4rYMfYGLD4bqCZ+w=
|
||||
github.com/ipfs/go-datastore v0.9.0/go.mod h1:uT77w/XEGrvJWwHgdrMr8bqCN6ZTW9gzmi+3uK+ouHg=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-dsqueue v0.0.5 h1:TUOk15TlCJ/NKV8Yk2W5wgkEjDa44Nem7a7FGIjsMNU=
|
||||
@ -360,8 +360,8 @@ github.com/ipfs/go-ipfs-redirects-file v0.1.2 h1:QCK7VtL91FH17KROVVy5KrzDx2hu68Q
|
||||
github.com/ipfs/go-ipfs-redirects-file v0.1.2/go.mod h1:yIiTlLcDEM/8lS6T3FlCEXZktPPqSOyuY6dEzVqw7Fw=
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1 h1:H05yEJbK/hxg0uf2AJhyerBDbjOuHX4yi+1U/ogRa7E=
|
||||
github.com/ipfs/go-ipld-cbor v0.2.1/go.mod h1:x9Zbeq8CoE5R2WicYgBMcr/9mnkQ0lHddYWJP2sMV3A=
|
||||
github.com/ipfs/go-ipld-format v0.6.2 h1:bPZQ+A05ol0b3lsJSl0bLvwbuQ+HQbSsdGTy4xtYUkU=
|
||||
github.com/ipfs/go-ipld-format v0.6.2/go.mod h1:nni2xFdHKx5lxvXJ6brt/pndtGxKAE+FPR1rg4jTkyk=
|
||||
github.com/ipfs/go-ipld-format v0.6.3 h1:9/lurLDTotJpZSuL++gh3sTdmcFhVkCwsgx2+rAh4j8=
|
||||
github.com/ipfs/go-ipld-format v0.6.3/go.mod h1:74ilVN12NXVMIV+SrBAyC05UJRk0jVvGqdmrcYZvCBk=
|
||||
github.com/ipfs/go-ipld-legacy v0.2.2 h1:DThbqCPVLpWBcGtU23KDLiY2YRZZnTkXQyfz8aOfBkQ=
|
||||
github.com/ipfs/go-ipld-legacy v0.2.2/go.mod h1:hhkj+b3kG9b2BcUNw8IFYAsfeNo8E3U7eYlWeAOPyDU=
|
||||
github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8=
|
||||
@ -374,8 +374,8 @@ github.com/ipfs/go-peertaskqueue v0.8.2 h1:PaHFRaVFdxQk1Qo3OKiHPYjmmusQy7gKQUaL8
|
||||
github.com/ipfs/go-peertaskqueue v0.8.2/go.mod h1:L6QPvou0346c2qPJNiJa6BvOibxDfaiPlqHInmzg0FA=
|
||||
github.com/ipfs/go-test v0.2.3 h1:Z/jXNAReQFtCYyn7bsv/ZqUwS6E7iIcSpJ2CuzCvnrc=
|
||||
github.com/ipfs/go-test v0.2.3/go.mod h1:QW8vSKkwYvWFwIZQLGQXdkt9Ud76eQXRQ9Ao2H+cA1o=
|
||||
github.com/ipfs/go-unixfsnode v1.10.1 h1:hGKhzuH6NSzZ4y621wGuDspkjXRNG3B+HqhlyTjSwSM=
|
||||
github.com/ipfs/go-unixfsnode v1.10.1/go.mod h1:eguv/otvacjmfSbYvmamc9ssNAzLvRk0+YN30EYeOOY=
|
||||
github.com/ipfs/go-unixfsnode v1.10.2 h1:TREegX1J4X+k1w4AhoDuxxFvVcS9SegMRvrmxF6Tca8=
|
||||
github.com/ipfs/go-unixfsnode v1.10.2/go.mod h1:ImDPTSiKZ+2h4UVdkSDITJHk87bUAp7kX/lgifjRicg=
|
||||
github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko=
|
||||
github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM=
|
||||
github.com/ipfs/iptb v1.4.1 h1:faXd3TKGPswbHyZecqqg6UfbES7RDjTKQb+6VFPKDUo=
|
||||
@ -913,11 +913,11 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU=
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac h1:TSSpLIG4v+p0rPv1pNOQtl1I8knsO4S9trOxNMOLVP4=
|
||||
@ -938,8 +938,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
|
||||
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -967,8 +967,8 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -1020,6 +1020,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8=
|
||||
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
@ -1031,8 +1033,8 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
|
||||
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
@ -1046,8 +1048,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
@ -1078,8 +1080,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||
golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
|
||||
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
|
||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
|
||||
|
||||
Loading…
Reference in New Issue
Block a user