From 5bac37c7351a5b70474ef2a5e426669bff86cfae Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 6 Oct 2023 16:04:23 +0200 Subject: [PATCH] feat(path)!: consolidated path libraries (#334) This commit was moved from ipfs/boxo@85c180e26664367f79de453c592020b4f279669f --- core/coreiface/block.go | 5 +- core/coreiface/coreapi.go | 9 +- core/coreiface/dht.go | 2 +- core/coreiface/key.go | 2 +- core/coreiface/name.go | 5 +- core/coreiface/object.go | 17 ++- core/coreiface/path/path.go | 199 -------------------------------- core/coreiface/pin.go | 6 +- core/coreiface/tests/block.go | 37 +++--- core/coreiface/tests/dag.go | 15 +-- core/coreiface/tests/name.go | 21 ++-- core/coreiface/tests/object.go | 14 +-- core/coreiface/tests/path.go | 191 ++++++++++++------------------ core/coreiface/tests/pin.go | 89 +++++++------- core/coreiface/tests/routing.go | 2 +- core/coreiface/tests/unixfs.go | 28 ++--- core/coreiface/unixfs.go | 11 +- 17 files changed, 206 insertions(+), 447 deletions(-) delete mode 100644 core/coreiface/path/path.go diff --git a/core/coreiface/block.go b/core/coreiface/block.go index dbe31e9f8..cdd5fcee2 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -4,9 +4,8 @@ import ( "context" "io" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/path" ) // BlockStat contains information about a block @@ -15,7 +14,7 @@ type BlockStat interface { Size() int // Path returns path to the block - Path() path.Resolved + Path() path.ImmutablePath } // BlockAPI specifies the interface to the block layer diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index 7276a3f60..25e54a37b 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -5,9 +5,8 @@ package iface import ( "context" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/path" ipld "github.com/ipfs/go-ipld-format" ) @@ -47,8 +46,10 @@ type CoreAPI interface { // Routing returns an implementation of Routing API Routing() RoutingAPI - // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, path.Path) (path.Resolved, error) + // ResolvePath resolves the path using UnixFS resolver, and returns the resolved + // immutable path, and the remainder of the path segments that cannot be resolved + // within UnixFS. + ResolvePath(context.Context, path.Path) (path.ImmutablePath, []string, error) // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index 93027a406..d9418ebfc 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -3,7 +3,7 @@ package iface import ( "context" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/coreiface/options" diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 118fe2e4f..4a1cbae80 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -3,7 +3,7 @@ package iface import ( "context" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/coreiface/options" diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 8c3e8e89a..f832033ef 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -4,10 +4,9 @@ import ( "context" "errors" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/ipns" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" ) var ErrResolveFailed = errors.New("could not resolve name") diff --git a/core/coreiface/object.go b/core/coreiface/object.go index d983fa49b..4a73f22ea 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -4,9 +4,8 @@ import ( "context" "io" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -60,11 +59,11 @@ type ObjectChange struct { // Before holds the link path before the change. Note that when a link is // added, this will be nil. - Before path.Resolved + Before path.ImmutablePath // After holds the link path after the change. Note that when a link is // removed, this will be nil. - After path.Resolved + After path.ImmutablePath } // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities @@ -74,7 +73,7 @@ type ObjectAPI interface { New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.Resolved, error) + Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.ImmutablePath, error) // Get returns the node for the path Get(context.Context, path.Path) (ipld.Node, error) @@ -91,16 +90,16 @@ type ObjectAPI interface { // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). - AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.Resolved, error) + AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.ImmutablePath, error) // RmLink removes a link from the node - RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error) + RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) // AppendData appends data to the node - AppendData(context.Context, path.Path, io.Reader) (path.Resolved, error) + AppendData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error) // SetData sets the data contained in the node - SetData(context.Context, path.Path, io.Reader) (path.Resolved, error) + SetData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error) // Diff returns a set of changes needed to transform the first object into the // second. diff --git a/core/coreiface/path/path.go b/core/coreiface/path/path.go deleted file mode 100644 index c26b8692b..000000000 --- a/core/coreiface/path/path.go +++ /dev/null @@ -1,199 +0,0 @@ -package path - -import ( - "strings" - - ipfspath "github.com/ipfs/boxo/path" - cid "github.com/ipfs/go-cid" -) - -// Path is a generic wrapper for paths used in the API. A path can be resolved -// to a CID using one of Resolve functions in the API. -// -// Paths must be prefixed with a valid prefix: -// -// * /ipfs - Immutable unixfs path (files) -// * /ipld - Immutable ipld path (data) -// * /ipns - Mutable names. Usually resolves to one of the immutable paths -// TODO: /local (MFS) -type Path interface { - // String returns the path as a string. - String() string - - // Namespace returns the first component of the path. - // - // For example path "/ipfs/QmHash", calling Namespace() will return "ipfs" - // - // Calling this method on invalid paths (IsValid() != nil) will result in - // empty string - Namespace() string - - // Mutable returns false if the data pointed to by this path in guaranteed - // to not change. - // - // Note that resolved mutable path can be immutable. - Mutable() bool - - // IsValid checks if this path is a valid ipfs Path, returning nil iff it is - // valid - IsValid() error -} - -// Resolved is a path which was resolved to the last resolvable node. -// ResolvedPaths are guaranteed to return nil from `IsValid` -type Resolved interface { - // Cid returns the CID of the node referenced by the path. Remainder of the - // path is guaranteed to be within the node. - // - // Examples: - // If you have 3 linked objects: QmRoot -> A -> B: - // - // cidB := {"foo": {"bar": 42 }} - // cidA := {"B": {"/": cidB }} - // cidRoot := {"A": {"/": cidA }} - // - // And resolve paths: - // - // * "/ipfs/${cidRoot}" - // * Calling Cid() will return `cidRoot` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `` - // - // * "/ipfs/${cidRoot}/A" - // * Calling Cid() will return `cidA` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `` - // - // * "/ipfs/${cidRoot}/A/B/foo" - // * Calling Cid() will return `cidB` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `foo` - // - // * "/ipfs/${cidRoot}/A/B/foo/bar" - // * Calling Cid() will return `cidB` - // * Calling Root() will return `cidRoot` - // * Calling Remainder() will return `foo/bar` - Cid() cid.Cid - - // Root returns the CID of the root object of the path - // - // Example: - // If you have 3 linked objects: QmRoot -> A -> B, and resolve path - // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot - // - // For more examples see the documentation of Cid() method - Root() cid.Cid - - // Remainder returns unresolved part of the path - // - // Example: - // If you have 2 linked objects: QmRoot -> A, where A is a CBOR node - // containing the following data: - // - // {"foo": {"bar": 42 }} - // - // When resolving "/ipld/QmRoot/A/foo/bar", Remainder will return "foo/bar" - // - // For more examples see the documentation of Cid() method - Remainder() string - - Path -} - -// path implements coreiface.Path -type path struct { - path string -} - -// resolvedPath implements coreiface.resolvedPath -type resolvedPath struct { - path - cid cid.Cid - root cid.Cid - remainder string -} - -// Join appends provided segments to the base path -func Join(base Path, a ...string) Path { - s := strings.Join(append([]string{base.String()}, a...), "/") - return &path{path: s} -} - -// IpfsPath creates new /ipfs path from the provided CID -func IpfsPath(c cid.Cid) Resolved { - return &resolvedPath{ - path: path{"/ipfs/" + c.String()}, - cid: c, - root: c, - remainder: "", - } -} - -// IpldPath creates new /ipld path from the provided CID -func IpldPath(c cid.Cid) Resolved { - return &resolvedPath{ - path: path{"/ipld/" + c.String()}, - cid: c, - root: c, - remainder: "", - } -} - -// New parses string path to a Path -func New(p string) Path { - if pp, err := ipfspath.ParsePath(p); err == nil { - p = pp.String() - } - - return &path{path: p} -} - -// NewResolvedPath creates new Resolved path. This function performs no checks -// and is intended to be used by resolver implementations. Incorrect inputs may -// cause panics. Handle with care. -func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) Resolved { - return &resolvedPath{ - path: path{ipath.String()}, - cid: c, - root: root, - remainder: remainder, - } -} - -func (p *path) String() string { - return p.path -} - -func (p *path) Namespace() string { - ip, err := ipfspath.ParsePath(p.path) - if err != nil { - return "" - } - - if len(ip.Segments()) < 1 { - panic("path without namespace") // this shouldn't happen under any scenario - } - return ip.Segments()[0] -} - -func (p *path) Mutable() bool { - // TODO: MFS: check for /local - return p.Namespace() == "ipns" -} - -func (p *path) IsValid() error { - _, err := ipfspath.ParsePath(p.path) - return err -} - -func (p *resolvedPath) Cid() cid.Cid { - return p.cid -} - -func (p *resolvedPath) Root() cid.Cid { - return p.root -} - -func (p *resolvedPath) Remainder() string { - return p.remainder -} diff --git a/core/coreiface/pin.go b/core/coreiface/pin.go index 6b97c6ca5..057516d08 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -3,7 +3,7 @@ package iface import ( "context" - path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/coreiface/options" ) @@ -11,7 +11,7 @@ import ( // Pin holds information about pinned resource type Pin interface { // Path to the pinned object - Path() path.Resolved + Path() path.ImmutablePath // Type of the pin Type() string @@ -35,7 +35,7 @@ type PinStatus interface { // BadPinNode is a node that has been marked as bad by Pin.Verify type BadPinNode interface { // Path is the path of the node - Path() path.Resolved + Path() path.ImmutablePath // Err is the reason why the node has been marked as bad Err() error diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 5dcb16e4f..6e254063e 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -9,9 +9,8 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" opt "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" ipld "github.com/ipfs/go-ipld-format" - mh "github.com/multiformats/go-multihash" ) @@ -68,8 +67,8 @@ func (tp *TestSuite) TestBlockPut(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != rawCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != rawCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -88,8 +87,8 @@ func (tp *TestSuite) TestBlockPutFormatDagCbor(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != cborCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != cborCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -108,8 +107,8 @@ func (tp *TestSuite) TestBlockPutFormatDagPb(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != pbCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != pbCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -128,8 +127,8 @@ func (tp *TestSuite) TestBlockPutFormatV0(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != pbCidV0 { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != pbCidV0 { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -146,8 +145,8 @@ func (tp *TestSuite) TestBlockPutCidCodecDagCbor(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != cborCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != cborCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -164,8 +163,8 @@ func (tp *TestSuite) TestBlockPutCidCodecDagPb(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != pbCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != pbCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -187,8 +186,8 @@ func (tp *TestSuite) TestBlockPutHash(t *testing.T) { t.Fatal(err) } - if res.Path().Cid().String() != cborKCid { - t.Errorf("got wrong cid: %s", res.Path().Cid().String()) + if res.Path().RootCid().String() != cborKCid { + t.Errorf("got wrong cid: %s", res.Path().RootCid().String()) } } @@ -219,13 +218,13 @@ func (tp *TestSuite) TestBlockGet(t *testing.T) { t.Error("didn't get correct data back") } - p := path.New("/ipfs/" + res.Path().Cid().String()) + p := path.FromCid(res.Path().RootCid()) - rp, err := api.ResolvePath(ctx, p) + rp, _, err := api.ResolvePath(ctx, p) if err != nil { t.Fatal(err) } - if rp.Cid().String() != res.Path().Cid().String() { + if rp.RootCid().String() != res.Path().RootCid().String() { t.Error("paths didn't match") } } diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index b9a03c8f4..a106788d6 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -3,13 +3,11 @@ package tests import ( "context" "math" - gopath "path" "strings" "testing" - path "github.com/ipfs/boxo/coreiface/path" - coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/path" ipldcbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" @@ -113,14 +111,17 @@ func (tp *TestSuite) TestDagPath(t *testing.T) { t.Fatal(err) } - p := path.New(gopath.Join(nd.Cid().String(), "lnk")) - - rp, err := api.ResolvePath(ctx, p) + p, err := path.Join(path.FromCid(nd.Cid()), "lnk") if err != nil { t.Fatal(err) } - ndd, err := api.Dag().Get(ctx, rp.Cid()) + rp, _, err := api.ResolvePath(ctx, p) + if err != nil { + t.Fatal(err) + } + + ndd, err := api.Dag().Get(ctx, rp.RootCid()) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index 74d88edff..2b6b7ec49 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -4,15 +4,14 @@ import ( "context" "io" "math/rand" - gopath "path" "testing" "time" coreiface "github.com/ipfs/boxo/coreiface" opt "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" "github.com/stretchr/testify/require" ) @@ -35,10 +34,6 @@ func addTestObject(ctx context.Context, api coreiface.CoreAPI) (path.Path, error return api.Unixfs().Add(ctx, files.NewReaderFile(&io.LimitedReader{R: rnd, N: 4092})) } -func appendPath(p path.Path, sub string) path.Path { - return path.New(gopath.Join(p.String(), sub)) -} - func (tp *TestSuite) TestPublishResolve(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -68,7 +63,10 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { t.Run("publishPath", func(t *testing.T) { api, p := init() - name, err := api.Name().Publish(ctx, appendPath(p, "/test")) + p, err := path.Join(p, "/test") + require.NoError(t, err) + + name, err := api.Name().Publish(ctx, p) require.NoError(t, err) self, err := api.Key().Self(ctx) @@ -77,7 +75,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { resPath, err := api.Name().Resolve(ctx, name.String(), ropts...) require.NoError(t, err) - require.Equal(t, p.String()+"/test", resPath.String()) + require.Equal(t, p.String(), resPath.String()) }) t.Run("revolvePath", func(t *testing.T) { @@ -96,7 +94,10 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { t.Run("publishRevolvePath", func(t *testing.T) { api, p := init() - name, err := api.Name().Publish(ctx, appendPath(p, "/a")) + p, err := path.Join(p, "/a") + require.NoError(t, err) + + name, err := api.Name().Publish(ctx, p) require.NoError(t, err) self, err := api.Key().Self(ctx) @@ -105,7 +106,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) { resPath, err := api.Name().Resolve(ctx, name.String()+"/b", ropts...) require.NoError(t, err) - require.Equal(t, p.String()+"/a/b", resPath.String()) + require.Equal(t, p.String()+"/b", resPath.String()) }) } diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 63c218eb3..5c6ba828c 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -166,7 +166,7 @@ func (tp *TestSuite) TestObjectLinks(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`"}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`"}]}`)) if err != nil { t.Fatal(err) } @@ -180,7 +180,7 @@ func (tp *TestSuite) TestObjectLinks(t *testing.T) { t.Errorf("unexpected number of links: %d", len(links)) } - if links[0].Cid.String() != p1.Cid().String() { + if links[0].Cid.String() != p1.RootCid().String() { t.Fatal("cids didn't batch") } @@ -202,7 +202,7 @@ func (tp *TestSuite) TestObjectStat(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) if err != nil { t.Fatal(err) } @@ -212,7 +212,7 @@ func (tp *TestSuite) TestObjectStat(t *testing.T) { t.Fatal(err) } - if stat.Cid.String() != p2.Cid().String() { + if stat.Cid.String() != p2.RootCid().String() { t.Error("unexpected stat.Cid") } @@ -250,7 +250,7 @@ func (tp *TestSuite) TestObjectAddLink(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) if err != nil { t.Fatal(err) } @@ -291,7 +291,7 @@ func (tp *TestSuite) TestObjectAddLinkCreate(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) if err != nil { t.Fatal(err) } @@ -340,7 +340,7 @@ func (tp *TestSuite) TestObjectRmLink(t *testing.T) { t.Fatal(err) } - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`)) + p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index 06f3aa1f8..116aed2e7 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -2,17 +2,26 @@ package tests import ( "context" + "fmt" "math" "strings" "testing" - "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" - + "github.com/ipfs/boxo/path" + "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" + "github.com/stretchr/testify/require" ) +func newIPLDPath(t *testing.T, cid cid.Cid) path.ImmutablePath { + p, err := path.NewPath(fmt.Sprintf("/%s/%s", path.IPLDNamespace, cid.String())) + require.NoError(t, err) + im, err := path.NewImmutablePath(p) + require.NoError(t, err) + return im +} + func (tp *TestSuite) TestPath(t *testing.T) { t.Run("TestMutablePath", tp.TestMutablePath) t.Run("TestPathRemainder", tp.TestPathRemainder) @@ -25,173 +34,115 @@ func (tp *TestSuite) TestPath(t *testing.T) { func (tp *TestSuite) TestMutablePath(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) blk, err := api.Block().Put(ctx, strings.NewReader(`foo`)) - if err != nil { - t.Fatal(err) - } - - if blk.Path().Mutable() { - t.Error("expected /ipld path to be immutable") - } - - // get self /ipns path - - if api.Key() == nil { - t.Fatal(".Key not implemented") - } + require.NoError(t, err) + require.False(t, blk.Path().Mutable()) + require.NotNil(t, api.Key()) keys, err := api.Key().List(ctx) - if err != nil { - t.Fatal(err) - } - - if !keys[0].Path().Mutable() { - t.Error("expected self /ipns path to be mutable") - } + require.NoError(t, err) + require.True(t, keys[0].Path().Mutable()) } func (tp *TestSuite) TestPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - if api.Dag() == nil { - t.Fatal(".Dag not implemented") - } + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + require.NotNil(t, api.Dag()) nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if err := api.Dag().Add(ctx, nd); err != nil { - t.Fatal(err) - } + err = api.Dag().Add(ctx, nd) + require.NoError(t, err) - rp1, err := api.ResolvePath(ctx, path.New(nd.String()+"/foo/bar")) - if err != nil { - t.Fatal(err) - } + p, err := path.Join(path.FromCid(nd.Cid()), "foo", "bar") + require.NoError(t, err) - if rp1.Remainder() != "foo/bar" { - t.Error("expected to get path remainder") - } + _, remainder, err := api.ResolvePath(ctx, p) + require.NoError(t, err) + require.Equal(t, "/foo/bar", path.SegmentsToString(remainder...)) } func (tp *TestSuite) TestEmptyPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - if api.Dag() == nil { - t.Fatal(".Dag not implemented") - } + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + require.NotNil(t, api.Dag()) nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if err := api.Dag().Add(ctx, nd); err != nil { - t.Fatal(err) - } + err = api.Dag().Add(ctx, nd) + require.NoError(t, err) - rp1, err := api.ResolvePath(ctx, path.New(nd.Cid().String())) - if err != nil { - t.Fatal(err) - } - - if rp1.Remainder() != "" { - t.Error("expected the resolved path to not have a remainder") - } + _, remainder, err := api.ResolvePath(ctx, path.FromCid(nd.Cid())) + require.NoError(t, err) + require.Empty(t, remainder) } func (tp *TestSuite) TestInvalidPathRemainder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - if api.Dag() == nil { - t.Fatal(".Dag not implemented") - } + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + require.NotNil(t, api.Dag()) nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if err := api.Dag().Add(ctx, nd); err != nil { - t.Fatal(err) - } + err = api.Dag().Add(ctx, nd) + require.NoError(t, err) - _, err = api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/bar/baz")) - if err == nil || !strings.Contains(err.Error(), `no link named "bar"`) { - t.Fatalf("unexpected error: %s", err) - } + p, err := path.Join(newIPLDPath(t, nd.Cid()), "/bar/baz") + require.NoError(t, err) + + _, _, err = api.ResolvePath(ctx, p) + require.NotNil(t, err) + require.ErrorContains(t, err, `no link named "bar"`) } func (tp *TestSuite) TestPathRoot(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - if api.Block() == nil { - t.Fatal(".Block not implemented") - } + api, err := tp.makeAPI(t, ctx) + require.NoError(t, err) + require.NotNil(t, api.Block()) blk, err := api.Block().Put(ctx, strings.NewReader(`foo`), options.Block.Format("raw")) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.NotNil(t, api.Dag()) - if api.Dag() == nil { - t.Fatal(".Dag not implemented") - } + nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"/": "`+blk.Path().RootCid().String()+`"}}`), math.MaxUint64, -1) + require.NoError(t, err) - nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`), math.MaxUint64, -1) - if err != nil { - t.Fatal(err) - } + err = api.Dag().Add(ctx, nd) + require.NoError(t, err) - if err := api.Dag().Add(ctx, nd); err != nil { - t.Fatal(err) - } + p, err := path.Join(newIPLDPath(t, nd.Cid()), "/foo") + require.NoError(t, err) - rp, err := api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/foo")) - if err != nil { - t.Fatal(err) - } - - if rp.Root().String() != nd.Cid().String() { - t.Error("unexpected path root") - } - - if rp.Cid().String() != blk.Path().Cid().String() { - t.Error("unexpected path cid") - } + rp, _, err := api.ResolvePath(ctx, p) + require.NoError(t, err) + require.Equal(t, rp.RootCid().String(), blk.Path().RootCid().String()) } func (tp *TestSuite) TestPathJoin(t *testing.T) { - p1 := path.New("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") + p1, err := path.NewPath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") + require.NoError(t, err) - if path.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { - t.Error("unexpected path") - } + p2, err := path.Join(p1, "foo") + require.NoError(t, err) + + require.Equal(t, "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo", p2.String()) } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index 4b0fea01d..49499b36a 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -8,8 +8,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" opt "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" - + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" @@ -77,7 +76,7 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().Cid().String() != p.Cid().String() { + if list[0].Path().RootCid().String() != p.RootCid().String() { t.Error("paths don't match") } @@ -120,12 +119,12 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Fatal(err) } - nd2, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`), math.MaxUint64, -1) + nd2, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p0.RootCid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Fatal(err) } - nd3, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`), math.MaxUint64, -1) + nd3, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p1.RootCid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Fatal(err) } @@ -134,12 +133,12 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(nd2.Cid())) + err = api.Pin().Add(ctx, path.FromCid(nd2.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(nd3.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(nd3.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } @@ -162,8 +161,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != path.IpldPath(nd3.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd3.Cid()).String()) + if list[0].Path().String() != path.FromCid(nd3.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.FromCid(nd3.Cid()).String()) } list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Recursive())) @@ -175,8 +174,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != path.IpldPath(nd2.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd2.Cid()).String()) + if list[0].Path().String() != path.FromCid(nd2.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.FromCid(nd2.Cid()).String()) } list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Indirect())) @@ -188,8 +187,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().Cid().String() != p0.Cid().String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().Cid().String(), p0.Cid().String()) + if list[0].Path().RootCid().String() != p0.RootCid().String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().RootCid().String(), p0.RootCid().String()) } res, err := api.Pin().Verify(ctx) @@ -259,12 +258,12 @@ func (tp *TestSuite) TestPinLsIndirect(t *testing.T) { leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "foo") - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } @@ -293,12 +292,12 @@ func (tp *TestSuite) TestPinLsPredenceRecursiveIndirect(t *testing.T) { // Test recursive > indirect leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "recursive > indirect") - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid())) if err != nil { t.Fatal(err) } @@ -317,12 +316,12 @@ func (tp *TestSuite) TestPinLsPrecedenceDirectIndirect(t *testing.T) { // Test direct > indirect leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "direct > indirect") - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } @@ -341,24 +340,24 @@ func (tp *TestSuite) TestPinLsPrecedenceRecursiveDirect(t *testing.T) { // Test recursive > direct leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "recursive + direct = error") - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false)) if err == nil { t.Fatal("expected error directly pinning a recursively pinned node") } assertPinTypes(t, ctx, api, []cidContainer{parent}, []cidContainer{}, []cidContainer{leaf}) - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid())) + err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid())) if err != nil { t.Fatal(err) } @@ -376,40 +375,48 @@ func (tp *TestSuite) TestPinIsPinned(t *testing.T) { leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "foofoo") - assertNotPinned(t, ctx, api, path.IpldPath(grandparent.Cid())) - assertNotPinned(t, ctx, api, path.IpldPath(parent.Cid())) - assertNotPinned(t, ctx, api, path.IpldPath(leaf.Cid())) + assertNotPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid())) + assertNotPinned(t, ctx, api, newIPLDPath(t, parent.Cid())) + assertNotPinned(t, ctx, api, newIPLDPath(t, leaf.Cid())) - err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(true)) + err = api.Pin().Add(ctx, newIPLDPath(t, parent.Cid()), opt.Pin.Recursive(true)) if err != nil { t.Fatal(err) } - assertNotPinned(t, ctx, api, path.IpldPath(grandparent.Cid())) - assertIsPinned(t, ctx, api, path.IpldPath(parent.Cid()), "recursive") - assertIsPinned(t, ctx, api, path.IpldPath(leaf.Cid()), "indirect") + assertNotPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid())) + assertIsPinned(t, ctx, api, newIPLDPath(t, parent.Cid()), "recursive") + assertIsPinned(t, ctx, api, newIPLDPath(t, leaf.Cid()), "indirect") - err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, newIPLDPath(t, grandparent.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } - assertIsPinned(t, ctx, api, path.IpldPath(grandparent.Cid()), "direct") - assertIsPinned(t, ctx, api, path.IpldPath(parent.Cid()), "recursive") - assertIsPinned(t, ctx, api, path.IpldPath(leaf.Cid()), "indirect") + assertIsPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid()), "direct") + assertIsPinned(t, ctx, api, newIPLDPath(t, parent.Cid()), "recursive") + assertIsPinned(t, ctx, api, newIPLDPath(t, leaf.Cid()), "indirect") } type cidContainer interface { Cid() cid.Cid } +type immutablePathCidContainer struct { + path.ImmutablePath +} + +func (i immutablePathCidContainer) Cid() cid.Cid { + return i.RootCid() +} + func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI, leafData string) (cidContainer, cidContainer, cidContainer) { leaf, err := api.Unixfs().Add(ctx, strFile(leafData)()) if err != nil { t.Fatal(err) } - parent, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+leaf.Cid().String()+`"}}`), math.MaxUint64, -1) + parent, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+leaf.RootCid().String()+`"}}`), math.MaxUint64, -1) if err != nil { t.Fatal(err) } @@ -423,7 +430,7 @@ func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI, t.Fatal(err) } - return leaf, parent, grandparent + return immutablePathCidContainer{leaf}, parent, grandparent } func assertPinTypes(t *testing.T, ctx context.Context, api iface.CoreAPI, recusive, direct, indirect []cidContainer) { @@ -466,7 +473,7 @@ func assertPinCids(t *testing.T, pins []iface.Pin, cids ...cidContainer) { valid := true for _, p := range pins { - c := p.Path().Cid() + c := p.Path().RootCid() if cSet.Has(c) { cSet.Remove(c) } else { @@ -480,7 +487,7 @@ func assertPinCids(t *testing.T, pins []iface.Pin, cids ...cidContainer) { if !valid { pinStrs := make([]string, len(pins)) for i, p := range pins { - pinStrs[i] = p.Path().Cid().String() + pinStrs[i] = p.Path().RootCid().String() } pathStrs := make([]string, len(cids)) for i, c := range cids { @@ -511,13 +518,13 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core } for _, p := range allPins { - if !all.Visit(p.Path().Cid()) { + if !all.Visit(p.Path().RootCid()) { t.Fatalf("pin ls returned the same cid multiple times") } typeStr := p.Type() if typeSet, ok := typeMap[p.Type()]; ok { - typeSet.Add(p.Path().Cid()) + typeSet.Add(p.Path().RootCid()) } else { t.Fatalf("unknown pin type: %s", typeStr) } @@ -538,7 +545,7 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core t.Fatalf("returned wrong pin type: expected %s, got %s", typeStr, pinType) } - if c := p.Path().Cid(); !pinProps.Has(c) { + if c := p.Path().RootCid(); !pinProps.Has(c) { t.Fatalf("%s expected to be in pin ls all as type %s", c.String(), typeStr) } } diff --git a/core/coreiface/tests/routing.go b/core/coreiface/tests/routing.go index fd10dffcd..c56e91659 100644 --- a/core/coreiface/tests/routing.go +++ b/core/coreiface/tests/routing.go @@ -7,8 +7,8 @@ import ( iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" "github.com/stretchr/testify/require" ) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 25c3ac1b7..e0c37fce4 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -14,10 +14,9 @@ import ( "sync" "testing" - "github.com/ipfs/boxo/coreiface/path" - coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/path" "github.com/ipfs/boxo/files" mdag "github.com/ipfs/boxo/ipld/merkledag" @@ -106,12 +105,12 @@ func (tp *TestSuite) TestAdd(t *testing.T) { t.Fatal(err) } - p := func(h string) path.Resolved { + p := func(h string) path.ImmutablePath { c, err := cid.Parse(h) if err != nil { t.Fatal(err) } - return path.IpfsPath(c) + return path.FromCid(c) } rf, err := os.CreateTemp(os.TempDir(), "unixfs-add-real") @@ -410,7 +409,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) { } if expected[0].Path != nil && event.Path != nil { - if expected[0].Path.Cid().String() != event.Path.Cid().String() { + if expected[0].Path.RootCid().String() != event.Path.RootCid().String() { t.Errorf("Event.Hash didn't match, %s != %s", expected[0].Path, event.Path) } } else if event.Path != expected[0].Path { @@ -553,7 +552,7 @@ func (tp *TestSuite) TestAddPinned(t *testing.T) { t.Fatalf("expected 1 pin, got %d", len(pins)) } - if pins[0].Path().String() != "/ipld/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" { + if pins[0].Path().String() != "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" { t.Fatalf("got unexpected pin: %s", pins[0].Path().String()) } } @@ -597,7 +596,10 @@ func (tp *TestSuite) TestGetEmptyFile(t *testing.T) { t.Fatal(err) } - emptyFilePath := path.New(emptyFile) + emptyFilePath, err := path.NewPath(emptyFile) + if err != nil { + t.Fatal(err) + } r, err := api.Unixfs().Get(ctx, emptyFilePath) if err != nil { @@ -626,18 +628,18 @@ func (tp *TestSuite) TestGetDir(t *testing.T) { if err != nil { t.Fatal(err) } - p := path.IpfsPath(edir.Cid()) + p := path.FromCid(edir.Cid()) emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) if err != nil { t.Fatal(err) } - if p.String() != path.IpfsPath(emptyDir.Cid()).String() { + if p.String() != path.FromCid(emptyDir.Cid()).String() { t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) } - r, err := api.Unixfs().Get(ctx, path.IpfsPath(emptyDir.Cid())) + r, err := api.Unixfs().Get(ctx, path.FromCid(emptyDir.Cid())) if err != nil { t.Fatal(err) } @@ -661,7 +663,7 @@ func (tp *TestSuite) TestGetNonUnixfs(t *testing.T) { t.Fatal(err) } - _, err = api.Unixfs().Get(ctx, path.IpfsPath(nd.Cid())) + _, err = api.Unixfs().Get(ctx, path.FromCid(nd.Cid())) if !strings.Contains(err.Error(), "proto: required field") { t.Fatalf("expected protobuf error, got: %s", err) } @@ -787,7 +789,7 @@ func (tp *TestSuite) TestLsEmptyDir(t *testing.T) { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, path.IpfsPath(emptyDir.Cid())) + links, err := api.Unixfs().Ls(ctx, path.FromCid(emptyDir.Cid())) if err != nil { t.Fatal(err) } @@ -816,7 +818,7 @@ func (tp *TestSuite) TestLsNonUnixfs(t *testing.T) { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, path.IpfsPath(nd.Cid())) + links, err := api.Unixfs().Ls(ctx, path.FromCid(nd.Cid())) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index 606bc8e78..35e108c02 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -4,17 +4,16 @@ import ( "context" "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ) type AddEvent struct { Name string - Path path.Resolved `json:",omitempty"` - Bytes int64 `json:",omitempty"` - Size string `json:",omitempty"` + Path path.ImmutablePath `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` } // FileType is an enum of possible UnixFS file types. @@ -66,7 +65,7 @@ type UnixfsAPI interface { // Add imports the data from the reader into merkledag file // // TODO: a long useful comment on how to use this for many different scenarios - Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.Resolved, error) + Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.ImmutablePath, error) // Get returns a read-only handle to a file tree referenced by a path //