mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
feat(path)!: consolidated path libraries (#334)
This commit was moved from ipfs/boxo@85c180e266
This commit is contained in:
parent
4e0f9aa922
commit
5bac37c735
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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())
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
//
|
||||
|
||||
Loading…
Reference in New Issue
Block a user