coreapi: move path utils to interface
License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
Łukasz Magiera committed
Jun 12, 2018 at 03:52 UTC
7adf1cb40d013ea9e6b1af09276542df8ace4bbc
14 files changed
+128
-120
core/coreapi/block.go
+2
-2
@@ -65,7 +65,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc
65
return nil, err
66
}
67
68
- return api.core().IpldPath(b.Cid()), nil
68
+ return coreiface.IpldPath(b.Cid()), nil
69
}
70
71
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
132
}
133
134
return &BlockStat{
135
- path: api.core().IpldPath(b.Cid()),
135
+ path: coreiface.IpldPath(b.Cid()),
136
size: len(b.RawData()),
137
}, nil
138
}
core/coreapi/dag.go
+2
-2
@@ -44,7 +44,7 @@ func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPut
44
return nil, err
45
}
46
47
- return api.core().IpldPath(nds[0].Cid()), nil
47
+ return coreiface.IpldPath(nds[0].Cid()), nil
48
}
49
50
// 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
66
paths := n.Tree("", settings.Depth)
67
out := make([]coreiface.Path, len(paths))
68
for n, p2 := range paths {
69
- out[n], err = api.core().ParsePath(gopath.Join(p.String(), p2))
69
+ out[n], err = coreiface.ParsePath(gopath.Join(p.String(), p2))
70
if err != nil {
71
return nil, err
72
}
core/coreapi/dag_test.go
+4
-3
@@ -6,9 +6,10 @@ import (
6
"strings"
7
"testing"
8
9
- mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash"
10
-
9
+ coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
10
opt "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
11
+
12
+ mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash"
13
)
14
15
var (
@@ -72,7 +73,7 @@ func TestPath(t *testing.T) {
73
t.Error(err)
74
}
75
75
- p, err := api.ParsePath(path.Join(res.Cid().String(), "lnk"))
76
+ p, err := coreiface.ParsePath(path.Join(res.Cid().String(), "lnk"))
77
if err != nil {
78
t.Error(err)
79
}
core/coreapi/interface/coreapi.go
-10
@@ -6,7 +6,6 @@ import (
6
"context"
7
8
ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format"
9
- cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid"
9
)
10
11
// CoreAPI defines an unified interface to IPFS for Go programs
@@ -38,13 +37,4 @@ type CoreAPI interface {
37
// ResolveNode resolves the path (if not resolved already) using Unixfs
38
// resolver, gets and returns the resolved Node
39
ResolveNode(context.Context, Path) (ipld.Node, error)
41
-
42
- // ParsePath parses string path to a Path
43
- ParsePath(string) (Path, error)
44
-
45
- // IpfsPath creates new /ipfs path from the provided CID
46
- IpfsPath(*cid.Cid) ResolvedPath
47
-
48
- // IpldPath creates new /ipld path from the provided CID
49
- IpldPath(*cid.Cid) ResolvedPath
40
}
core/coreapi/interface/path.go
+87
@@ -1,9 +1,13 @@
1
package iface
2
3
import (
4
+ ipfspath "github.com/ipfs/go-ipfs/path"
5
+
6
cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid"
7
)
8
9
+//TODO: merge with ipfspath so we don't depend on it
10
+
11
// Path is a generic wrapper for paths used in the API. A path can be resolved
12
// to a CID using one of Resolve functions in the API.
13
//
@@ -87,3 +91,86 @@ type ResolvedPath interface {
91
92
Path
93
}
94
+
95
+// path implements coreiface.Path
96
+type path struct {
97
+ path ipfspath.Path
98
+}
99
+
100
+// resolvedPath implements coreiface.resolvedPath
101
+type resolvedPath struct {
102
+ path
103
+ cid *cid.Cid
104
+ root *cid.Cid
105
+ remainder string
106
+}
107
+
108
+// IpfsPath creates new /ipfs path from the provided CID
109
+func IpfsPath(c *cid.Cid) ResolvedPath {
110
+ return &resolvedPath{
111
+ path: path{ipfspath.Path("/ipfs/" + c.String())},
112
+ cid: c,
113
+ root: c,
114
+ remainder: "",
115
+ }
116
+}
117
+
118
+// IpldPath creates new /ipld path from the provided CID
119
+func IpldPath(c *cid.Cid) ResolvedPath {
120
+ return &resolvedPath{
121
+ path: path{ipfspath.Path("/ipld/" + c.String())},
122
+ cid: c,
123
+ root: c,
124
+ remainder: "",
125
+ }
126
+}
127
+
128
+// ParsePath parses string path to a Path
129
+func ParsePath(p string) (Path, error) {
130
+ pp, err := ipfspath.ParsePath(p)
131
+ if err != nil {
132
+ return nil, err
133
+ }
134
+
135
+ return &path{path: pp}, nil
136
+}
137
+
138
+// NewResolvedPath creates new ResolvedPath. This function performs no checks
139
+// and is intended to be used by resolver implementations. Incorrect inputs may
140
+// cause panics. Handle with care.
141
+func NewResolvedPath(ipath ipfspath.Path, c *cid.Cid, root *cid.Cid, remainder string) ResolvedPath {
142
+ return &resolvedPath{
143
+ path: path{ipath},
144
+ cid: c,
145
+ root: root,
146
+ remainder: remainder,
147
+ }
148
+}
149
+
150
+func (p *path) String() string {
151
+ return p.path.String()
152
+}
153
+
154
+func (p *path) Namespace() string {
155
+ if len(p.path.Segments()) < 1 {
156
+ panic("path without namespace") //this shouldn't happen under any scenario
157
+ }
158
+ return p.path.Segments()[0]
159
+}
160
+
161
+func (p *path) Mutable() bool {
162
+ //TODO: MFS: check for /local
163
+ return p.Namespace() == "ipns"
164
+}
165
+
166
+func (p *resolvedPath) Cid() *cid.Cid {
167
+ return p.cid
168
+}
169
+
170
+func (p *resolvedPath) Root() *cid.Cid {
171
+ return p.root
172
+}
173
+
174
+func (p *resolvedPath) Remainder() string {
175
+ return p.remainder
176
+}
core/coreapi/key.go
+6
-1
@@ -28,7 +28,12 @@ func (k *key) Name() string {
28
29
// Path returns the path of the key.
30
func (k *key) Path() coreiface.Path {
31
- return &path{path: ipfspath.FromString(ipfspath.Join([]string{"/ipns", k.peerId}))}
31
+ path, err := coreiface.ParsePath(ipfspath.Join([]string{"/ipns", k.peerId}))
32
+ if err != nil {
33
+ panic("error parsing path: " + err.Error())
34
+ }
35
+
36
+ return path
37
}
38
39
// Generate generates new key, stores it in the keystore under the specified
core/coreapi/name.go
+1
-1
@@ -129,7 +129,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam
129
return nil, err
130
}
131
132
- return &path{path: output}, nil
132
+ return coreiface.ParsePath(output.String())
133
}
134
135
func keylookup(n *core.IpfsNode, k string) (crypto.PrivKey, error) {
core/coreapi/object.go
+4
-4
@@ -121,7 +121,7 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj
121
return nil, err
122
}
123
124
- return api.core().IpfsPath(dagnode.Cid()), nil
124
+ return coreiface.IpfsPath(dagnode.Cid()), nil
125
}
126
127
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
218
return nil, err
219
}
220
221
- return api.core().IpfsPath(nnode.Cid()), nil
221
+ return coreiface.IpfsPath(nnode.Cid()), nil
222
}
223
224
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
244
return nil, err
245
}
246
247
- return api.core().IpfsPath(nnode.Cid()), nil
247
+ return coreiface.IpfsPath(nnode.Cid()), nil
248
}
249
250
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
281
return nil, err
282
}
283
284
- return api.core().IpfsPath(pbnd.Cid()), nil
284
+ return coreiface.IpfsPath(pbnd.Cid()), nil
285
}
286
287
func (api *ObjectAPI) core() coreiface.CoreAPI {
core/coreapi/path.go
+2
-78
@@ -16,39 +16,6 @@ import (
16
cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid"
17
)
18
19
-// path implements coreiface.Path
20
-type path struct {
21
- path ipfspath.Path
22
-}
23
-
24
-// resolvedPath implements coreiface.resolvedPath
25
-type resolvedPath struct {
26
- path
27
- cid *cid.Cid
28
- root *cid.Cid
29
- remainder string
30
-}
31
-
32
-// IpfsPath parses the path from `c`, reruns the parsed path.
33
-func (api *CoreAPI) IpfsPath(c *cid.Cid) coreiface.ResolvedPath {
34
- return &resolvedPath{
35
- path: path{ipfspath.Path("/ipfs/" + c.String())},
36
- cid: c,
37
- root: c,
38
- remainder: "",
39
- }
40
-}
41
-
42
-// IpldPath parses the path from `c`, reruns the parsed path.
43
-func (api *CoreAPI) IpldPath(c *cid.Cid) coreiface.ResolvedPath {
44
- return &resolvedPath{
45
- path: path{ipfspath.Path("/ipld/" + c.String())},
46
- cid: c,
47
- root: c,
48
- remainder: "",
49
- }
50
-}
51
-
19
// ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the
20
// resolved Node.
21
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
46
return p.(coreiface.ResolvedPath), nil
47
}
48
82
- ipath := p.(*path).path
49
+ ipath := ipfspath.Path(p.String())
50
ipath, err := core.ResolveIPNS(ctx, nsys, ipath)
51
if err == core.ErrNoNamesys {
52
return nil, coreiface.ErrOffline
@@ -113,48 +80,5 @@ func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSyste
80
return nil, err
81
}
82
116
- return &resolvedPath{
117
- path: path{ipath},
118
- cid: node.Cid(),
119
- root: root,
120
- remainder: gopath.Join(rest...),
121
- }, nil
122
-}
123
-
124
-// ParsePath parses path `p` using ipfspath parser, returns the parsed path.
125
-func (api *CoreAPI) ParsePath(p string) (coreiface.Path, error) {
126
- pp, err := ipfspath.ParsePath(p)
127
- if err != nil {
128
- return nil, err
129
- }
130
-
131
- return &path{path: pp}, nil
132
-}
133
-
134
-func (p *path) String() string {
135
- return p.path.String()
136
-}
137
-
138
-func (p *path) Namespace() string {
139
- if len(p.path.Segments()) < 1 {
140
- panic("path without namespace") //this shouldn't happen under any scenario
141
- }
142
- return p.path.Segments()[0]
143
-}
144
-
145
-func (p *path) Mutable() bool {
146
- //TODO: MFS: check for /local
147
- return p.Namespace() == "ipns"
148
-}
149
-
150
-func (p *resolvedPath) Cid() *cid.Cid {
151
- return p.cid
152
-}
153
-
154
-func (p *resolvedPath) Root() *cid.Cid {
155
- return p.root
156
-}
157
-
158
-func (p *resolvedPath) Remainder() string {
159
- return p.remainder
83
+ return coreiface.NewResolvedPath(ipath, node.Cid(), root, gopath.Join(rest...)), nil
84
}
core/coreapi/path_test.go
+5
-4
@@ -5,6 +5,7 @@ import (
5
"strings"
6
"testing"
7
8
+ coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
9
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
10
)
11
@@ -47,7 +48,7 @@ func TestPathRemainder(t *testing.T) {
48
t.Fatal(err)
49
}
50
50
- p1, err := api.ParsePath(obj.String() + "/foo/bar")
51
+ p1, err := coreiface.ParsePath(obj.String() + "/foo/bar")
52
if err != nil {
53
t.Error(err)
54
}
@@ -78,7 +79,7 @@ func TestEmptyPathRemainder(t *testing.T) {
79
t.Error("expected the resolved path to not have a remainder")
80
}
81
81
- p1, err := api.ParsePath(obj.String())
82
+ p1, err := coreiface.ParsePath(obj.String())
83
if err != nil {
84
t.Error(err)
85
}
@@ -105,7 +106,7 @@ func TestInvalidPathRemainder(t *testing.T) {
106
t.Fatal(err)
107
}
108
108
- p1, err := api.ParsePath(obj.String() + "/bar/baz")
109
+ p1, err := coreiface.ParsePath(obj.String() + "/bar/baz")
110
if err != nil {
111
t.Error(err)
112
}
@@ -133,7 +134,7 @@ func TestPathRoot(t *testing.T) {
134
t.Fatal(err)
135
}
136
136
- p1, err := api.ParsePath(obj.String() + "/foo")
137
+ p1, err := coreiface.ParsePath(obj.String() + "/foo")
138
if err != nil {
139
t.Error(err)
140
}
core/coreapi/pin.go
+2
-2
@@ -125,7 +125,7 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro
125
links, err := getLinks(ctx, root)
126
if err != nil {
127
status := &pinStatus{ok: false, cid: root}
128
- status.badNodes = []coreiface.BadPinNode{&badNode{path: api.core().IpldPath(root), err: err}}
128
+ status.badNodes = []coreiface.BadPinNode{&badNode{path: coreiface.IpldPath(root), err: err}}
129
visited[key] = status
130
return status
131
}
@@ -175,7 +175,7 @@ func (api *PinAPI) pinLsAll(typeStr string, ctx context.Context) ([]coreiface.Pi
175
for _, c := range keyList {
176
keys[c.String()] = &pinInfo{
177
pinType: typeStr,
178
- path: api.core().IpldPath(c),
178
+ path: coreiface.IpldPath(c),
179
}
180
}
181
}
core/coreapi/unixfs.go
+1
-1
@@ -25,7 +25,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.ResolvedP
25
if err != nil {
26
return nil, err
27
}
28
- return api.core().IpfsPath(c), nil
28
+ return coreiface.IpfsPath(c), nil
29
}
30
31
// Cat returns the data contained by an IPFS or IPNS object(s) at path `p`.
core/coreapi/unixfs_test.go
+10
-10
@@ -151,7 +151,7 @@ func TestCatBasic(t *testing.T) {
151
t.Fatalf("expected CID %s, got: %s", hello, p)
152
}
153
154
- helloPath, err := api.ParsePath(hello)
154
+ helloPath, err := coreiface.ParsePath(hello)
155
if err != nil {
156
t.Fatal(err)
157
}
@@ -183,7 +183,7 @@ func TestCatEmptyFile(t *testing.T) {
183
t.Fatal(err)
184
}
185
186
- emptyFilePath, err := api.ParsePath(emptyFile)
186
+ emptyFilePath, err := coreiface.ParsePath(emptyFile)
187
if err != nil {
188
t.Fatal(err)
189
}
@@ -214,18 +214,18 @@ func TestCatDir(t *testing.T) {
214
if err != nil {
215
t.Error(err)
216
}
217
- p := api.IpfsPath(edir.Cid())
217
+ p := coreiface.IpfsPath(edir.Cid())
218
219
emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir"))
220
if err != nil {
221
t.Error(err)
222
}
223
224
- if p.String() != api.IpfsPath(emptyDir.Cid()).String() {
224
+ if p.String() != coreiface.IpfsPath(emptyDir.Cid()).String() {
225
t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String())
226
}
227
228
- _, err = api.Unixfs().Cat(ctx, api.IpfsPath(emptyDir.Cid()))
228
+ _, err = api.Unixfs().Cat(ctx, coreiface.IpfsPath(emptyDir.Cid()))
229
if err != coreiface.ErrIsDir {
230
t.Fatalf("expected ErrIsDir, got: %s", err)
231
}
@@ -244,7 +244,7 @@ func TestCatNonUnixfs(t *testing.T) {
244
t.Error(err)
245
}
246
247
- _, err = api.Unixfs().Cat(ctx, api.IpfsPath(nd.Cid()))
247
+ _, err = api.Unixfs().Cat(ctx, coreiface.IpfsPath(nd.Cid()))
248
if !strings.Contains(err.Error(), "proto: required field") {
249
t.Fatalf("expected protobuf error, got: %s", err)
250
}
@@ -257,7 +257,7 @@ func TestCatOffline(t *testing.T) {
257
t.Error(err)
258
}
259
260
- p, err := api.ParsePath("/ipns/Qmfoobar")
260
+ p, err := coreiface.ParsePath("/ipns/Qmfoobar")
261
if err != nil {
262
t.Error(err)
263
}
@@ -283,7 +283,7 @@ func TestLs(t *testing.T) {
283
if len(parts) != 2 {
284
t.Errorf("unexpected path: %s", k)
285
}
286
- p, err := api.ParsePath("/ipfs/" + parts[0])
286
+ p, err := coreiface.ParsePath("/ipfs/" + parts[0])
287
if err != nil {
288
t.Error(err)
289
}
@@ -324,7 +324,7 @@ func TestLsEmptyDir(t *testing.T) {
324
t.Error(err)
325
}
326
327
- links, err := api.Unixfs().Ls(ctx, api.IpfsPath(emptyDir.Cid()))
327
+ links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(emptyDir.Cid()))
328
if err != nil {
329
t.Error(err)
330
}
@@ -352,7 +352,7 @@ func TestLsNonUnixfs(t *testing.T) {
352
t.Error(err)
353
}
354
355
- links, err := api.Unixfs().Ls(ctx, api.IpfsPath(nd.Cid()))
355
+ links, err := api.Unixfs().Ls(ctx, coreiface.IpfsPath(nd.Cid()))
356
if err != nil {
357
t.Error(err)
358
}
core/corehttp/gateway_handler.go
+2
-2
@@ -159,7 +159,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
159
ipnsHostname = true
160
}
161
162
- parsedPath, err := i.api.ParsePath(urlPath)
162
+ parsedPath, err := coreiface.ParsePath(urlPath)
163
if err != nil {
164
webError(w, "invalid ipfs path", err, http.StatusBadRequest)
165
return
@@ -287,7 +287,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
287
return
288
}
289
290
- dr, err := i.api.Unixfs().Cat(ctx, i.api.IpfsPath(ixnd.Cid()))
290
+ dr, err := i.api.Unixfs().Cat(ctx, coreiface.IpfsPath(ixnd.Cid()))
291
if err != nil {
292
internalWebError(w, err)
293
return