@cryptotaxi247 / kubo / commits / 5bac37c73

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 //