mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 18:37:45 +08:00
path: WIP
This commit was moved from ipfs/interface-go-ipfs-core@5a83651539 This commit was moved from ipfs/boxo@b8463e7c12
This commit is contained in:
parent
aca6f61a63
commit
51a937fffd
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
199
core/coreiface/path/path.go
Normal file
199
core/coreiface/path/path.go
Normal file
@ -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
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user