From 51a937fffd45edbc0543fe4a2338b6034e5ea2a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 25 Mar 2019 19:37:28 +0100 Subject: [PATCH] path: WIP This commit was moved from ipfs/interface-go-ipfs-core@5a836515396273412794edaaba72ef0cf3ead46d This commit was moved from ipfs/boxo@b8463e7c123e4ff15fd8fdd33a02a6414682ca9a --- core/coreiface/block.go | 11 +- core/coreiface/coreapi.go | 5 +- core/coreiface/dht.go | 7 +- core/coreiface/key.go | 5 +- core/coreiface/name.go | 11 +- core/coreiface/object.go | 29 ++--- core/coreiface/path.go | 197 -------------------------------- core/coreiface/path/path.go | 199 +++++++++++++++++++++++++++++++++ core/coreiface/pin.go | 13 ++- core/coreiface/tests/block.go | 3 +- core/coreiface/tests/dag.go | 5 +- core/coreiface/tests/name.go | 12 +- core/coreiface/tests/path.go | 14 +-- core/coreiface/tests/pin.go | 13 ++- core/coreiface/tests/unixfs.go | 19 ++-- core/coreiface/unixfs.go | 17 +-- 16 files changed, 287 insertions(+), 273 deletions(-) create mode 100644 core/coreiface/path/path.go diff --git a/core/coreiface/block.go b/core/coreiface/block.go index 587ad339f..9f0ad9cbb 100644 --- a/core/coreiface/block.go +++ b/core/coreiface/block.go @@ -2,9 +2,10 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "io" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" ) // BlockStat contains information about a block @@ -13,7 +14,7 @@ type BlockStat interface { Size() int // Path returns path to the block - Path() ResolvedPath + Path() path.ResolvedPath } // BlockAPI specifies the interface to the block layer @@ -22,15 +23,15 @@ type BlockAPI interface { Put(context.Context, io.Reader, ...options.BlockPutOption) (BlockStat, error) // Get attempts to resolve the path and return a reader for data in the block - Get(context.Context, Path) (io.Reader, error) + Get(context.Context, path.Path) (io.Reader, error) // Rm removes the block specified by the path from local blockstore. // By default an error will be returned if the block can't be found locally. // // NOTE: If the specified block is pinned it won't be removed and no error // will be returned - Rm(context.Context, Path, ...options.BlockRmOption) error + Rm(context.Context, path.Path, ...options.BlockRmOption) error // Stat returns information on - Stat(context.Context, Path) (BlockStat, error) + Stat(context.Context, path.Path) (BlockStat, error) } diff --git a/core/coreiface/coreapi.go b/core/coreiface/coreapi.go index f3433c089..bef3ce01f 100644 --- a/core/coreiface/coreapi.go +++ b/core/coreiface/coreapi.go @@ -4,6 +4,7 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" @@ -43,11 +44,11 @@ type CoreAPI interface { PubSub() PubSubAPI // ResolvePath resolves the path using Unixfs resolver - ResolvePath(context.Context, Path) (ResolvedPath, error) + ResolvePath(context.Context, path.Path) (path.ResolvedPath, error) // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node - ResolveNode(context.Context, Path) (ipld.Node, error) + ResolveNode(context.Context, path.Path) (ipld.Node, error) // WithOptions creates new instance of CoreAPI based on this instance with // a set of options applied diff --git a/core/coreiface/dht.go b/core/coreiface/dht.go index d1ae05125..0cb7893ef 100644 --- a/core/coreiface/dht.go +++ b/core/coreiface/dht.go @@ -2,10 +2,11 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/options" - peer "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-peer" pstore "github.com/libp2p/go-libp2p-peerstore" ) @@ -19,8 +20,8 @@ type DhtAPI interface { // FindProviders finds peers in the DHT who can provide a specific value // given a key. - FindProviders(context.Context, Path, ...options.DhtFindProvidersOption) (<-chan pstore.PeerInfo, error) + FindProviders(context.Context, path.Path, ...options.DhtFindProvidersOption) (<-chan pstore.PeerInfo, error) // Provide announces to the network that you are providing given values - Provide(context.Context, Path, ...options.DhtProvideOption) error + Provide(context.Context, path.Path, ...options.DhtProvideOption) error } diff --git a/core/coreiface/key.go b/core/coreiface/key.go index 78c29d268..e7fb3f442 100644 --- a/core/coreiface/key.go +++ b/core/coreiface/key.go @@ -2,8 +2,9 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" "github.com/libp2p/go-libp2p-peer" ) @@ -14,7 +15,7 @@ type Key interface { Name() string // Path returns key path - Path() Path + Path() path.Path // ID returns key PeerID ID() peer.ID diff --git a/core/coreiface/name.go b/core/coreiface/name.go index 51b005b7e..3dc9f6878 100644 --- a/core/coreiface/name.go +++ b/core/coreiface/name.go @@ -3,8 +3,9 @@ package iface import ( "context" "errors" + path "github.com/ipfs/interface-go-ipfs-core/path" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" ) var ErrResolveFailed = errors.New("could not resolve name") @@ -14,11 +15,11 @@ type IpnsEntry interface { // Name returns IpnsEntry name Name() string // Value returns IpnsEntry value - Value() Path + Value() path.Path } type IpnsResult struct { - Path + path.Path Err error } @@ -32,10 +33,10 @@ type IpnsResult struct { // You can use .Key API to list and generate more names and their respective keys. type NameAPI interface { // Publish announces new IPNS name - Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (IpnsEntry, error) + Publish(ctx context.Context, path path.Path, opts ...options.NamePublishOption) (IpnsEntry, error) // Resolve attempts to resolve the newest version of the specified name - Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error) + Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (path.Path, error) // Search is a version of Resolve which outputs paths as they are discovered, // reducing the time to first entry diff --git a/core/coreiface/object.go b/core/coreiface/object.go index 4f9652fb1..3e4b7e087 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -2,11 +2,12 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "io" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) @@ -58,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 ResolvedPath + Before path.ResolvedPath // After holds the link path after the change. Note that when a link is // removed, this will be nil. - After ResolvedPath + After path.ResolvedPath } // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities @@ -72,35 +73,35 @@ type ObjectAPI interface { New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (ResolvedPath, error) + Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.ResolvedPath, error) // Get returns the node for the path - Get(context.Context, Path) (ipld.Node, error) + Get(context.Context, path.Path) (ipld.Node, error) // Data returns reader for data of the node - Data(context.Context, Path) (io.Reader, error) + Data(context.Context, path.Path) (io.Reader, error) // Links returns lint or links the node contains - Links(context.Context, Path) ([]*ipld.Link, error) + Links(context.Context, path.Path) ([]*ipld.Link, error) // Stat returns information about the node - Stat(context.Context, Path) (*ObjectStat, error) + Stat(context.Context, path.Path) (*ObjectStat, error) // 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, name string, child Path, opts ...options.ObjectAddLinkOption) (ResolvedPath, error) + AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.ResolvedPath, error) // RmLink removes a link from the node - RmLink(ctx context.Context, base Path, link string) (ResolvedPath, error) + RmLink(ctx context.Context, base path.Path, link string) (path.ResolvedPath, error) // AppendData appends data to the node - AppendData(context.Context, Path, io.Reader) (ResolvedPath, error) + AppendData(context.Context, path.Path, io.Reader) (path.ResolvedPath, error) // SetData sets the data contained in the node - SetData(context.Context, Path, io.Reader) (ResolvedPath, error) + SetData(context.Context, path.Path, io.Reader) (path.ResolvedPath, error) // Diff returns a set of changes needed to transform the first object into the // second. - Diff(context.Context, Path, Path) ([]ObjectChange, error) + Diff(context.Context, path.Path, path.Path) ([]ObjectChange, error) } diff --git a/core/coreiface/path.go b/core/coreiface/path.go index ede190df7..198651129 100644 --- a/core/coreiface/path.go +++ b/core/coreiface/path.go @@ -1,201 +1,4 @@ package iface -import ( - "strings" - - cid "github.com/ipfs/go-cid" - ipfspath "github.com/ipfs/go-path" -) - //TODO: merge with ipfspath so we don't depend on it -// 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 -} - -// ResolvedPath is a path which was resolved to the last resolvable node. -// ResolvedPaths are guaranteed to return nil from `IsValid` -type ResolvedPath 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) ResolvedPath { - 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) ResolvedPath { - return &resolvedPath{ - path: path{"/ipld/" + c.String()}, - cid: c, - root: c, - remainder: "", - } -} - -// ParsePath parses string path to a Path -func ParsePath(p string) Path { - if pp, err := ipfspath.ParsePath(p); err == nil { - p = pp.String() - } - - return &path{path: p} -} - -// NewResolvedPath creates new ResolvedPath. 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) ResolvedPath { - 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/path/path.go b/core/coreiface/path/path.go new file mode 100644 index 000000000..414d454fa --- /dev/null +++ b/core/coreiface/path/path.go @@ -0,0 +1,199 @@ +package path + +import ( + "strings" + + cid "github.com/ipfs/go-cid" + ipfspath "github.com/ipfs/go-path" +) + +// 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 +} + +// ResolvedPath is a path which was resolved to the last resolvable node. +// ResolvedPaths are guaranteed to return nil from `IsValid` +type ResolvedPath 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) ResolvedPath { + 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) ResolvedPath { + return &resolvedPath{ + path: path{"/ipld/" + c.String()}, + cid: c, + root: c, + remainder: "", + } +} + +// ParsePath parses string path to a Path +func ParsePath(p string) Path { + if pp, err := ipfspath.ParsePath(p); err == nil { + p = pp.String() + } + + return &path{path: p} +} + +// NewResolvedPath creates new ResolvedPath. 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) ResolvedPath { + 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 6a7dab413..736b2d68b 100644 --- a/core/coreiface/pin.go +++ b/core/coreiface/pin.go @@ -2,14 +2,15 @@ package iface import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" - options "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/options" ) // Pin holds information about pinned resource type Pin interface { // Path to the pinned object - Path() ResolvedPath + Path() path.ResolvedPath // Type of the pin Type() string @@ -27,7 +28,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() ResolvedPath + Path() path.ResolvedPath // Err is the reason why the node has been marked as bad Err() error @@ -37,17 +38,17 @@ type BadPinNode interface { type PinAPI interface { // Add creates new pin, be default recursive - pinning the whole referenced // tree - Add(context.Context, Path, ...options.PinAddOption) error + Add(context.Context, path.Path, ...options.PinAddOption) error // Ls returns list of pinned objects on this node Ls(context.Context, ...options.PinLsOption) ([]Pin, error) // Rm removes pin for object specified by the path - Rm(context.Context, Path, ...options.PinRmOption) error + Rm(context.Context, path.Path, ...options.PinRmOption) error // Update changes one pin to another, skipping checks for matching paths in // the old tree - Update(ctx context.Context, from Path, to Path, opts ...options.PinUpdateOption) error + Update(ctx context.Context, from path.Path, to path.Path, opts ...options.PinUpdateOption) error // Verify verifies the integrity of pinned objects Verify(context.Context) (<-chan PinStatus, error) diff --git a/core/coreiface/tests/block.go b/core/coreiface/tests/block.go index 96319b488..59b49d567 100644 --- a/core/coreiface/tests/block.go +++ b/core/coreiface/tests/block.go @@ -2,6 +2,7 @@ package tests import ( "context" + "github.com/ipfs/interface-go-ipfs-core/path" "io/ioutil" "strings" "testing" @@ -110,7 +111,7 @@ func (tp *provider) TestBlockGet(t *testing.T) { t.Error("didn't get correct data back") } - p := coreiface.ParsePath("/ipfs/" + res.Path().Cid().String()) + p := path.ParsePath("/ipfs/" + res.Path().Cid().String()) rp, err := api.ResolvePath(ctx, p) if err != nil { diff --git a/core/coreiface/tests/dag.go b/core/coreiface/tests/dag.go index a17296d1d..0abcee32f 100644 --- a/core/coreiface/tests/dag.go +++ b/core/coreiface/tests/dag.go @@ -2,8 +2,9 @@ package tests import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "math" - "path" + gopath "path" "strings" "testing" @@ -113,7 +114,7 @@ func (tp *provider) TestDagPath(t *testing.T) { t.Fatal(err) } - p := coreiface.ParsePath(path.Join(nd.Cid().String(), "lnk")) + p := path.ParsePath(gopath.Join(nd.Cid().String(), "lnk")) rp, err := api.ResolvePath(ctx, p) if err != nil { diff --git a/core/coreiface/tests/name.go b/core/coreiface/tests/name.go index c9e99a584..98ae6853e 100644 --- a/core/coreiface/tests/name.go +++ b/core/coreiface/tests/name.go @@ -2,9 +2,10 @@ package tests import ( "context" + path "github.com/ipfs/interface-go-ipfs-core/path" "io" "math/rand" - "path" + gopath "path" "testing" "time" @@ -30,18 +31,18 @@ func (tp *provider) TestName(t *testing.T) { var rnd = rand.New(rand.NewSource(0x62796532303137)) -func addTestObject(ctx context.Context, api coreiface.CoreAPI) (coreiface.Path, error) { +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 coreiface.Path, sub string) coreiface.Path { - return coreiface.ParsePath(path.Join(p.String(), sub)) +func appendPath(p path.Path, sub string) path.Path { + return path.ParsePath(gopath.Join(p.String(), sub)) } func (tp *provider) TestPublishResolve(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - init := func() (coreiface.CoreAPI, coreiface.Path) { + init := func() (coreiface.CoreAPI, path.Path) { apis, err := tp.MakeAPISwarm(ctx, true, 5) if err != nil { t.Fatal(err) @@ -56,7 +57,6 @@ func (tp *provider) TestPublishResolve(t *testing.T) { } return api, p } - run := func(t *testing.T, ropts []opt.NameResolveOption) { t.Run("basic", func(t *testing.T) { api, p := init() diff --git a/core/coreiface/tests/path.go b/core/coreiface/tests/path.go index f5b0ee348..685f46998 100644 --- a/core/coreiface/tests/path.go +++ b/core/coreiface/tests/path.go @@ -2,11 +2,11 @@ package tests import ( "context" + "github.com/ipfs/interface-go-ipfs-core/path" "math" "strings" "testing" - coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" ipldcbor "github.com/ipfs/go-ipld-cbor" @@ -75,7 +75,7 @@ func (tp *provider) TestPathRemainder(t *testing.T) { t.Fatal(err) } - rp1, err := api.ResolvePath(ctx, coreiface.ParsePath(nd.String()+"/foo/bar")) + rp1, err := api.ResolvePath(ctx, path.ParsePath(nd.String()+"/foo/bar")) if err != nil { t.Fatal(err) } @@ -106,7 +106,7 @@ func (tp *provider) TestEmptyPathRemainder(t *testing.T) { t.Fatal(err) } - rp1, err := api.ResolvePath(ctx, coreiface.ParsePath(nd.Cid().String())) + rp1, err := api.ResolvePath(ctx, path.ParsePath(nd.Cid().String())) if err != nil { t.Fatal(err) } @@ -137,7 +137,7 @@ func (tp *provider) TestInvalidPathRemainder(t *testing.T) { t.Fatal(err) } - _, err = api.ResolvePath(ctx, coreiface.ParsePath("/ipld/"+nd.Cid().String()+"/bar/baz")) + _, err = api.ResolvePath(ctx, path.ParsePath("/ipld/"+nd.Cid().String()+"/bar/baz")) if err == nil || !strings.Contains(err.Error(), "no such link found") { t.Fatalf("unexpected error: %s", err) } @@ -173,7 +173,7 @@ func (tp *provider) TestPathRoot(t *testing.T) { t.Fatal(err) } - rp, err := api.ResolvePath(ctx, coreiface.ParsePath("/ipld/"+nd.Cid().String()+"/foo")) + rp, err := api.ResolvePath(ctx, path.ParsePath("/ipld/"+nd.Cid().String()+"/foo")) if err != nil { t.Fatal(err) } @@ -188,9 +188,9 @@ func (tp *provider) TestPathRoot(t *testing.T) { } func (tp *provider) TestPathJoin(t *testing.T) { - p1 := coreiface.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") + p1 := path.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz") - if coreiface.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { + if path.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" { t.Error("unexpected path") } } diff --git a/core/coreiface/tests/pin.go b/core/coreiface/tests/pin.go index ff6f98e35..344db65e2 100644 --- a/core/coreiface/tests/pin.go +++ b/core/coreiface/tests/pin.go @@ -2,6 +2,7 @@ package tests import ( "context" + "github.com/ipfs/interface-go-ipfs-core/path" "math" "strings" "testing" @@ -127,12 +128,12 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Fatal(err) } - err = api.Pin().Add(ctx, iface.IpldPath(nd2.Cid())) + err = api.Pin().Add(ctx, path.IpldPath(nd2.Cid())) if err != nil { t.Fatal(err) } - err = api.Pin().Add(ctx, iface.IpldPath(nd3.Cid()), opt.Pin.Recursive(false)) + err = api.Pin().Add(ctx, path.IpldPath(nd3.Cid()), opt.Pin.Recursive(false)) if err != nil { t.Fatal(err) } @@ -155,8 +156,8 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != iface.IpldPath(nd3.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpfsPath(nd2.Cid()).String()) + if list[0].Path().String() != path.IpldPath(nd3.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd2.Cid()).String()) } list, err = api.Pin().Ls(ctx, opt.Pin.Type.Recursive()) @@ -168,8 +169,8 @@ func (tp *provider) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - if list[0].Path().String() != iface.IpldPath(nd2.Cid()).String() { - t.Errorf("unexpected path, %s != %s", list[0].Path().String(), iface.IpldPath(nd3.Cid()).String()) + if list[0].Path().String() != path.IpldPath(nd2.Cid()).String() { + t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd3.Cid()).String()) } list, err = api.Pin().Ls(ctx, opt.Pin.Type.Indirect()) diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 15cb8abc8..d2d9f85b8 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -5,6 +5,7 @@ import ( "context" "encoding/hex" "fmt" + "github.com/ipfs/interface-go-ipfs-core/path" "io" "io/ioutil" "math" @@ -101,12 +102,12 @@ func (tp *provider) TestAdd(t *testing.T) { t.Fatal(err) } - p := func(h string) coreiface.ResolvedPath { + p := func(h string) path.ResolvedPath { c, err := cid.Parse(h) if err != nil { t.Fatal(err) } - return coreiface.IpfsPath(c) + return path.IpfsPath(c) } rf, err := ioutil.TempFile(os.TempDir(), "unixfs-add-real") @@ -592,7 +593,7 @@ func (tp *provider) TestGetEmptyFile(t *testing.T) { t.Fatal(err) } - emptyFilePath := coreiface.ParsePath(emptyFile) + emptyFilePath := path.ParsePath(emptyFile) r, err := api.Unixfs().Get(ctx, emptyFilePath) if err != nil { @@ -621,18 +622,18 @@ func (tp *provider) TestGetDir(t *testing.T) { if err != nil { t.Fatal(err) } - p := coreiface.IpfsPath(edir.Cid()) + p := path.IpfsPath(edir.Cid()) emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) if err != nil { t.Fatal(err) } - if p.String() != coreiface.IpfsPath(emptyDir.Cid()).String() { + if p.String() != path.IpfsPath(emptyDir.Cid()).String() { t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) } - r, err := api.Unixfs().Get(ctx, coreiface.IpfsPath(emptyDir.Cid())) + r, err := api.Unixfs().Get(ctx, path.IpfsPath(emptyDir.Cid())) if err != nil { t.Fatal(err) } @@ -656,7 +657,7 @@ func (tp *provider) TestGetNonUnixfs(t *testing.T) { t.Fatal(err) } - _, err = api.Unixfs().Get(ctx, coreiface.IpfsPath(nd.Cid())) + _, err = api.Unixfs().Get(ctx, path.IpfsPath(nd.Cid())) if !strings.Contains(err.Error(), "proto: required field") { t.Fatalf("expected protobuf error, got: %s", err) } @@ -782,7 +783,7 @@ func (tp *provider) TestLsEmptyDir(t *testing.T) { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(emptyDir.Cid())) + links, err := api.Unixfs().Ls(ctx, path.IpfsPath(emptyDir.Cid())) if err != nil { t.Fatal(err) } @@ -811,7 +812,7 @@ func (tp *provider) TestLsNonUnixfs(t *testing.T) { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(nd.Cid())) + links, err := api.Unixfs().Ls(ctx, path.IpfsPath(nd.Cid())) if err != nil { t.Fatal(err) } diff --git a/core/coreiface/unixfs.go b/core/coreiface/unixfs.go index f9508f138..0b27519f3 100644 --- a/core/coreiface/unixfs.go +++ b/core/coreiface/unixfs.go @@ -3,16 +3,17 @@ package iface import ( "context" "github.com/ipfs/interface-go-ipfs-core/options" + path "github.com/ipfs/interface-go-ipfs-core/path" - cid "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipfs-files" ) type AddEvent struct { Name string - Path ResolvedPath `json:",omitempty"` - Bytes int64 `json:",omitempty"` - Size string `json:",omitempty"` + Path path.ResolvedPath `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` } // FileType is an enum of possible UnixFS file types. @@ -64,15 +65,15 @@ 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) (ResolvedPath, error) + Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.ResolvedPath, error) // Get returns a read-only handle to a file tree referenced by a path // // Note that some implementations of this API may apply the specified context // to operations performed on the returned file - Get(context.Context, Path) (files.Node, error) + Get(context.Context, path.Path) (files.Node, error) // Ls returns the list of links in a directory. Links aren't guaranteed to be // returned in order - Ls(context.Context, Path, ...options.UnixfsLsOption) (<-chan DirEntry, error) + Ls(context.Context, path.Path, ...options.UnixfsLsOption) (<-chan DirEntry, error) }