From 7adf1cb40d013ea9e6b1af09276542df8ace4bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 12 Jun 2018 03:52:26 +0200 Subject: [PATCH] coreapi: move path utils to interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Ɓukasz Magiera --- core/coreapi/block.go | 4 +- core/coreapi/dag.go | 4 +- core/coreapi/dag_test.go | 7 +-- core/coreapi/interface/coreapi.go | 10 ---- core/coreapi/interface/path.go | 87 +++++++++++++++++++++++++++++++ core/coreapi/key.go | 7 ++- core/coreapi/name.go | 2 +- core/coreapi/object.go | 8 +-- core/coreapi/path.go | 80 +--------------------------- core/coreapi/path_test.go | 9 ++-- core/coreapi/pin.go | 4 +- core/coreapi/unixfs.go | 2 +- core/coreapi/unixfs_test.go | 20 +++---- core/corehttp/gateway_handler.go | 4 +- 14 files changed, 128 insertions(+), 120 deletions(-) diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 6342dc692..69f5060c8 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -65,7 +65,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc return nil, err } - return api.core().IpldPath(b.Cid()), nil + return coreiface.IpldPath(b.Cid()), nil } func (api *BlockAPI) Get(ctx context.Context, p coreiface.Path) (io.Reader, error) { @@ -132,7 +132,7 @@ func (api *BlockAPI) Stat(ctx context.Context, p coreiface.Path) (coreiface.Bloc } return &BlockStat{ - path: api.core().IpldPath(b.Cid()), + path: coreiface.IpldPath(b.Cid()), size: len(b.RawData()), }, nil } diff --git a/core/coreapi/dag.go b/core/coreapi/dag.go index 60692157c..75416a249 100644 --- a/core/coreapi/dag.go +++ b/core/coreapi/dag.go @@ -44,7 +44,7 @@ func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPut return nil, err } - return api.core().IpldPath(nds[0].Cid()), nil + return coreiface.IpldPath(nds[0].Cid()), nil } // Get resolves `path` using Unixfs resolver, returns the resolved Node. @@ -66,7 +66,7 @@ func (api *DagAPI) Tree(ctx context.Context, p coreiface.Path, opts ...caopts.Da paths := n.Tree("", settings.Depth) out := make([]coreiface.Path, len(paths)) for n, p2 := range paths { - out[n], err = api.core().ParsePath(gopath.Join(p.String(), p2)) + out[n], err = coreiface.ParsePath(gopath.Join(p.String(), p2)) if err != nil { return nil, err } diff --git a/core/coreapi/dag_test.go b/core/coreapi/dag_test.go index 416d7d97b..773ff0f1a 100644 --- a/core/coreapi/dag_test.go +++ b/core/coreapi/dag_test.go @@ -6,9 +6,10 @@ import ( "strings" "testing" - mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" - + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + + mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash" ) var ( @@ -72,7 +73,7 @@ func TestPath(t *testing.T) { t.Error(err) } - p, err := api.ParsePath(path.Join(res.Cid().String(), "lnk")) + p, err := coreiface.ParsePath(path.Join(res.Cid().String(), "lnk")) if err != nil { t.Error(err) } diff --git a/core/coreapi/interface/coreapi.go b/core/coreapi/interface/coreapi.go index f5e81adce..82a2ebf4e 100644 --- a/core/coreapi/interface/coreapi.go +++ b/core/coreapi/interface/coreapi.go @@ -6,7 +6,6 @@ import ( "context" ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format" - cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ) // CoreAPI defines an unified interface to IPFS for Go programs @@ -38,13 +37,4 @@ type CoreAPI interface { // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node ResolveNode(context.Context, Path) (ipld.Node, error) - - // ParsePath parses string path to a Path - ParsePath(string) (Path, error) - - // IpfsPath creates new /ipfs path from the provided CID - IpfsPath(*cid.Cid) ResolvedPath - - // IpldPath creates new /ipld path from the provided CID - IpldPath(*cid.Cid) ResolvedPath } diff --git a/core/coreapi/interface/path.go b/core/coreapi/interface/path.go index acdcd85da..e097ea3b6 100644 --- a/core/coreapi/interface/path.go +++ b/core/coreapi/interface/path.go @@ -1,9 +1,13 @@ package iface import ( + ipfspath "github.com/ipfs/go-ipfs/path" + cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid" ) +//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. // @@ -87,3 +91,86 @@ type ResolvedPath interface { Path } + +// path implements coreiface.Path +type path struct { + path ipfspath.Path +} + +// resolvedPath implements coreiface.resolvedPath +type resolvedPath struct { + path + cid *cid.Cid + root *cid.Cid + remainder string +} + +// IpfsPath creates new /ipfs path from the provided CID +func IpfsPath(c *cid.Cid) ResolvedPath { + return &resolvedPath{ + path: path{ipfspath.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{ipfspath.Path("/ipld/" + c.String())}, + cid: c, + root: c, + remainder: "", + } +} + +// ParsePath parses string path to a Path +func ParsePath(p string) (Path, error) { + pp, err := ipfspath.ParsePath(p) + if err != nil { + return nil, err + } + + return &path{path: pp}, nil +} + +// 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}, + cid: c, + root: root, + remainder: remainder, + } +} + +func (p *path) String() string { + return p.path.String() +} + +func (p *path) Namespace() string { + if len(p.path.Segments()) < 1 { + panic("path without namespace") //this shouldn't happen under any scenario + } + return p.path.Segments()[0] +} + +func (p *path) Mutable() bool { + //TODO: MFS: check for /local + return p.Namespace() == "ipns" +} + +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/coreapi/key.go b/core/coreapi/key.go index 0198f6762..e22d70cb4 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -28,7 +28,12 @@ func (k *key) Name() string { // Path returns the path of the key. func (k *key) Path() coreiface.Path { - return &path{path: ipfspath.FromString(ipfspath.Join([]string{"/ipns", k.peerId}))} + path, err := coreiface.ParsePath(ipfspath.Join([]string{"/ipns", k.peerId})) + if err != nil { + panic("error parsing path: " + err.Error()) + } + + return path } // Generate generates new key, stores it in the keystore under the specified diff --git a/core/coreapi/name.go b/core/coreapi/name.go index 651d85523..4e1018b54 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -129,7 +129,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam return nil, err } - return &path{path: output}, nil + return coreiface.ParsePath(output.String()) } func keylookup(n *core.IpfsNode, k string) (crypto.PrivKey, error) { diff --git a/core/coreapi/object.go b/core/coreapi/object.go index b8a007bd5..f0ccecef6 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -121,7 +121,7 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj return nil, err } - return api.core().IpfsPath(dagnode.Cid()), nil + return coreiface.IpfsPath(dagnode.Cid()), nil } func (api *ObjectAPI) Get(ctx context.Context, path coreiface.Path) (ipld.Node, error) { @@ -218,7 +218,7 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base coreiface.Path, name str return nil, err } - return api.core().IpfsPath(nnode.Cid()), nil + return coreiface.IpfsPath(nnode.Cid()), nil } func (api *ObjectAPI) RmLink(ctx context.Context, base coreiface.Path, link string) (coreiface.ResolvedPath, error) { @@ -244,7 +244,7 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base coreiface.Path, link stri return nil, err } - return api.core().IpfsPath(nnode.Cid()), nil + return coreiface.IpfsPath(nnode.Cid()), nil } func (api *ObjectAPI) AppendData(ctx context.Context, path coreiface.Path, r io.Reader) (coreiface.ResolvedPath, error) { @@ -281,7 +281,7 @@ func (api *ObjectAPI) patchData(ctx context.Context, path coreiface.Path, r io.R return nil, err } - return api.core().IpfsPath(pbnd.Cid()), nil + return coreiface.IpfsPath(pbnd.Cid()), nil } func (api *ObjectAPI) core() coreiface.CoreAPI { diff --git a/core/coreapi/path.go b/core/coreapi/path.go index 85dc0f7cc..c8987006e 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -16,39 +16,6 @@ import ( cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid" ) -// path implements coreiface.Path -type path struct { - path ipfspath.Path -} - -// resolvedPath implements coreiface.resolvedPath -type resolvedPath struct { - path - cid *cid.Cid - root *cid.Cid - remainder string -} - -// IpfsPath parses the path from `c`, reruns the parsed path. -func (api *CoreAPI) IpfsPath(c *cid.Cid) coreiface.ResolvedPath { - return &resolvedPath{ - path: path{ipfspath.Path("/ipfs/" + c.String())}, - cid: c, - root: c, - remainder: "", - } -} - -// IpldPath parses the path from `c`, reruns the parsed path. -func (api *CoreAPI) IpldPath(c *cid.Cid) coreiface.ResolvedPath { - return &resolvedPath{ - path: path{ipfspath.Path("/ipld/" + c.String())}, - cid: c, - root: c, - remainder: "", - } -} - // ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the // resolved Node. func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (ipld.Node, error) { @@ -79,7 +46,7 @@ func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSyste return p.(coreiface.ResolvedPath), nil } - ipath := p.(*path).path + ipath := ipfspath.Path(p.String()) ipath, err := core.ResolveIPNS(ctx, nsys, ipath) if err == core.ErrNoNamesys { return nil, coreiface.ErrOffline @@ -113,48 +80,5 @@ func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSyste return nil, err } - return &resolvedPath{ - path: path{ipath}, - cid: node.Cid(), - root: root, - remainder: gopath.Join(rest...), - }, nil -} - -// ParsePath parses path `p` using ipfspath parser, returns the parsed path. -func (api *CoreAPI) ParsePath(p string) (coreiface.Path, error) { - pp, err := ipfspath.ParsePath(p) - if err != nil { - return nil, err - } - - return &path{path: pp}, nil -} - -func (p *path) String() string { - return p.path.String() -} - -func (p *path) Namespace() string { - if len(p.path.Segments()) < 1 { - panic("path without namespace") //this shouldn't happen under any scenario - } - return p.path.Segments()[0] -} - -func (p *path) Mutable() bool { - //TODO: MFS: check for /local - return p.Namespace() == "ipns" -} - -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 + return coreiface.NewResolvedPath(ipath, node.Cid(), root, gopath.Join(rest...)), nil } diff --git a/core/coreapi/path_test.go b/core/coreapi/path_test.go index 7f1f686fa..76e78b545 100644 --- a/core/coreapi/path_test.go +++ b/core/coreapi/path_test.go @@ -5,6 +5,7 @@ import ( "strings" "testing" + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" ) @@ -47,7 +48,7 @@ func TestPathRemainder(t *testing.T) { t.Fatal(err) } - p1, err := api.ParsePath(obj.String() + "/foo/bar") + p1, err := coreiface.ParsePath(obj.String() + "/foo/bar") if err != nil { t.Error(err) } @@ -78,7 +79,7 @@ func TestEmptyPathRemainder(t *testing.T) { t.Error("expected the resolved path to not have a remainder") } - p1, err := api.ParsePath(obj.String()) + p1, err := coreiface.ParsePath(obj.String()) if err != nil { t.Error(err) } @@ -105,7 +106,7 @@ func TestInvalidPathRemainder(t *testing.T) { t.Fatal(err) } - p1, err := api.ParsePath(obj.String() + "/bar/baz") + p1, err := coreiface.ParsePath(obj.String() + "/bar/baz") if err != nil { t.Error(err) } @@ -133,7 +134,7 @@ func TestPathRoot(t *testing.T) { t.Fatal(err) } - p1, err := api.ParsePath(obj.String() + "/foo") + p1, err := coreiface.ParsePath(obj.String() + "/foo") if err != nil { t.Error(err) } diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index e705a20c2..6c5a0fbdb 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -125,7 +125,7 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro links, err := getLinks(ctx, root) if err != nil { status := &pinStatus{ok: false, cid: root} - status.badNodes = []coreiface.BadPinNode{&badNode{path: api.core().IpldPath(root), err: err}} + status.badNodes = []coreiface.BadPinNode{&badNode{path: coreiface.IpldPath(root), err: err}} visited[key] = status return status } @@ -175,7 +175,7 @@ func (api *PinAPI) pinLsAll(typeStr string, ctx context.Context) ([]coreiface.Pi for _, c := range keyList { keys[c.String()] = &pinInfo{ pinType: typeStr, - path: api.core().IpldPath(c), + path: coreiface.IpldPath(c), } } } diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index ef4547989..9cc16ddc5 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -25,7 +25,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.ResolvedP if err != nil { return nil, err } - return api.core().IpfsPath(c), nil + return coreiface.IpfsPath(c), nil } // Cat returns the data contained by an IPFS or IPNS object(s) at path `p`. diff --git a/core/coreapi/unixfs_test.go b/core/coreapi/unixfs_test.go index c7325f3ac..2e7f15f62 100644 --- a/core/coreapi/unixfs_test.go +++ b/core/coreapi/unixfs_test.go @@ -151,7 +151,7 @@ func TestCatBasic(t *testing.T) { t.Fatalf("expected CID %s, got: %s", hello, p) } - helloPath, err := api.ParsePath(hello) + helloPath, err := coreiface.ParsePath(hello) if err != nil { t.Fatal(err) } @@ -183,7 +183,7 @@ func TestCatEmptyFile(t *testing.T) { t.Fatal(err) } - emptyFilePath, err := api.ParsePath(emptyFile) + emptyFilePath, err := coreiface.ParsePath(emptyFile) if err != nil { t.Fatal(err) } @@ -214,18 +214,18 @@ func TestCatDir(t *testing.T) { if err != nil { t.Error(err) } - p := api.IpfsPath(edir.Cid()) + p := coreiface.IpfsPath(edir.Cid()) emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) if err != nil { t.Error(err) } - if p.String() != api.IpfsPath(emptyDir.Cid()).String() { + if p.String() != coreiface.IpfsPath(emptyDir.Cid()).String() { t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) } - _, err = api.Unixfs().Cat(ctx, api.IpfsPath(emptyDir.Cid())) + _, err = api.Unixfs().Cat(ctx, coreiface.IpfsPath(emptyDir.Cid())) if err != coreiface.ErrIsDir { t.Fatalf("expected ErrIsDir, got: %s", err) } @@ -244,7 +244,7 @@ func TestCatNonUnixfs(t *testing.T) { t.Error(err) } - _, err = api.Unixfs().Cat(ctx, api.IpfsPath(nd.Cid())) + _, err = api.Unixfs().Cat(ctx, coreiface.IpfsPath(nd.Cid())) if !strings.Contains(err.Error(), "proto: required field") { t.Fatalf("expected protobuf error, got: %s", err) } @@ -257,7 +257,7 @@ func TestCatOffline(t *testing.T) { t.Error(err) } - p, err := api.ParsePath("/ipns/Qmfoobar") + p, err := coreiface.ParsePath("/ipns/Qmfoobar") if err != nil { t.Error(err) } @@ -283,7 +283,7 @@ func TestLs(t *testing.T) { if len(parts) != 2 { t.Errorf("unexpected path: %s", k) } - p, err := api.ParsePath("/ipfs/" + parts[0]) + p, err := coreiface.ParsePath("/ipfs/" + parts[0]) if err != nil { t.Error(err) } @@ -324,7 +324,7 @@ func TestLsEmptyDir(t *testing.T) { t.Error(err) } - links, err := api.Unixfs().Ls(ctx, api.IpfsPath(emptyDir.Cid())) + links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(emptyDir.Cid())) if err != nil { t.Error(err) } @@ -352,7 +352,7 @@ func TestLsNonUnixfs(t *testing.T) { t.Error(err) } - links, err := api.Unixfs().Ls(ctx, api.IpfsPath(nd.Cid())) + links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(nd.Cid())) if err != nil { t.Error(err) } diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 0f148a495..1236b30f5 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -159,7 +159,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr ipnsHostname = true } - parsedPath, err := i.api.ParsePath(urlPath) + parsedPath, err := coreiface.ParsePath(urlPath) if err != nil { webError(w, "invalid ipfs path", err, http.StatusBadRequest) return @@ -287,7 +287,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr return } - dr, err := i.api.Unixfs().Cat(ctx, i.api.IpfsPath(ixnd.Cid())) + dr, err := i.api.Unixfs().Cat(ctx, coreiface.IpfsPath(ixnd.Cid())) if err != nil { internalWebError(w, err) return