feat(path)!: consolidated path libraries (#334)
This commit was moved from ipfs/boxo@85c180e26664367f79de453c592020b4f279669f
Henrique Dias committed
Oct 6, 2023 at 16:04 UTC
5bac37c7351a5b70474ef2a5e426669bff86cfae
17 files changed
+216
-457
core/coreiface/block.go
+2
-3
@@ -4,9 +4,8 @@ import (
4
"context"
5
"io"
6
7
- path "github.com/ipfs/boxo/coreiface/path"
8
-
7
"github.com/ipfs/boxo/coreiface/options"
8
+ "github.com/ipfs/boxo/path"
9
)
10
11
// BlockStat contains information about a block
@@ -15,7 +14,7 @@ type BlockStat interface {
14
Size() int
15
16
// Path returns path to the block
18
- Path() path.Resolved
17
+ Path() path.ImmutablePath
18
}
19
20
// BlockAPI specifies the interface to the block layer
core/coreiface/coreapi.go
+5
-4
@@ -5,9 +5,8 @@ package iface
5
import (
6
"context"
7
8
- path "github.com/ipfs/boxo/coreiface/path"
9
-
8
"github.com/ipfs/boxo/coreiface/options"
9
+ "github.com/ipfs/boxo/path"
10
11
ipld "github.com/ipfs/go-ipld-format"
12
)
@@ -47,8 +46,10 @@ type CoreAPI interface {
46
// Routing returns an implementation of Routing API
47
Routing() RoutingAPI
48
50
- // ResolvePath resolves the path using Unixfs resolver
51
- ResolvePath(context.Context, path.Path) (path.Resolved, error)
49
+ // ResolvePath resolves the path using UnixFS resolver, and returns the resolved
50
+ // immutable path, and the remainder of the path segments that cannot be resolved
51
+ // within UnixFS.
52
+ ResolvePath(context.Context, path.Path) (path.ImmutablePath, []string, error)
53
54
// ResolveNode resolves the path (if not resolved already) using Unixfs
55
// resolver, gets and returns the resolved Node
core/coreiface/dht.go
+1
-1
@@ -3,7 +3,7 @@ package iface
3
import (
4
"context"
5
6
- "github.com/ipfs/boxo/coreiface/path"
6
+ "github.com/ipfs/boxo/path"
7
8
"github.com/ipfs/boxo/coreiface/options"
9
core/coreiface/key.go
+1
-1
@@ -3,7 +3,7 @@ package iface
3
import (
4
"context"
5
6
- "github.com/ipfs/boxo/coreiface/path"
6
+ "github.com/ipfs/boxo/path"
7
8
"github.com/ipfs/boxo/coreiface/options"
9
core/coreiface/name.go
+2
-3
@@ -4,10 +4,9 @@ import (
4
"context"
5
"errors"
6
7
- path "github.com/ipfs/boxo/coreiface/path"
8
- "github.com/ipfs/boxo/ipns"
9
-
7
"github.com/ipfs/boxo/coreiface/options"
8
+ "github.com/ipfs/boxo/ipns"
9
+ "github.com/ipfs/boxo/path"
10
)
11
12
var ErrResolveFailed = errors.New("could not resolve name")
core/coreiface/object.go
+8
-9
@@ -4,9 +4,8 @@ import (
4
"context"
5
"io"
6
7
- path "github.com/ipfs/boxo/coreiface/path"
8
-
7
"github.com/ipfs/boxo/coreiface/options"
8
+ "github.com/ipfs/boxo/path"
9
10
"github.com/ipfs/go-cid"
11
ipld "github.com/ipfs/go-ipld-format"
@@ -60,11 +59,11 @@ type ObjectChange struct {
59
60
// Before holds the link path before the change. Note that when a link is
61
// added, this will be nil.
63
- Before path.Resolved
62
+ Before path.ImmutablePath
63
64
// After holds the link path after the change. Note that when a link is
65
// removed, this will be nil.
67
- After path.Resolved
66
+ After path.ImmutablePath
67
}
68
69
// ObjectAPI specifies the interface to MerkleDAG and contains useful utilities
@@ -74,7 +73,7 @@ type ObjectAPI interface {
73
New(context.Context, ...options.ObjectNewOption) (ipld.Node, error)
74
75
// Put imports the data into merkledag
77
- Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.Resolved, error)
76
+ Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.ImmutablePath, error)
77
78
// Get returns the node for the path
79
Get(context.Context, path.Path) (ipld.Node, error)
@@ -91,16 +90,16 @@ type ObjectAPI interface {
90
// AddLink adds a link under the specified path. child path can point to a
91
// subdirectory within the patent which must be present (can be overridden
92
// with WithCreate option).
94
- AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.Resolved, error)
93
+ AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.ImmutablePath, error)
94
95
// RmLink removes a link from the node
97
- RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error)
96
+ RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error)
97
98
// AppendData appends data to the node
100
- AppendData(context.Context, path.Path, io.Reader) (path.Resolved, error)
99
+ AppendData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error)
100
101
// SetData sets the data contained in the node
103
- SetData(context.Context, path.Path, io.Reader) (path.Resolved, error)
102
+ SetData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error)
103
104
// Diff returns a set of changes needed to transform the first object into the
105
// second.
core/coreiface/path/path.go
deleted
-199
@@ -1,199 +0,0 @@
1
-package path
2
-
3
-import (
4
- "strings"
5
-
6
- ipfspath "github.com/ipfs/boxo/path"
7
- cid "github.com/ipfs/go-cid"
8
-)
9
-
10
-// Path is a generic wrapper for paths used in the API. A path can be resolved
11
-// to a CID using one of Resolve functions in the API.
12
-//
13
-// Paths must be prefixed with a valid prefix:
14
-//
15
-// * /ipfs - Immutable unixfs path (files)
16
-// * /ipld - Immutable ipld path (data)
17
-// * /ipns - Mutable names. Usually resolves to one of the immutable paths
18
-// TODO: /local (MFS)
19
-type Path interface {
20
- // String returns the path as a string.
21
- String() string
22
-
23
- // Namespace returns the first component of the path.
24
- //
25
- // For example path "/ipfs/QmHash", calling Namespace() will return "ipfs"
26
- //
27
- // Calling this method on invalid paths (IsValid() != nil) will result in
28
- // empty string
29
- Namespace() string
30
-
31
- // Mutable returns false if the data pointed to by this path in guaranteed
32
- // to not change.
33
- //
34
- // Note that resolved mutable path can be immutable.
35
- Mutable() bool
36
-
37
- // IsValid checks if this path is a valid ipfs Path, returning nil iff it is
38
- // valid
39
- IsValid() error
40
-}
41
-
42
-// Resolved is a path which was resolved to the last resolvable node.
43
-// ResolvedPaths are guaranteed to return nil from `IsValid`
44
-type Resolved interface {
45
- // Cid returns the CID of the node referenced by the path. Remainder of the
46
- // path is guaranteed to be within the node.
47
- //
48
- // Examples:
49
- // If you have 3 linked objects: QmRoot -> A -> B:
50
- //
51
- // cidB := {"foo": {"bar": 42 }}
52
- // cidA := {"B": {"/": cidB }}
53
- // cidRoot := {"A": {"/": cidA }}
54
- //
55
- // And resolve paths:
56
- //
57
- // * "/ipfs/${cidRoot}"
58
- // * Calling Cid() will return `cidRoot`
59
- // * Calling Root() will return `cidRoot`
60
- // * Calling Remainder() will return ``
61
- //
62
- // * "/ipfs/${cidRoot}/A"
63
- // * Calling Cid() will return `cidA`
64
- // * Calling Root() will return `cidRoot`
65
- // * Calling Remainder() will return ``
66
- //
67
- // * "/ipfs/${cidRoot}/A/B/foo"
68
- // * Calling Cid() will return `cidB`
69
- // * Calling Root() will return `cidRoot`
70
- // * Calling Remainder() will return `foo`
71
- //
72
- // * "/ipfs/${cidRoot}/A/B/foo/bar"
73
- // * Calling Cid() will return `cidB`
74
- // * Calling Root() will return `cidRoot`
75
- // * Calling Remainder() will return `foo/bar`
76
- Cid() cid.Cid
77
-
78
- // Root returns the CID of the root object of the path
79
- //
80
- // Example:
81
- // If you have 3 linked objects: QmRoot -> A -> B, and resolve path
82
- // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot
83
- //
84
- // For more examples see the documentation of Cid() method
85
- Root() cid.Cid
86
-
87
- // Remainder returns unresolved part of the path
88
- //
89
- // Example:
90
- // If you have 2 linked objects: QmRoot -> A, where A is a CBOR node
91
- // containing the following data:
92
- //
93
- // {"foo": {"bar": 42 }}
94
- //
95
- // When resolving "/ipld/QmRoot/A/foo/bar", Remainder will return "foo/bar"
96
- //
97
- // For more examples see the documentation of Cid() method
98
- Remainder() string
99
-
100
- Path
101
-}
102
-
103
-// path implements coreiface.Path
104
-type path struct {
105
- path string
106
-}
107
-
108
-// resolvedPath implements coreiface.resolvedPath
109
-type resolvedPath struct {
110
- path
111
- cid cid.Cid
112
- root cid.Cid
113
- remainder string
114
-}
115
-
116
-// Join appends provided segments to the base path
117
-func Join(base Path, a ...string) Path {
118
- s := strings.Join(append([]string{base.String()}, a...), "/")
119
- return &path{path: s}
120
-}
121
-
122
-// IpfsPath creates new /ipfs path from the provided CID
123
-func IpfsPath(c cid.Cid) Resolved {
124
- return &resolvedPath{
125
- path: path{"/ipfs/" + c.String()},
126
- cid: c,
127
- root: c,
128
- remainder: "",
129
- }
130
-}
131
-
132
-// IpldPath creates new /ipld path from the provided CID
133
-func IpldPath(c cid.Cid) Resolved {
134
- return &resolvedPath{
135
- path: path{"/ipld/" + c.String()},
136
- cid: c,
137
- root: c,
138
- remainder: "",
139
- }
140
-}
141
-
142
-// New parses string path to a Path
143
-func New(p string) Path {
144
- if pp, err := ipfspath.ParsePath(p); err == nil {
145
- p = pp.String()
146
- }
147
-
148
- return &path{path: p}
149
-}
150
-
151
-// NewResolvedPath creates new Resolved path. This function performs no checks
152
-// and is intended to be used by resolver implementations. Incorrect inputs may
153
-// cause panics. Handle with care.
154
-func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) Resolved {
155
- return &resolvedPath{
156
- path: path{ipath.String()},
157
- cid: c,
158
- root: root,
159
- remainder: remainder,
160
- }
161
-}
162
-
163
-func (p *path) String() string {
164
- return p.path
165
-}
166
-
167
-func (p *path) Namespace() string {
168
- ip, err := ipfspath.ParsePath(p.path)
169
- if err != nil {
170
- return ""
171
- }
172
-
173
- if len(ip.Segments()) < 1 {
174
- panic("path without namespace") // this shouldn't happen under any scenario
175
- }
176
- return ip.Segments()[0]
177
-}
178
-
179
-func (p *path) Mutable() bool {
180
- // TODO: MFS: check for /local
181
- return p.Namespace() == "ipns"
182
-}
183
-
184
-func (p *path) IsValid() error {
185
- _, err := ipfspath.ParsePath(p.path)
186
- return err
187
-}
188
-
189
-func (p *resolvedPath) Cid() cid.Cid {
190
- return p.cid
191
-}
192
-
193
-func (p *resolvedPath) Root() cid.Cid {
194
- return p.root
195
-}
196
-
197
-func (p *resolvedPath) Remainder() string {
198
- return p.remainder
199
-}
core/coreiface/pin.go
+3
-3
@@ -3,7 +3,7 @@ package iface
3
import (
4
"context"
5
6
- path "github.com/ipfs/boxo/coreiface/path"
6
+ "github.com/ipfs/boxo/path"
7
8
"github.com/ipfs/boxo/coreiface/options"
9
)
@@ -11,7 +11,7 @@ import (
11
// Pin holds information about pinned resource
12
type Pin interface {
13
// Path to the pinned object
14
- Path() path.Resolved
14
+ Path() path.ImmutablePath
15
16
// Type of the pin
17
Type() string
@@ -35,7 +35,7 @@ type PinStatus interface {
35
// BadPinNode is a node that has been marked as bad by Pin.Verify
36
type BadPinNode interface {
37
// Path is the path of the node
38
- Path() path.Resolved
38
+ Path() path.ImmutablePath
39
40
// Err is the reason why the node has been marked as bad
41
Err() error
core/coreiface/tests/block.go
+18
-19
@@ -9,9 +9,8 @@ import (
9
10
coreiface "github.com/ipfs/boxo/coreiface"
11
opt "github.com/ipfs/boxo/coreiface/options"
12
- "github.com/ipfs/boxo/coreiface/path"
12
+ "github.com/ipfs/boxo/path"
13
ipld "github.com/ipfs/go-ipld-format"
14
-
14
mh "github.com/multiformats/go-multihash"
15
)
16
@@ -68,8 +67,8 @@ func (tp *TestSuite) TestBlockPut(t *testing.T) {
67
t.Fatal(err)
68
}
69
71
- if res.Path().Cid().String() != rawCid {
72
- t.Errorf("got wrong cid: %s", res.Path().Cid().String())
70
+ if res.Path().RootCid().String() != rawCid {
71
+ t.Errorf("got wrong cid: %s", res.Path().RootCid().String())
72
}
73
}
74
@@ -88,8 +87,8 @@ func (tp *TestSuite) TestBlockPutFormatDagCbor(t *testing.T) {
87
t.Fatal(err)
88
}
89
91
- if res.Path().Cid().String() != cborCid {
92
- t.Errorf("got wrong cid: %s", res.Path().Cid().String())
90
+ if res.Path().RootCid().String() != cborCid {
91
+ t.Errorf("got wrong cid: %s", res.Path().RootCid().String())
92
}
93
}
94
@@ -108,8 +107,8 @@ func (tp *TestSuite) TestBlockPutFormatDagPb(t *testing.T) {
107
t.Fatal(err)
108
}
109
111
- if res.Path().Cid().String() != pbCid {
112
- t.Errorf("got wrong cid: %s", res.Path().Cid().String())
110
+ if res.Path().RootCid().String() != pbCid {
111
+ t.Errorf("got wrong cid: %s", res.Path().RootCid().String())
112
}
113
}
114
@@ -128,8 +127,8 @@ func (tp *TestSuite) TestBlockPutFormatV0(t *testing.T) {
127
t.Fatal(err)
128
}
129
131
- if res.Path().Cid().String() != pbCidV0 {
132
- t.Errorf("got wrong cid: %s", res.Path().Cid().String())
130
+ if res.Path().RootCid().String() != pbCidV0 {
131
+ t.Errorf("got wrong cid: %s", res.Path().RootCid().String())
132
}
133
}
134
@@ -146,8 +145,8 @@ func (tp *TestSuite) TestBlockPutCidCodecDagCbor(t *testing.T) {
145
t.Fatal(err)
146
}
147
149
- if res.Path().Cid().String() != cborCid {
150
- t.Errorf("got wrong cid: %s", res.Path().Cid().String())
148
+ if res.Path().RootCid().String() != cborCid {
149
+ t.Errorf("got wrong cid: %s", res.Path().RootCid().String())
150
}
151
}
152
@@ -164,8 +163,8 @@ func (tp *TestSuite) TestBlockPutCidCodecDagPb(t *testing.T) {
163
t.Fatal(err)
164
}
165
167
- if res.Path().Cid().String() != pbCid {
168
- t.Errorf("got wrong cid: %s", res.Path().Cid().String())
166
+ if res.Path().RootCid().String() != pbCid {
167
+ t.Errorf("got wrong cid: %s", res.Path().RootCid().String())
168
}
169
}
170
@@ -187,8 +186,8 @@ func (tp *TestSuite) TestBlockPutHash(t *testing.T) {
186
t.Fatal(err)
187
}
188
190
- if res.Path().Cid().String() != cborKCid {
191
- t.Errorf("got wrong cid: %s", res.Path().Cid().String())
189
+ if res.Path().RootCid().String() != cborKCid {
190
+ t.Errorf("got wrong cid: %s", res.Path().RootCid().String())
191
}
192
}
193
@@ -219,13 +218,13 @@ func (tp *TestSuite) TestBlockGet(t *testing.T) {
218
t.Error("didn't get correct data back")
219
}
220
222
- p := path.New("/ipfs/" + res.Path().Cid().String())
221
+ p := path.FromCid(res.Path().RootCid())
222
224
- rp, err := api.ResolvePath(ctx, p)
223
+ rp, _, err := api.ResolvePath(ctx, p)
224
if err != nil {
225
t.Fatal(err)
226
}
228
- if rp.Cid().String() != res.Path().Cid().String() {
227
+ if rp.RootCid().String() != res.Path().RootCid().String() {
228
t.Error("paths didn't match")
229
}
230
}
core/coreiface/tests/dag.go
+7
-6
@@ -3,13 +3,11 @@ package tests
3
import (
4
"context"
5
"math"
6
- gopath "path"
6
"strings"
7
"testing"
8
10
- path "github.com/ipfs/boxo/coreiface/path"
11
-
9
coreiface "github.com/ipfs/boxo/coreiface"
10
+ "github.com/ipfs/boxo/path"
11
12
ipldcbor "github.com/ipfs/go-ipld-cbor"
13
ipld "github.com/ipfs/go-ipld-format"
@@ -113,14 +111,17 @@ func (tp *TestSuite) TestDagPath(t *testing.T) {
111
t.Fatal(err)
112
}
113
116
- p := path.New(gopath.Join(nd.Cid().String(), "lnk"))
114
+ p, err := path.Join(path.FromCid(nd.Cid()), "lnk")
115
+ if err != nil {
116
+ t.Fatal(err)
117
+ }
118
118
- rp, err := api.ResolvePath(ctx, p)
119
+ rp, _, err := api.ResolvePath(ctx, p)
120
if err != nil {
121
t.Fatal(err)
122
}
123
123
- ndd, err := api.Dag().Get(ctx, rp.Cid())
124
+ ndd, err := api.Dag().Get(ctx, rp.RootCid())
125
if err != nil {
126
t.Fatal(err)
127
}
core/coreiface/tests/name.go
+11
-10
@@ -4,15 +4,14 @@ import (
4
"context"
5
"io"
6
"math/rand"
7
- gopath "path"
7
"testing"
8
"time"
9
10
coreiface "github.com/ipfs/boxo/coreiface"
11
opt "github.com/ipfs/boxo/coreiface/options"
13
- path "github.com/ipfs/boxo/coreiface/path"
12
"github.com/ipfs/boxo/files"
13
"github.com/ipfs/boxo/ipns"
14
+ "github.com/ipfs/boxo/path"
15
"github.com/stretchr/testify/require"
16
)
17
@@ -35,10 +34,6 @@ func addTestObject(ctx context.Context, api coreiface.CoreAPI) (path.Path, error
34
return api.Unixfs().Add(ctx, files.NewReaderFile(&io.LimitedReader{R: rnd, N: 4092}))
35
}
36
38
-func appendPath(p path.Path, sub string) path.Path {
39
- return path.New(gopath.Join(p.String(), sub))
40
-}
41
-
37
func (tp *TestSuite) TestPublishResolve(t *testing.T) {
38
ctx, cancel := context.WithCancel(context.Background())
39
defer cancel()
@@ -68,7 +63,10 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) {
63
64
t.Run("publishPath", func(t *testing.T) {
65
api, p := init()
71
- name, err := api.Name().Publish(ctx, appendPath(p, "/test"))
66
+ p, err := path.Join(p, "/test")
67
+ require.NoError(t, err)
68
+
69
+ name, err := api.Name().Publish(ctx, p)
70
require.NoError(t, err)
71
72
self, err := api.Key().Self(ctx)
@@ -77,7 +75,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) {
75
76
resPath, err := api.Name().Resolve(ctx, name.String(), ropts...)
77
require.NoError(t, err)
80
- require.Equal(t, p.String()+"/test", resPath.String())
78
+ require.Equal(t, p.String(), resPath.String())
79
})
80
81
t.Run("revolvePath", func(t *testing.T) {
@@ -96,7 +94,10 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) {
94
95
t.Run("publishRevolvePath", func(t *testing.T) {
96
api, p := init()
99
- name, err := api.Name().Publish(ctx, appendPath(p, "/a"))
97
+ p, err := path.Join(p, "/a")
98
+ require.NoError(t, err)
99
+
100
+ name, err := api.Name().Publish(ctx, p)
101
require.NoError(t, err)
102
103
self, err := api.Key().Self(ctx)
@@ -105,7 +106,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) {
106
107
resPath, err := api.Name().Resolve(ctx, name.String()+"/b", ropts...)
108
require.NoError(t, err)
108
- require.Equal(t, p.String()+"/a/b", resPath.String())
109
+ require.Equal(t, p.String()+"/b", resPath.String())
110
})
111
}
112
core/coreiface/tests/object.go
+7
-7
@@ -166,7 +166,7 @@ func (tp *TestSuite) TestObjectLinks(t *testing.T) {
166
t.Fatal(err)
167
}
168
169
- p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`"}]}`))
169
+ p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`"}]}`))
170
if err != nil {
171
t.Fatal(err)
172
}
@@ -180,7 +180,7 @@ func (tp *TestSuite) TestObjectLinks(t *testing.T) {
180
t.Errorf("unexpected number of links: %d", len(links))
181
}
182
183
- if links[0].Cid.String() != p1.Cid().String() {
183
+ if links[0].Cid.String() != p1.RootCid().String() {
184
t.Fatal("cids didn't batch")
185
}
186
@@ -202,7 +202,7 @@ func (tp *TestSuite) TestObjectStat(t *testing.T) {
202
t.Fatal(err)
203
}
204
205
- p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`))
205
+ p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`))
206
if err != nil {
207
t.Fatal(err)
208
}
@@ -212,7 +212,7 @@ func (tp *TestSuite) TestObjectStat(t *testing.T) {
212
t.Fatal(err)
213
}
214
215
- if stat.Cid.String() != p2.Cid().String() {
215
+ if stat.Cid.String() != p2.RootCid().String() {
216
t.Error("unexpected stat.Cid")
217
}
218
@@ -250,7 +250,7 @@ func (tp *TestSuite) TestObjectAddLink(t *testing.T) {
250
t.Fatal(err)
251
}
252
253
- p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`))
253
+ p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`))
254
if err != nil {
255
t.Fatal(err)
256
}
@@ -291,7 +291,7 @@ func (tp *TestSuite) TestObjectAddLinkCreate(t *testing.T) {
291
t.Fatal(err)
292
}
293
294
- p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`))
294
+ p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`))
295
if err != nil {
296
t.Fatal(err)
297
}
@@ -340,7 +340,7 @@ func (tp *TestSuite) TestObjectRmLink(t *testing.T) {
340
t.Fatal(err)
341
}
342
343
- p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.Cid().String()+`", "Size":3}]}`))
343
+ p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`))
344
if err != nil {
345
t.Fatal(err)
346
}
core/coreiface/tests/path.go
+82
-131
@@ -2,17 +2,26 @@ package tests
2
3
import (
4
"context"
5
+ "fmt"
6
"math"
7
"strings"
8
"testing"
9
9
- "github.com/ipfs/boxo/coreiface/path"
10
-
10
"github.com/ipfs/boxo/coreiface/options"
12
-
11
+ "github.com/ipfs/boxo/path"
12
+ "github.com/ipfs/go-cid"
13
ipldcbor "github.com/ipfs/go-ipld-cbor"
14
+ "github.com/stretchr/testify/require"
15
)
16
17
+func newIPLDPath(t *testing.T, cid cid.Cid) path.ImmutablePath {
18
+ p, err := path.NewPath(fmt.Sprintf("/%s/%s", path.IPLDNamespace, cid.String()))
19
+ require.NoError(t, err)
20
+ im, err := path.NewImmutablePath(p)
21
+ require.NoError(t, err)
22
+ return im
23
+}
24
+
25
func (tp *TestSuite) TestPath(t *testing.T) {
26
t.Run("TestMutablePath", tp.TestMutablePath)
27
t.Run("TestPathRemainder", tp.TestPathRemainder)
@@ -25,173 +34,115 @@ func (tp *TestSuite) TestPath(t *testing.T) {
34
func (tp *TestSuite) TestMutablePath(t *testing.T) {
35
ctx, cancel := context.WithCancel(context.Background())
36
defer cancel()
37
+
38
api, err := tp.makeAPI(t, ctx)
29
- if err != nil {
30
- t.Fatal(err)
31
- }
39
+ require.NoError(t, err)
40
41
blk, err := api.Block().Put(ctx, strings.NewReader(`foo`))
34
- if err != nil {
35
- t.Fatal(err)
36
- }
37
-
38
- if blk.Path().Mutable() {
39
- t.Error("expected /ipld path to be immutable")
40
- }
41
-
42
- // get self /ipns path
43
-
44
- if api.Key() == nil {
45
- t.Fatal(".Key not implemented")
46
- }
42
+ require.NoError(t, err)
43
+ require.False(t, blk.Path().Mutable())
44
+ require.NotNil(t, api.Key())
45
46
keys, err := api.Key().List(ctx)
49
- if err != nil {
50
- t.Fatal(err)
51
- }
52
-
53
- if !keys[0].Path().Mutable() {
54
- t.Error("expected self /ipns path to be mutable")
55
- }
47
+ require.NoError(t, err)
48
+ require.True(t, keys[0].Path().Mutable())
49
}
50
51
func (tp *TestSuite) TestPathRemainder(t *testing.T) {
52
ctx, cancel := context.WithCancel(context.Background())
53
defer cancel()
61
- api, err := tp.makeAPI(t, ctx)
62
- if err != nil {
63
- t.Fatal(err)
64
- }
54
66
- if api.Dag() == nil {
67
- t.Fatal(".Dag not implemented")
68
- }
55
+ api, err := tp.makeAPI(t, ctx)
56
+ require.NoError(t, err)
57
+ require.NotNil(t, api.Dag())
58
59
nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1)
71
- if err != nil {
72
- t.Fatal(err)
73
- }
74
-
75
- if err := api.Dag().Add(ctx, nd); err != nil {
76
- t.Fatal(err)
77
- }
78
-
79
- rp1, err := api.ResolvePath(ctx, path.New(nd.String()+"/foo/bar"))
80
- if err != nil {
81
- t.Fatal(err)
82
- }
83
-
84
- if rp1.Remainder() != "foo/bar" {
85
- t.Error("expected to get path remainder")
86
- }
60
+ require.NoError(t, err)
61
+
62
+ err = api.Dag().Add(ctx, nd)
63
+ require.NoError(t, err)
64
+
65
+ p, err := path.Join(path.FromCid(nd.Cid()), "foo", "bar")
66
+ require.NoError(t, err)
67
+
68
+ _, remainder, err := api.ResolvePath(ctx, p)
69
+ require.NoError(t, err)
70
+ require.Equal(t, "/foo/bar", path.SegmentsToString(remainder...))
71
}
72
73
func (tp *TestSuite) TestEmptyPathRemainder(t *testing.T) {
74
ctx, cancel := context.WithCancel(context.Background())
75
defer cancel()
92
- api, err := tp.makeAPI(t, ctx)
93
- if err != nil {
94
- t.Fatal(err)
95
- }
76
97
- if api.Dag() == nil {
98
- t.Fatal(".Dag not implemented")
99
- }
77
+ api, err := tp.makeAPI(t, ctx)
78
+ require.NoError(t, err)
79
+ require.NotNil(t, api.Dag())
80
81
nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1)
102
- if err != nil {
103
- t.Fatal(err)
104
- }
105
-
106
- if err := api.Dag().Add(ctx, nd); err != nil {
107
- t.Fatal(err)
108
- }
109
-
110
- rp1, err := api.ResolvePath(ctx, path.New(nd.Cid().String()))
111
- if err != nil {
112
- t.Fatal(err)
113
- }
114
-
115
- if rp1.Remainder() != "" {
116
- t.Error("expected the resolved path to not have a remainder")
117
- }
82
+ require.NoError(t, err)
83
+
84
+ err = api.Dag().Add(ctx, nd)
85
+ require.NoError(t, err)
86
+
87
+ _, remainder, err := api.ResolvePath(ctx, path.FromCid(nd.Cid()))
88
+ require.NoError(t, err)
89
+ require.Empty(t, remainder)
90
}
91
92
func (tp *TestSuite) TestInvalidPathRemainder(t *testing.T) {
93
ctx, cancel := context.WithCancel(context.Background())
94
defer cancel()
123
- api, err := tp.makeAPI(t, ctx)
124
- if err != nil {
125
- t.Fatal(err)
126
- }
95
128
- if api.Dag() == nil {
129
- t.Fatal(".Dag not implemented")
130
- }
96
+ api, err := tp.makeAPI(t, ctx)
97
+ require.NoError(t, err)
98
+ require.NotNil(t, api.Dag())
99
100
nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"bar": "baz"}}`), math.MaxUint64, -1)
133
- if err != nil {
134
- t.Fatal(err)
135
- }
136
-
137
- if err := api.Dag().Add(ctx, nd); err != nil {
138
- t.Fatal(err)
139
- }
140
-
141
- _, err = api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/bar/baz"))
142
- if err == nil || !strings.Contains(err.Error(), `no link named "bar"`) {
143
- t.Fatalf("unexpected error: %s", err)
144
- }
101
+ require.NoError(t, err)
102
+
103
+ err = api.Dag().Add(ctx, nd)
104
+ require.NoError(t, err)
105
+
106
+ p, err := path.Join(newIPLDPath(t, nd.Cid()), "/bar/baz")
107
+ require.NoError(t, err)
108
+
109
+ _, _, err = api.ResolvePath(ctx, p)
110
+ require.NotNil(t, err)
111
+ require.ErrorContains(t, err, `no link named "bar"`)
112
}
113
114
func (tp *TestSuite) TestPathRoot(t *testing.T) {
115
ctx, cancel := context.WithCancel(context.Background())
116
defer cancel()
150
- api, err := tp.makeAPI(t, ctx)
151
- if err != nil {
152
- t.Fatal(err)
153
- }
117
155
- if api.Block() == nil {
156
- t.Fatal(".Block not implemented")
157
- }
118
+ api, err := tp.makeAPI(t, ctx)
119
+ require.NoError(t, err)
120
+ require.NotNil(t, api.Block())
121
122
blk, err := api.Block().Put(ctx, strings.NewReader(`foo`), options.Block.Format("raw"))
160
- if err != nil {
161
- t.Fatal(err)
162
- }
163
-
164
- if api.Dag() == nil {
165
- t.Fatal(".Dag not implemented")
166
- }
167
-
168
- nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"/": "`+blk.Path().Cid().String()+`"}}`), math.MaxUint64, -1)
169
- if err != nil {
170
- t.Fatal(err)
171
- }
172
-
173
- if err := api.Dag().Add(ctx, nd); err != nil {
174
- t.Fatal(err)
175
- }
176
-
177
- rp, err := api.ResolvePath(ctx, path.New("/ipld/"+nd.Cid().String()+"/foo"))
178
- if err != nil {
179
- t.Fatal(err)
180
- }
181
-
182
- if rp.Root().String() != nd.Cid().String() {
183
- t.Error("unexpected path root")
184
- }
185
-
186
- if rp.Cid().String() != blk.Path().Cid().String() {
187
- t.Error("unexpected path cid")
188
- }
123
+ require.NoError(t, err)
124
+ require.NotNil(t, api.Dag())
125
+
126
+ nd, err := ipldcbor.FromJSON(strings.NewReader(`{"foo": {"/": "`+blk.Path().RootCid().String()+`"}}`), math.MaxUint64, -1)
127
+ require.NoError(t, err)
128
+
129
+ err = api.Dag().Add(ctx, nd)
130
+ require.NoError(t, err)
131
+
132
+ p, err := path.Join(newIPLDPath(t, nd.Cid()), "/foo")
133
+ require.NoError(t, err)
134
+
135
+ rp, _, err := api.ResolvePath(ctx, p)
136
+ require.NoError(t, err)
137
+ require.Equal(t, rp.RootCid().String(), blk.Path().RootCid().String())
138
}
139
140
func (tp *TestSuite) TestPathJoin(t *testing.T) {
192
- p1 := path.New("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz")
141
+ p1, err := path.NewPath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz")
142
+ require.NoError(t, err)
143
+
144
+ p2, err := path.Join(p1, "foo")
145
+ require.NoError(t, err)
146
194
- if path.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" {
195
- t.Error("unexpected path")
196
- }
147
+ require.Equal(t, "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo", p2.String())
148
}
core/coreiface/tests/pin.go
+48
-41
@@ -8,8 +8,7 @@ import (
8
9
iface "github.com/ipfs/boxo/coreiface"
10
opt "github.com/ipfs/boxo/coreiface/options"
11
- "github.com/ipfs/boxo/coreiface/path"
12
-
11
+ "github.com/ipfs/boxo/path"
12
"github.com/ipfs/go-cid"
13
ipldcbor "github.com/ipfs/go-ipld-cbor"
14
ipld "github.com/ipfs/go-ipld-format"
@@ -77,7 +76,7 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) {
76
t.Errorf("unexpected pin list len: %d", len(list))
77
}
78
80
- if list[0].Path().Cid().String() != p.Cid().String() {
79
+ if list[0].Path().RootCid().String() != p.RootCid().String() {
80
t.Error("paths don't match")
81
}
82
@@ -120,12 +119,12 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) {
119
t.Fatal(err)
120
}
121
123
- nd2, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p0.Cid().String()+`"}}`), math.MaxUint64, -1)
122
+ nd2, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p0.RootCid().String()+`"}}`), math.MaxUint64, -1)
123
if err != nil {
124
t.Fatal(err)
125
}
126
128
- nd3, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p1.Cid().String()+`"}}`), math.MaxUint64, -1)
127
+ nd3, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+p1.RootCid().String()+`"}}`), math.MaxUint64, -1)
128
if err != nil {
129
t.Fatal(err)
130
}
@@ -134,12 +133,12 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) {
133
t.Fatal(err)
134
}
135
137
- err = api.Pin().Add(ctx, path.IpldPath(nd2.Cid()))
136
+ err = api.Pin().Add(ctx, path.FromCid(nd2.Cid()))
137
if err != nil {
138
t.Fatal(err)
139
}
140
142
- err = api.Pin().Add(ctx, path.IpldPath(nd3.Cid()), opt.Pin.Recursive(false))
141
+ err = api.Pin().Add(ctx, path.FromCid(nd3.Cid()), opt.Pin.Recursive(false))
142
if err != nil {
143
t.Fatal(err)
144
}
@@ -162,8 +161,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) {
161
t.Errorf("unexpected pin list len: %d", len(list))
162
}
163
165
- if list[0].Path().String() != path.IpldPath(nd3.Cid()).String() {
166
- t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd3.Cid()).String())
164
+ if list[0].Path().String() != path.FromCid(nd3.Cid()).String() {
165
+ t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.FromCid(nd3.Cid()).String())
166
}
167
168
list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Recursive()))
@@ -175,8 +174,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) {
174
t.Errorf("unexpected pin list len: %d", len(list))
175
}
176
178
- if list[0].Path().String() != path.IpldPath(nd2.Cid()).String() {
179
- t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd2.Cid()).String())
177
+ if list[0].Path().String() != path.FromCid(nd2.Cid()).String() {
178
+ t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.FromCid(nd2.Cid()).String())
179
}
180
181
list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Indirect()))
@@ -188,8 +187,8 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) {
187
t.Errorf("unexpected pin list len: %d", len(list))
188
}
189
191
- if list[0].Path().Cid().String() != p0.Cid().String() {
192
- t.Errorf("unexpected path, %s != %s", list[0].Path().Cid().String(), p0.Cid().String())
190
+ if list[0].Path().RootCid().String() != p0.RootCid().String() {
191
+ t.Errorf("unexpected path, %s != %s", list[0].Path().RootCid().String(), p0.RootCid().String())
192
}
193
194
res, err := api.Pin().Verify(ctx)
@@ -259,12 +258,12 @@ func (tp *TestSuite) TestPinLsIndirect(t *testing.T) {
258
259
leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "foo")
260
262
- err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()))
261
+ err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid()))
262
if err != nil {
263
t.Fatal(err)
264
}
265
267
- err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false))
266
+ err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false))
267
if err != nil {
268
t.Fatal(err)
269
}
@@ -293,12 +292,12 @@ func (tp *TestSuite) TestPinLsPredenceRecursiveIndirect(t *testing.T) {
292
// Test recursive > indirect
293
leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "recursive > indirect")
294
296
- err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()))
295
+ err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid()))
296
if err != nil {
297
t.Fatal(err)
298
}
299
301
- err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()))
300
+ err = api.Pin().Add(ctx, path.FromCid(parent.Cid()))
301
if err != nil {
302
t.Fatal(err)
303
}
@@ -317,12 +316,12 @@ func (tp *TestSuite) TestPinLsPrecedenceDirectIndirect(t *testing.T) {
316
// Test direct > indirect
317
leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "direct > indirect")
318
320
- err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()))
319
+ err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid()))
320
if err != nil {
321
t.Fatal(err)
322
}
323
325
- err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false))
324
+ err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false))
325
if err != nil {
326
t.Fatal(err)
327
}
@@ -341,24 +340,24 @@ func (tp *TestSuite) TestPinLsPrecedenceRecursiveDirect(t *testing.T) {
340
// Test recursive > direct
341
leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "recursive + direct = error")
342
344
- err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()))
343
+ err = api.Pin().Add(ctx, path.FromCid(parent.Cid()))
344
if err != nil {
345
t.Fatal(err)
346
}
347
349
- err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(false))
348
+ err = api.Pin().Add(ctx, path.FromCid(parent.Cid()), opt.Pin.Recursive(false))
349
if err == nil {
350
t.Fatal("expected error directly pinning a recursively pinned node")
351
}
352
353
assertPinTypes(t, ctx, api, []cidContainer{parent}, []cidContainer{}, []cidContainer{leaf})
354
356
- err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()), opt.Pin.Recursive(false))
355
+ err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid()), opt.Pin.Recursive(false))
356
if err != nil {
357
t.Fatal(err)
358
}
359
361
- err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()))
360
+ err = api.Pin().Add(ctx, path.FromCid(grandparent.Cid()))
361
if err != nil {
362
t.Fatal(err)
363
}
@@ -376,40 +375,48 @@ func (tp *TestSuite) TestPinIsPinned(t *testing.T) {
375
376
leaf, parent, grandparent := getThreeChainedNodes(t, ctx, api, "foofoo")
377
379
- assertNotPinned(t, ctx, api, path.IpldPath(grandparent.Cid()))
380
- assertNotPinned(t, ctx, api, path.IpldPath(parent.Cid()))
381
- assertNotPinned(t, ctx, api, path.IpldPath(leaf.Cid()))
378
+ assertNotPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid()))
379
+ assertNotPinned(t, ctx, api, newIPLDPath(t, parent.Cid()))
380
+ assertNotPinned(t, ctx, api, newIPLDPath(t, leaf.Cid()))
381
383
- err = api.Pin().Add(ctx, path.IpldPath(parent.Cid()), opt.Pin.Recursive(true))
382
+ err = api.Pin().Add(ctx, newIPLDPath(t, parent.Cid()), opt.Pin.Recursive(true))
383
if err != nil {
384
t.Fatal(err)
385
}
386
388
- assertNotPinned(t, ctx, api, path.IpldPath(grandparent.Cid()))
389
- assertIsPinned(t, ctx, api, path.IpldPath(parent.Cid()), "recursive")
390
- assertIsPinned(t, ctx, api, path.IpldPath(leaf.Cid()), "indirect")
387
+ assertNotPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid()))
388
+ assertIsPinned(t, ctx, api, newIPLDPath(t, parent.Cid()), "recursive")
389
+ assertIsPinned(t, ctx, api, newIPLDPath(t, leaf.Cid()), "indirect")
390
392
- err = api.Pin().Add(ctx, path.IpldPath(grandparent.Cid()), opt.Pin.Recursive(false))
391
+ err = api.Pin().Add(ctx, newIPLDPath(t, grandparent.Cid()), opt.Pin.Recursive(false))
392
if err != nil {
393
t.Fatal(err)
394
}
395
397
- assertIsPinned(t, ctx, api, path.IpldPath(grandparent.Cid()), "direct")
398
- assertIsPinned(t, ctx, api, path.IpldPath(parent.Cid()), "recursive")
399
- assertIsPinned(t, ctx, api, path.IpldPath(leaf.Cid()), "indirect")
396
+ assertIsPinned(t, ctx, api, newIPLDPath(t, grandparent.Cid()), "direct")
397
+ assertIsPinned(t, ctx, api, newIPLDPath(t, parent.Cid()), "recursive")
398
+ assertIsPinned(t, ctx, api, newIPLDPath(t, leaf.Cid()), "indirect")
399
}
400
401
type cidContainer interface {
402
Cid() cid.Cid
403
}
404
405
+type immutablePathCidContainer struct {
406
+ path.ImmutablePath
407
+}
408
+
409
+func (i immutablePathCidContainer) Cid() cid.Cid {
410
+ return i.RootCid()
411
+}
412
+
413
func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI, leafData string) (cidContainer, cidContainer, cidContainer) {
414
leaf, err := api.Unixfs().Add(ctx, strFile(leafData)())
415
if err != nil {
416
t.Fatal(err)
417
}
418
412
- parent, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+leaf.Cid().String()+`"}}`), math.MaxUint64, -1)
419
+ parent, err := ipldcbor.FromJSON(strings.NewReader(`{"lnk": {"/": "`+leaf.RootCid().String()+`"}}`), math.MaxUint64, -1)
420
if err != nil {
421
t.Fatal(err)
422
}
@@ -423,7 +430,7 @@ func getThreeChainedNodes(t *testing.T, ctx context.Context, api iface.CoreAPI,
430
t.Fatal(err)
431
}
432
426
- return leaf, parent, grandparent
433
+ return immutablePathCidContainer{leaf}, parent, grandparent
434
}
435
436
func assertPinTypes(t *testing.T, ctx context.Context, api iface.CoreAPI, recusive, direct, indirect []cidContainer) {
@@ -466,7 +473,7 @@ func assertPinCids(t *testing.T, pins []iface.Pin, cids ...cidContainer) {
473
474
valid := true
475
for _, p := range pins {
469
- c := p.Path().Cid()
476
+ c := p.Path().RootCid()
477
if cSet.Has(c) {
478
cSet.Remove(c)
479
} else {
@@ -480,7 +487,7 @@ func assertPinCids(t *testing.T, pins []iface.Pin, cids ...cidContainer) {
487
if !valid {
488
pinStrs := make([]string, len(pins))
489
for i, p := range pins {
483
- pinStrs[i] = p.Path().Cid().String()
490
+ pinStrs[i] = p.Path().RootCid().String()
491
}
492
pathStrs := make([]string, len(cids))
493
for i, c := range cids {
@@ -511,13 +518,13 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core
518
}
519
520
for _, p := range allPins {
514
- if !all.Visit(p.Path().Cid()) {
521
+ if !all.Visit(p.Path().RootCid()) {
522
t.Fatalf("pin ls returned the same cid multiple times")
523
}
524
525
typeStr := p.Type()
526
if typeSet, ok := typeMap[p.Type()]; ok {
520
- typeSet.Add(p.Path().Cid())
527
+ typeSet.Add(p.Path().RootCid())
528
} else {
529
t.Fatalf("unknown pin type: %s", typeStr)
530
}
@@ -538,7 +545,7 @@ func assertPinLsAllConsistency(t *testing.T, ctx context.Context, api iface.Core
545
t.Fatalf("returned wrong pin type: expected %s, got %s", typeStr, pinType)
546
}
547
541
- if c := p.Path().Cid(); !pinProps.Has(c) {
548
+ if c := p.Path().RootCid(); !pinProps.Has(c) {
549
t.Fatalf("%s expected to be in pin ls all as type %s", c.String(), typeStr)
550
}
551
}
core/coreiface/tests/routing.go
+1
-1
@@ -7,8 +7,8 @@ import (
7
8
iface "github.com/ipfs/boxo/coreiface"
9
"github.com/ipfs/boxo/coreiface/options"
10
- "github.com/ipfs/boxo/coreiface/path"
10
"github.com/ipfs/boxo/ipns"
11
+ "github.com/ipfs/boxo/path"
12
"github.com/stretchr/testify/require"
13
)
14
core/coreiface/tests/unixfs.go
+15
-13
@@ -14,10 +14,9 @@ import (
14
"sync"
15
"testing"
16
17
- "github.com/ipfs/boxo/coreiface/path"
18
-
17
coreiface "github.com/ipfs/boxo/coreiface"
18
"github.com/ipfs/boxo/coreiface/options"
19
+ "github.com/ipfs/boxo/path"
20
21
"github.com/ipfs/boxo/files"
22
mdag "github.com/ipfs/boxo/ipld/merkledag"
@@ -106,12 +105,12 @@ func (tp *TestSuite) TestAdd(t *testing.T) {
105
t.Fatal(err)
106
}
107
109
- p := func(h string) path.Resolved {
108
+ p := func(h string) path.ImmutablePath {
109
c, err := cid.Parse(h)
110
if err != nil {
111
t.Fatal(err)
112
}
114
- return path.IpfsPath(c)
113
+ return path.FromCid(c)
114
}
115
116
rf, err := os.CreateTemp(os.TempDir(), "unixfs-add-real")
@@ -410,7 +409,7 @@ func (tp *TestSuite) TestAdd(t *testing.T) {
409
}
410
411
if expected[0].Path != nil && event.Path != nil {
413
- if expected[0].Path.Cid().String() != event.Path.Cid().String() {
412
+ if expected[0].Path.RootCid().String() != event.Path.RootCid().String() {
413
t.Errorf("Event.Hash didn't match, %s != %s", expected[0].Path, event.Path)
414
}
415
} else if event.Path != expected[0].Path {
@@ -553,7 +552,7 @@ func (tp *TestSuite) TestAddPinned(t *testing.T) {
552
t.Fatalf("expected 1 pin, got %d", len(pins))
553
}
554
556
- if pins[0].Path().String() != "/ipld/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" {
555
+ if pins[0].Path().String() != "/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" {
556
t.Fatalf("got unexpected pin: %s", pins[0].Path().String())
557
}
558
}
@@ -597,7 +596,10 @@ func (tp *TestSuite) TestGetEmptyFile(t *testing.T) {
596
t.Fatal(err)
597
}
598
600
- emptyFilePath := path.New(emptyFile)
599
+ emptyFilePath, err := path.NewPath(emptyFile)
600
+ if err != nil {
601
+ t.Fatal(err)
602
+ }
603
604
r, err := api.Unixfs().Get(ctx, emptyFilePath)
605
if err != nil {
@@ -626,18 +628,18 @@ func (tp *TestSuite) TestGetDir(t *testing.T) {
628
if err != nil {
629
t.Fatal(err)
630
}
629
- p := path.IpfsPath(edir.Cid())
631
+ p := path.FromCid(edir.Cid())
632
633
emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir"))
634
if err != nil {
635
t.Fatal(err)
636
}
637
636
- if p.String() != path.IpfsPath(emptyDir.Cid()).String() {
638
+ if p.String() != path.FromCid(emptyDir.Cid()).String() {
639
t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String())
640
}
641
640
- r, err := api.Unixfs().Get(ctx, path.IpfsPath(emptyDir.Cid()))
642
+ r, err := api.Unixfs().Get(ctx, path.FromCid(emptyDir.Cid()))
643
if err != nil {
644
t.Fatal(err)
645
}
@@ -661,7 +663,7 @@ func (tp *TestSuite) TestGetNonUnixfs(t *testing.T) {
663
t.Fatal(err)
664
}
665
664
- _, err = api.Unixfs().Get(ctx, path.IpfsPath(nd.Cid()))
666
+ _, err = api.Unixfs().Get(ctx, path.FromCid(nd.Cid()))
667
if !strings.Contains(err.Error(), "proto: required field") {
668
t.Fatalf("expected protobuf error, got: %s", err)
669
}
@@ -787,7 +789,7 @@ func (tp *TestSuite) TestLsEmptyDir(t *testing.T) {
789
t.Fatal(err)
790
}
791
790
- links, err := api.Unixfs().Ls(ctx, path.IpfsPath(emptyDir.Cid()))
792
+ links, err := api.Unixfs().Ls(ctx, path.FromCid(emptyDir.Cid()))
793
if err != nil {
794
t.Fatal(err)
795
}
@@ -816,7 +818,7 @@ func (tp *TestSuite) TestLsNonUnixfs(t *testing.T) {
818
t.Fatal(err)
819
}
820
819
- links, err := api.Unixfs().Ls(ctx, path.IpfsPath(nd.Cid()))
821
+ links, err := api.Unixfs().Ls(ctx, path.FromCid(nd.Cid()))
822
if err != nil {
823
t.Fatal(err)
824
}
core/coreiface/unixfs.go
+5
-6
@@ -4,17 +4,16 @@ import (
4
"context"
5
6
"github.com/ipfs/boxo/coreiface/options"
7
- path "github.com/ipfs/boxo/coreiface/path"
8
-
7
"github.com/ipfs/boxo/files"
8
+ "github.com/ipfs/boxo/path"
9
"github.com/ipfs/go-cid"
10
)
11
12
type AddEvent struct {
13
Name string
15
- Path path.Resolved `json:",omitempty"`
16
- Bytes int64 `json:",omitempty"`
17
- Size string `json:",omitempty"`
14
+ Path path.ImmutablePath `json:",omitempty"`
15
+ Bytes int64 `json:",omitempty"`
16
+ Size string `json:",omitempty"`
17
}
18
19
// FileType is an enum of possible UnixFS file types.
@@ -66,7 +65,7 @@ type UnixfsAPI interface {
65
// Add imports the data from the reader into merkledag file
66
//
67
// TODO: a long useful comment on how to use this for many different scenarios
69
- Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.Resolved, error)
68
+ Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.ImmutablePath, error)
69
70
// Get returns a read-only handle to a file tree referenced by a path
71
//