@cryptotaxi247 / kubo / commits / a7c651849

feat: path consolidation (#10063)

Henrique Dias committed Oct 6, 2023 at 16:14 UTC a7c65184976e8717ac23d7efaa5b0d477ad15deb
70 files changed +605 -378
assets/assets.go
+3 -3
@@ -9,8 +9,8 @@ import (
9 "github.com/ipfs/kubo/core/coreapi"
10
11 options "github.com/ipfs/boxo/coreiface/options"
12 - "github.com/ipfs/boxo/coreiface/path"
12 "github.com/ipfs/boxo/files"
13 + "github.com/ipfs/boxo/path"
14 cid "github.com/ipfs/go-cid"
15 )
16
@@ -44,7 +44,7 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) {
44 return cid.Cid{}, err
45 }
46
47 - basePath := path.IpfsPath(dirb.Cid())
47 + basePath := path.FromCid(dirb.Cid())
48
49 for _, p := range l {
50 d, err := Asset.ReadFile(p)
@@ -69,5 +69,5 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) {
69 return cid.Cid{}, err
70 }
71
72 - return basePath.Cid(), nil
72 + return basePath.RootCid(), nil
73 }
client/rpc/api_test.go
+11 -3
@@ -12,8 +12,8 @@ import (
12 "time"
13
14 iface "github.com/ipfs/boxo/coreiface"
15 - "github.com/ipfs/boxo/coreiface/path"
15 "github.com/ipfs/boxo/coreiface/tests"
16 + "github.com/ipfs/boxo/path"
17 "github.com/ipfs/kubo/test/cli/harness"
18 ma "github.com/multiformats/go-multiaddr"
19 "go.uber.org/multierr"
@@ -70,7 +70,11 @@ func (np NodeProvider) MakeAPISwarm(t *testing.T, ctx context.Context, fullIdent
70 apis[i] = api
71
72 // empty node is pinned even with --empty-repo, we don't want that
73 - emptyNode := path.New("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn")
73 + emptyNode, err := path.NewPath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn")
74 + if err != nil {
75 + return err
76 + }
77 +
78 if err := api.Pin().Rm(ctx, emptyNode); err != nil {
79 return err
80 }
@@ -126,7 +130,11 @@ func Test_NewURLApiWithClient_With_Headers(t *testing.T) {
130 t.Fatal(err)
131 }
132 api.Headers.Set(headerToTest, expectedHeaderValue)
129 - if err := api.Pin().Rm(context.Background(), path.New("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv")); err != nil {
133 + p, err := path.NewPath("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv")
134 + if err != nil {
135 + t.Fatal(err)
136 + }
137 + if err := api.Pin().Rm(context.Background(), p); err != nil {
138 t.Fatal(err)
139 }
140 }
client/rpc/apifile.go
+4 -4
@@ -6,9 +6,9 @@ import (
6 "fmt"
7 "io"
8
9 - "github.com/ipfs/boxo/coreiface/path"
9 "github.com/ipfs/boxo/files"
10 unixfs "github.com/ipfs/boxo/ipld/unixfs"
11 + "github.com/ipfs/boxo/path"
12 "github.com/ipfs/go-cid"
13 )
14
@@ -17,7 +17,7 @@ const forwardSeekLimit = 1 << 14 // 16k
17 func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) {
18 if p.Mutable() { // use resolved path in case we are dealing with IPNS / MFS
19 var err error
20 - p, err = api.core().ResolvePath(ctx, p)
20 + p, _, err = api.core().ResolvePath(ctx, p)
21 if err != nil {
22 return nil, err
23 }
@@ -195,13 +195,13 @@ func (it *apiIter) Next() bool {
195
196 switch it.cur.Type {
197 case unixfs.THAMTShard, unixfs.TMetadata, unixfs.TDirectory:
198 - it.curFile, err = it.core.getDir(it.ctx, path.IpfsPath(c), int64(it.cur.Size))
198 + it.curFile, err = it.core.getDir(it.ctx, path.FromCid(c), int64(it.cur.Size))
199 if err != nil {
200 it.err = err
201 return false
202 }
203 case unixfs.TFile:
204 - it.curFile, err = it.core.getFile(it.ctx, path.IpfsPath(c), int64(it.cur.Size))
204 + it.curFile, err = it.core.getFile(it.ctx, path.FromCid(c), int64(it.cur.Size))
205 if err != nil {
206 it.err = err
207 return false
client/rpc/block.go
+3 -3
@@ -8,7 +8,7 @@ import (
8
9 iface "github.com/ipfs/boxo/coreiface"
10 caopts "github.com/ipfs/boxo/coreiface/options"
11 - "github.com/ipfs/boxo/coreiface/path"
11 + "github.com/ipfs/boxo/path"
12 "github.com/ipfs/go-cid"
13 mc "github.com/multiformats/go-multicodec"
14 mh "github.com/multiformats/go-multihash"
@@ -27,8 +27,8 @@ func (s *blockStat) Size() int {
27 return s.BSize
28 }
29
30 -func (s *blockStat) Path() path.Resolved {
31 - return path.IpldPath(s.cid)
30 +func (s *blockStat) Path() path.ImmutablePath {
31 + return path.FromCid(s.cid)
32 }
33
34 func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) {
client/rpc/dag.go
+6 -6
@@ -7,8 +7,8 @@ import (
7 "io"
8
9 "github.com/ipfs/boxo/coreiface/options"
10 - "github.com/ipfs/boxo/coreiface/path"
11 - "github.com/ipfs/go-block-format"
10 + "github.com/ipfs/boxo/path"
11 + blocks "github.com/ipfs/go-block-format"
12 "github.com/ipfs/go-cid"
13 format "github.com/ipfs/go-ipld-format"
14 multicodec "github.com/multiformats/go-multicodec"
@@ -21,7 +21,7 @@ type (
21 )
22
23 func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) {
24 - r, err := api.core().Block().Get(ctx, path.IpldPath(c))
24 + r, err := api.core().Block().Get(ctx, path.FromCid(c))
25 if err != nil {
26 return nil, err
27 }
@@ -79,8 +79,8 @@ func (api *httpNodeAdder) add(ctx context.Context, nd format.Node, pin bool) err
79 if err != nil {
80 return err
81 }
82 - if !stat.Path().Cid().Equals(c) {
83 - return fmt.Errorf("cids didn't match - local %s, remote %s", c.String(), stat.Path().Cid().String())
82 + if !stat.Path().RootCid().Equals(c) {
83 + return fmt.Errorf("cids didn't match - local %s, remote %s", c.String(), stat.Path().RootCid().String())
84 }
85 return nil
86 }
@@ -116,7 +116,7 @@ func (api *HttpDagServ) Pinning() format.NodeAdder {
116 }
117
118 func (api *HttpDagServ) Remove(ctx context.Context, c cid.Cid) error {
119 - return api.core().Block().Rm(ctx, path.IpldPath(c)) // TODO: should we force rm?
119 + return api.core().Block().Rm(ctx, path.FromCid(c)) // TODO: should we force rm?
120 }
121
122 func (api *HttpDagServ) RemoveMany(ctx context.Context, cids []cid.Cid) error {
client/rpc/dht.go
+5 -5
@@ -5,7 +5,7 @@ import (
5 "encoding/json"
6
7 caopts "github.com/ipfs/boxo/coreiface/options"
8 - "github.com/ipfs/boxo/coreiface/path"
8 + "github.com/ipfs/boxo/path"
9 "github.com/libp2p/go-libp2p/core/peer"
10 "github.com/libp2p/go-libp2p/core/routing"
11 )
@@ -42,12 +42,12 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt
42 return nil, err
43 }
44
45 - rp, err := api.core().ResolvePath(ctx, p)
45 + rp, _, err := api.core().ResolvePath(ctx, p)
46 if err != nil {
47 return nil, err
48 }
49
50 - resp, err := api.core().Request("dht/findprovs", rp.Cid().String()).
50 + resp, err := api.core().Request("dht/findprovs", rp.RootCid().String()).
51 Option("num-providers", options.NumProviders).
52 Send(ctx)
53 if err != nil {
@@ -98,12 +98,12 @@ func (api *DhtAPI) Provide(ctx context.Context, p path.Path, opts ...caopts.DhtP
98 return err
99 }
100
101 - rp, err := api.core().ResolvePath(ctx, p)
101 + rp, _, err := api.core().ResolvePath(ctx, p)
102 if err != nil {
103 return err
104 }
105
106 - return api.core().Request("dht/provide", rp.Cid().String()).
106 + return api.core().Request("dht/provide", rp.RootCid().String()).
107 Option("recursive", options.Recursive).
108 Exec(ctx, nil)
109 }
client/rpc/key.go
+47 -27
@@ -6,31 +6,50 @@ import (
6
7 iface "github.com/ipfs/boxo/coreiface"
8 caopts "github.com/ipfs/boxo/coreiface/options"
9 - "github.com/ipfs/boxo/coreiface/path"
9 + "github.com/ipfs/boxo/ipns"
10 + "github.com/ipfs/boxo/path"
11 "github.com/libp2p/go-libp2p/core/peer"
12 )
13
14 type KeyAPI HttpApi
15
15 -type keyOutput struct {
16 - JName string `json:"Name"`
17 - Id string
16 +type key struct {
17 + name string
18 + pid peer.ID
19 + path path.Path
20 +}
21 +
22 +func newKey(name, pidStr string) (*key, error) {
23 + pid, err := peer.Decode(pidStr)
24 + if err != nil {
25 + return nil, err
26 + }
27
19 - pid peer.ID
28 + path, err := path.NewPath("/ipns/" + ipns.NameFromPeer(pid).String())
29 + if err != nil {
30 + return nil, err
31 + }
32 +
33 + return &key{name: name, pid: pid, path: path}, nil
34 }
35
22 -func (k *keyOutput) Name() string {
23 - return k.JName
36 +func (k *key) Name() string {
37 + return k.name
38 }
39
26 -func (k *keyOutput) Path() path.Path {
27 - return path.New("/ipns/" + k.Id)
40 +func (k *key) Path() path.Path {
41 + return k.path
42 }
43
30 -func (k *keyOutput) ID() peer.ID {
44 +func (k *key) ID() peer.ID {
45 return k.pid
46 }
47
48 +type keyOutput struct {
49 + Name string
50 + Id string
51 +}
52 +
53 func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (iface.Key, error) {
54 options, err := caopts.KeyGenerateOptions(opts...)
55 if err != nil {
@@ -45,8 +64,8 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
64 if err != nil {
65 return nil, err
66 }
48 - out.pid, err = peer.Decode(out.Id)
49 - return &out, err
67 +
68 + return newKey(out.Name, out.Id)
69 }
70
71 func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (iface.Key, bool, error) {
@@ -68,25 +87,29 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o
87 return nil, false, err
88 }
89
71 - id := &keyOutput{JName: out.Now, Id: out.Id}
72 - id.pid, err = peer.Decode(id.Id)
73 - return id, out.Overwrite, err
90 + key, err := newKey(out.Now, out.Id)
91 + if err != nil {
92 + return nil, false, err
93 + }
94 +
95 + return key, out.Overwrite, err
96 }
97
98 func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) {
77 - var out struct{ Keys []*keyOutput }
99 + var out struct {
100 + Keys []keyOutput
101 + }
102 if err := api.core().Request("key/list").Exec(ctx, &out); err != nil {
103 return nil, err
104 }
105
106 res := make([]iface.Key, len(out.Keys))
107 for i, k := range out.Keys {
84 - var err error
85 - k.pid, err = peer.Decode(k.Id)
108 + key, err := newKey(k.Name, k.Id)
109 if err != nil {
110 return nil, err
111 }
89 - res[i] = k
112 + res[i] = key
113 }
114
115 return res, nil
@@ -98,14 +121,13 @@ func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) {
121 return nil, err
122 }
123
101 - var err error
102 - out := keyOutput{JName: "self", Id: id.ID}
103 - out.pid, err = peer.Decode(out.Id)
104 - return &out, err
124 + return newKey("self", id.ID)
125 }
126
127 func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) {
108 - var out struct{ Keys []keyOutput }
128 + var out struct {
129 + Keys []keyOutput
130 + }
131 if err := api.core().Request("key/rm", name).Exec(ctx, &out); err != nil {
132 return nil, err
133 }
@@ -113,9 +135,7 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) {
135 return nil, errors.New("got unexpected number of keys back")
136 }
137
116 - var err error
117 - out.Keys[0].pid, err = peer.Decode(out.Keys[0].Id)
118 - return &out.Keys[0], err
138 + return newKey(out.Keys[0].Name, out.Keys[0].Id)
139 }
140
141 func (api *KeyAPI) core() *HttpApi {
client/rpc/name.go
+7 -3
@@ -9,8 +9,8 @@ import (
9 iface "github.com/ipfs/boxo/coreiface"
10 caopts "github.com/ipfs/boxo/coreiface/options"
11 nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
12 - "github.com/ipfs/boxo/coreiface/path"
12 "github.com/ipfs/boxo/ipns"
13 + "github.com/ipfs/boxo/path"
14 )
15
16 type NameAPI HttpApi
@@ -84,7 +84,11 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name
84 }
85 var ires iface.IpnsResult
86 if err == nil {
87 - ires.Path = path.New(out.Path)
87 + p, err := path.NewPath(out.Path)
88 + if err != nil {
89 + return
90 + }
91 + ires.Path = p
92 }
93
94 select {
@@ -122,7 +126,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam
126 return nil, err
127 }
128
125 - return path.New(out.Path), nil
129 + return path.NewPath(out.Path)
130 }
131
132 func (api *NameAPI) core() *HttpApi {
client/rpc/object.go
+13 -13
@@ -8,9 +8,9 @@ import (
8
9 iface "github.com/ipfs/boxo/coreiface"
10 caopts "github.com/ipfs/boxo/coreiface/options"
11 - "github.com/ipfs/boxo/coreiface/path"
11 "github.com/ipfs/boxo/ipld/merkledag"
12 ft "github.com/ipfs/boxo/ipld/unixfs"
13 + "github.com/ipfs/boxo/path"
14 "github.com/ipfs/go-cid"
15 ipld "github.com/ipfs/go-ipld-format"
16 )
@@ -40,7 +40,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (
40 return n, nil
41 }
42
43 -func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.Resolved, error) {
43 +func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) {
44 options, err := caopts.ObjectPutOptions(opts...)
45 if err != nil {
46 return nil, err
@@ -62,7 +62,7 @@ func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.Objec
62 return nil, err
63 }
64
65 - return path.IpfsPath(c), nil
65 + return path.FromCid(c), nil
66 }
67
68 func (api *ObjectAPI) Get(ctx context.Context, p path.Path) (ipld.Node, error) {
@@ -153,7 +153,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, p path.Path) (*iface.ObjectStat,
153 }, nil
154 }
155
156 -func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.Resolved, error) {
156 +func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) {
157 options, err := caopts.ObjectAddLinkOptions(opts...)
158 if err != nil {
159 return nil, err
@@ -172,10 +172,10 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string,
172 return nil, err
173 }
174
175 - return path.IpfsPath(c), nil
175 + return path.FromCid(c), nil
176 }
177
178 -func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error) {
178 +func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) {
179 var out objectOut
180 err := api.core().Request("object/patch/rm-link", base.String(), link).
181 Exec(ctx, &out)
@@ -188,10 +188,10 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (
188 return nil, err
189 }
190
191 - return path.IpfsPath(c), nil
191 + return path.FromCid(c), nil
192 }
193
194 -func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) (path.Resolved, error) {
194 +func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) (path.ImmutablePath, error) {
195 var out objectOut
196 err := api.core().Request("object/patch/append-data", p.String()).
197 FileBody(r).
@@ -205,10 +205,10 @@ func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader)
205 return nil, err
206 }
207
208 - return path.IpfsPath(c), nil
208 + return path.FromCid(c), nil
209 }
210
211 -func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (path.Resolved, error) {
211 +func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (path.ImmutablePath, error) {
212 var out objectOut
213 err := api.core().Request("object/patch/set-data", p.String()).
214 FileBody(r).
@@ -222,7 +222,7 @@ func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (pa
222 return nil, err
223 }
224
225 - return path.IpfsPath(c), nil
225 + return path.FromCid(c), nil
226 }
227
228 type change struct {
@@ -246,10 +246,10 @@ func (api *ObjectAPI) Diff(ctx context.Context, a path.Path, b path.Path) ([]ifa
246 Path: ch.Path,
247 }
248 if ch.Before != cid.Undef {
249 - res[i].Before = path.IpfsPath(ch.Before)
249 + res[i].Before = path.FromCid(ch.Before)
250 }
251 if ch.After != cid.Undef {
252 - res[i].After = path.IpfsPath(ch.After)
252 + res[i].After = path.FromCid(ch.After)
253 }
254 }
255 return res, nil
client/rpc/path.go
+12 -16
@@ -3,50 +3,46 @@ package rpc
3 import (
4 "context"
5
6 - "github.com/ipfs/boxo/coreiface/path"
7 - ipfspath "github.com/ipfs/boxo/path"
6 + "github.com/ipfs/boxo/path"
7 cid "github.com/ipfs/go-cid"
8 ipld "github.com/ipfs/go-ipld-format"
9 )
10
12 -func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) {
11 +func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.ImmutablePath, []string, error) {
12 var out struct {
13 Cid cid.Cid
14 RemPath string
15 }
16
18 - // TODO: this is hacky, fixing https://github.com/ipfs/go-ipfs/issues/5703 would help
19 -
17 var err error
21 - if p.Namespace() == "ipns" {
18 + if p.Namespace() == path.IPNSNamespace {
19 if p, err = api.Name().Resolve(ctx, p.String()); err != nil {
23 - return nil, err
20 + return nil, nil, err
21 }
22 }
23
24 if err := api.Request("dag/resolve", p.String()).Exec(ctx, &out); err != nil {
28 - return nil, err
25 + return nil, nil, err
26 }
27
31 - // TODO:
32 - ipath, err := ipfspath.FromSegments("/"+p.Namespace()+"/", out.Cid.String(), out.RemPath)
28 + p, err = path.NewPathFromSegments(p.Namespace(), out.Cid.String(), out.RemPath)
29 if err != nil {
34 - return nil, err
30 + return nil, nil, err
31 }
32
37 - root, err := cid.Parse(ipfspath.Path(p.String()).Segments()[1])
33 + imPath, err := path.NewImmutablePath(p)
34 if err != nil {
39 - return nil, err
35 + return nil, nil, err
36 }
37
42 - return path.NewResolvedPath(ipath, out.Cid, root, out.RemPath), nil
38 + return imPath, path.StringToSegments(out.RemPath), nil
39 }
40
41 func (api *HttpApi) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, error) {
46 - rp, err := api.ResolvePath(ctx, p)
42 + rp, _, err := api.ResolvePath(ctx, p)
43 if err != nil {
44 return nil, err
45 }
46
51 - return api.Dag().Get(ctx, rp.Cid())
47 + return api.Dag().Get(ctx, rp.RootCid())
48 }
client/rpc/pin.go
+6 -6
@@ -8,7 +8,7 @@ import (
8
9 iface "github.com/ipfs/boxo/coreiface"
10 caopts "github.com/ipfs/boxo/coreiface/options"
11 - "github.com/ipfs/boxo/coreiface/path"
11 + "github.com/ipfs/boxo/path"
12 "github.com/ipfs/go-cid"
13 "github.com/pkg/errors"
14 )
@@ -24,7 +24,7 @@ type pinRefKeyList struct {
24 }
25
26 type pin struct {
27 - path path.Resolved
27 + path path.ImmutablePath
28 typ string
29 err error
30 }
@@ -33,7 +33,7 @@ func (p pin) Err() error {
33 return p.err
34 }
35
36 -func (p pin) Path() path.Resolved {
36 +func (p pin) Path() path.ImmutablePath {
37 return p.path
38 }
39
@@ -102,7 +102,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan i
102 }
103
104 select {
105 - case ch <- pin{typ: out.Type, path: path.IpldPath(c)}:
105 + case ch <- pin{typ: out.Type, path: path.FromCid(c)}:
106 case <-ctx.Done():
107 return
108 }
@@ -182,8 +182,8 @@ type badNode struct {
182 cid cid.Cid
183 }
184
185 -func (n badNode) Path() path.Resolved {
186 - return path.IpldPath(n.cid)
185 +func (n badNode) Path() path.ImmutablePath {
186 + return path.FromCid(n.cid)
187 }
188
189 func (n badNode) Err() error {
client/rpc/unixfs.go
+4 -4
@@ -9,10 +9,10 @@ import (
9
10 iface "github.com/ipfs/boxo/coreiface"
11 caopts "github.com/ipfs/boxo/coreiface/options"
12 - "github.com/ipfs/boxo/coreiface/path"
12 "github.com/ipfs/boxo/files"
13 unixfs "github.com/ipfs/boxo/ipld/unixfs"
14 unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb"
15 + "github.com/ipfs/boxo/path"
16 "github.com/ipfs/go-cid"
17 mh "github.com/multiformats/go-multihash"
18 )
@@ -26,7 +26,7 @@ type addEvent struct {
26
27 type UnixfsAPI HttpApi
28
29 -func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (path.Resolved, error) {
29 +func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (path.ImmutablePath, error) {
30 options, _, err := caopts.UnixfsAddOptions(opts...)
31 if err != nil {
32 return nil, err
@@ -105,7 +105,7 @@ loop:
105 return nil, err
106 }
107
108 - ifevt.Path = path.IpfsPath(c)
108 + ifevt.Path = path.FromCid(c)
109 }
110
111 select {
@@ -121,7 +121,7 @@ loop:
121 return nil, err
122 }
123
124 - return path.IpfsPath(c), nil
124 + return path.FromCid(c), nil
125 }
126
127 type lsLink struct {
cmd/ipfs/add_migrations.go
+3 -3
@@ -10,8 +10,8 @@ import (
10
11 coreiface "github.com/ipfs/boxo/coreiface"
12 "github.com/ipfs/boxo/coreiface/options"
13 - ipath "github.com/ipfs/boxo/coreiface/path"
13 "github.com/ipfs/boxo/files"
14 + "github.com/ipfs/boxo/path"
15 "github.com/ipfs/kubo/core"
16 "github.com/ipfs/kubo/core/coreapi"
17 "github.com/ipfs/kubo/repo/fsrepo/migrations"
@@ -98,7 +98,7 @@ func addMigrationFiles(ctx context.Context, node *core.IpfsNode, paths []string,
98
99 // addMigrationPaths adds the files at paths to IPFS, optionally pinning
100 // them. This is done after connecting to the peer.
101 -func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.AddrInfo, paths []ipath.Path, pin bool) error {
101 +func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.AddrInfo, paths []path.Path, pin bool) error {
102 if len(paths) == 0 {
103 return errors.New("nothing downloaded by ipfs fetcher")
104 }
@@ -142,7 +142,7 @@ func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.A
142 return nil
143 }
144
145 -func ipfsGet(ctx context.Context, ufs coreiface.UnixfsAPI, ipfsPath ipath.Path) error {
145 +func ipfsGet(ctx context.Context, ufs coreiface.UnixfsAPI, ipfsPath path.Path) error {
146 nd, err := ufs.Get(ctx, ipfsPath)
147 if err != nil {
148 return err
cmd/ipfs/init.go
+1 -1
@@ -11,7 +11,7 @@ import (
11 "strings"
12
13 unixfs "github.com/ipfs/boxo/ipld/unixfs"
14 - path "github.com/ipfs/boxo/path"
14 + "github.com/ipfs/boxo/path"
15 assets "github.com/ipfs/kubo/assets"
16 oldcmds "github.com/ipfs/kubo/commands"
17 core "github.com/ipfs/kubo/core"
core/commands/add.go
+2 -2
@@ -317,7 +317,7 @@ See 'dag export' and 'dag import' for more information.
317 }
318
319 var nodeAdded ipld.Node
320 - nodeAdded, err = api.Dag().Get(req.Context, pathAdded.Cid())
320 + nodeAdded, err = api.Dag().Get(req.Context, pathAdded.RootCid())
321 if err != nil {
322 errCh <- err
323 return
@@ -340,7 +340,7 @@ See 'dag export' and 'dag import' for more information.
340
341 h := ""
342 if output.Path != nil {
343 - h = enc.Encode(output.Path.Cid())
343 + h = enc.Encode(output.Path.RootCid())
344 }
345
346 if !dir && addit.Name() != "" {
core/commands/block.go
+23 -8
@@ -12,7 +12,7 @@ import (
12 "github.com/ipfs/kubo/core/commands/cmdutils"
13
14 options "github.com/ipfs/boxo/coreiface/options"
15 - path "github.com/ipfs/boxo/coreiface/path"
15 +
16 cmds "github.com/ipfs/go-ipfs-cmds"
17 mh "github.com/multiformats/go-multihash"
18 )
@@ -66,13 +66,18 @@ on raw IPFS blocks. It outputs the following to stdout:
66 return err
67 }
68
69 - b, err := api.Block().Stat(req.Context, path.New(req.Arguments[0]))
69 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
70 + if err != nil {
71 + return err
72 + }
73 +
74 + b, err := api.Block().Stat(req.Context, p)
75 if err != nil {
76 return err
77 }
78
79 return cmds.EmitOnce(res, &BlockStat{
75 - Key: b.Path().Cid().String(),
80 + Key: b.Path().RootCid().String(),
81 Size: b.Size(),
82 })
83 },
@@ -103,7 +108,12 @@ It takes a <cid>, and outputs the block to stdout.
108 return err
109 }
110
106 - r, err := api.Block().Get(req.Context, path.New(req.Arguments[0]))
111 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
112 + if err != nil {
113 + return err
114 + }
115 +
116 + r, err := api.Block().Get(req.Context, p)
117 if err != nil {
118 return err
119 }
@@ -200,7 +210,7 @@ only for backward compatibility when a legacy CIDv0 is required (--format=v0).
210 }
211
212 err = res.Emit(&BlockStat{
203 - Key: p.Path().Cid().String(),
213 + Key: p.Path().RootCid().String(),
214 Size: p.Size(),
215 })
216 if err != nil {
@@ -255,7 +265,12 @@ It takes a list of CIDs to remove from the local datastore..
265
266 // TODO: use batching coreapi when done
267 for _, b := range req.Arguments {
258 - rp, err := api.ResolvePath(req.Context, path.New(b))
268 + p, err := cmdutils.PathOrCidPath(b)
269 + if err != nil {
270 + return err
271 + }
272 +
273 + rp, _, err := api.ResolvePath(req.Context, p)
274 if err != nil {
275 return err
276 }
@@ -263,7 +278,7 @@ It takes a list of CIDs to remove from the local datastore..
278 err = api.Block().Rm(req.Context, rp, options.Block.Force(force))
279 if err != nil {
280 if err := res.Emit(&removedBlock{
266 - Hash: rp.Cid().String(),
281 + Hash: rp.RootCid().String(),
282 Error: err.Error(),
283 }); err != nil {
284 return err
@@ -273,7 +288,7 @@ It takes a list of CIDs to remove from the local datastore..
288
289 if !quiet {
290 err := res.Emit(&removedBlock{
276 - Hash: rp.Cid().String(),
291 + Hash: rp.RootCid().String(),
292 })
293 if err != nil {
294 return err
core/commands/cat.go
+8 -3
@@ -7,10 +7,10 @@ import (
7 "os"
8
9 "github.com/ipfs/kubo/core/commands/cmdenv"
10 + "github.com/ipfs/kubo/core/commands/cmdutils"
11
12 "github.com/cheggaaa/pb"
13 iface "github.com/ipfs/boxo/coreiface"
13 - "github.com/ipfs/boxo/coreiface/path"
14 "github.com/ipfs/boxo/files"
15 cmds "github.com/ipfs/go-ipfs-cmds"
16 )
@@ -127,8 +127,13 @@ func cat(ctx context.Context, api iface.CoreAPI, paths []string, offset int64, m
127 if max == 0 {
128 return nil, 0, nil
129 }
130 - for _, p := range paths {
131 - f, err := api.Unixfs().Get(ctx, path.New(p))
130 + for _, pString := range paths {
131 + p, err := cmdutils.PathOrCidPath(pString)
132 + if err != nil {
133 + return nil, 0, err
134 + }
135 +
136 + f, err := api.Unixfs().Get(ctx, p)
137 if err != nil {
138 return nil, 0, err
139 }
core/commands/cmdutils/utils.go
+17
@@ -6,6 +6,7 @@ import (
6 cmds "github.com/ipfs/go-ipfs-cmds"
7
8 coreiface "github.com/ipfs/boxo/coreiface"
9 + "github.com/ipfs/boxo/path"
10 "github.com/ipfs/go-cid"
11 )
12
@@ -48,3 +49,19 @@ func CheckBlockSize(req *cmds.Request, size uint64) error {
49 }
50 return nil
51 }
52 +
53 +// PathOrCidPath returns a path.Path built from the argument. It keeps the old
54 +// behaviour by building a path from a CID string.
55 +func PathOrCidPath(str string) (path.Path, error) {
56 + p, err := path.NewPath(str)
57 + if err == nil {
58 + return p, nil
59 + }
60 +
61 + if p, err := path.NewPath("/ipfs/" + str); err == nil {
62 + return p, nil
63 + }
64 +
65 + // Send back original err.
66 + return nil, err
67 +}
core/commands/dag/dag.go
+2 -2
@@ -5,11 +5,11 @@ import (
5 "encoding/json"
6 "fmt"
7 "io"
8 + "path"
9
10 "github.com/ipfs/kubo/core/commands/cmdenv"
11 "github.com/ipfs/kubo/core/commands/cmdutils"
12
12 - ipfspath "github.com/ipfs/boxo/path"
13 cid "github.com/ipfs/go-cid"
14 cidenc "github.com/ipfs/go-cidutil/cidenc"
15 cmds "github.com/ipfs/go-ipfs-cmds"
@@ -157,7 +157,7 @@ var DagResolveCmd = &cmds.Command{
157 }
158 p := enc.Encode(out.Cid)
159 if out.RemPath != "" {
160 - p = ipfspath.Join([]string{p, out.RemPath})
160 + p = path.Join(p, out.RemPath)
161 }
162
163 fmt.Fprint(w, p)
core/commands/dag/get.go
+11 -5
@@ -4,9 +4,10 @@ import (
4 "fmt"
5 "io"
6
7 - "github.com/ipfs/boxo/coreiface/path"
7 + "github.com/ipfs/boxo/path"
8 ipldlegacy "github.com/ipfs/go-ipld-legacy"
9 "github.com/ipfs/kubo/core/commands/cmdenv"
10 + "github.com/ipfs/kubo/core/commands/cmdutils"
11
12 "github.com/ipld/go-ipld-prime"
13 "github.com/ipld/go-ipld-prime/multicodec"
@@ -28,12 +29,17 @@ func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e
29 return err
30 }
31
31 - rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0]))
32 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
33 if err != nil {
34 return err
35 }
36
36 - obj, err := api.Dag().Get(req.Context, rp.Cid())
37 + rp, remainder, err := api.ResolvePath(req.Context, p)
38 + if err != nil {
39 + return err
40 + }
41 +
42 + obj, err := api.Dag().Get(req.Context, rp.RootCid())
43 if err != nil {
44 return err
45 }
@@ -45,8 +51,8 @@ func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e
51
52 finalNode := universal.(ipld.Node)
53
48 - if len(rp.Remainder()) > 0 {
49 - remainderPath := ipld.ParsePath(rp.Remainder())
54 + if len(remainder) > 0 {
55 + remainderPath := ipld.ParsePath(path.SegmentsToString(remainder...))
56
57 finalNode, err = traversal.Get(finalNode, remainderPath)
58 if err != nil {
core/commands/dag/resolve.go
+10 -4
@@ -1,8 +1,9 @@
1 package dagcmd
2
3 import (
4 - "github.com/ipfs/boxo/coreiface/path"
4 + "github.com/ipfs/boxo/path"
5 "github.com/ipfs/kubo/core/commands/cmdenv"
6 + "github.com/ipfs/kubo/core/commands/cmdutils"
7
8 cmds "github.com/ipfs/go-ipfs-cmds"
9 )
@@ -13,13 +14,18 @@ func dagResolve(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environmen
14 return err
15 }
16
16 - rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0]))
17 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
18 + if err != nil {
19 + return err
20 + }
21 +
22 + rp, remainder, err := api.ResolvePath(req.Context, p)
23 if err != nil {
24 return err
25 }
26
27 return cmds.EmitOnce(res, &ResolveOutput{
22 - Cid: rp.Cid(),
23 - RemPath: rp.Remainder(),
28 + Cid: rp.RootCid(),
29 + RemPath: path.SegmentsToString(remainder...),
30 })
31 }
core/commands/dag/stat.go
+9 -5
@@ -5,12 +5,12 @@ import (
5 "io"
6 "os"
7
8 - "github.com/ipfs/boxo/coreiface/path"
8 mdag "github.com/ipfs/boxo/ipld/merkledag"
9 "github.com/ipfs/boxo/ipld/merkledag/traverse"
10 cid "github.com/ipfs/go-cid"
11 cmds "github.com/ipfs/go-ipfs-cmds"
12 "github.com/ipfs/kubo/core/commands/cmdenv"
13 + "github.com/ipfs/kubo/core/commands/cmdutils"
14 "github.com/ipfs/kubo/core/commands/e"
15 )
16
@@ -29,19 +29,23 @@ func dagStat(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment)
29 cidSet := cid.NewSet()
30 dagStatSummary := &DagStatSummary{DagStatsArray: []*DagStat{}}
31 for _, a := range req.Arguments {
32 - rp, err := api.ResolvePath(req.Context, path.New(a))
32 + p, err := cmdutils.PathOrCidPath(a)
33 if err != nil {
34 return err
35 }
36 - if len(rp.Remainder()) > 0 {
36 + rp, remainder, err := api.ResolvePath(req.Context, p)
37 + if err != nil {
38 + return err
39 + }
40 + if len(remainder) > 0 {
41 return fmt.Errorf("cannot return size for anything other than a DAG with a root CID")
42 }
43
40 - obj, err := nodeGetter.Get(req.Context, rp.Cid())
44 + obj, err := nodeGetter.Get(req.Context, rp.RootCid())
45 if err != nil {
46 return err
47 }
44 - dagstats := &DagStat{Cid: rp.Cid()}
48 + dagstats := &DagStat{Cid: rp.RootCid()}
49 dagStatSummary.appendStats(dagstats)
50 err = traverse.Traverse(obj, traverse.Options{
51 DAG: nodeGetter,
core/commands/dns.go
+2 -2
@@ -56,11 +56,11 @@ It will work across multiple DNSLinks and IPNS keys.
56 if err != nil && (recursive || err != namesys.ErrResolveRecursion) {
57 return err
58 }
59 - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: output})
59 + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: output.String()})
60 },
61 Encoders: cmds.EncoderMap{
62 cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ncmd.ResolvedPath) error {
63 - fmt.Fprintln(w, cmdenv.EscNonPrint(out.Path.String()))
63 + fmt.Fprintln(w, cmdenv.EscNonPrint(out.Path))
64 return nil
65 }),
66 },
core/commands/files.go
+7 -2
@@ -16,11 +16,11 @@ import (
16
17 bservice "github.com/ipfs/boxo/blockservice"
18 iface "github.com/ipfs/boxo/coreiface"
19 - path "github.com/ipfs/boxo/coreiface/path"
19 offline "github.com/ipfs/boxo/exchange/offline"
20 dag "github.com/ipfs/boxo/ipld/merkledag"
21 ft "github.com/ipfs/boxo/ipld/unixfs"
22 mfs "github.com/ipfs/boxo/mfs"
23 + "github.com/ipfs/boxo/path"
24 cid "github.com/ipfs/go-cid"
25 cidenc "github.com/ipfs/go-cidutil/cidenc"
26 cmds "github.com/ipfs/go-ipfs-cmds"
@@ -423,7 +423,12 @@ being GC'ed.
423 func getNodeFromPath(ctx context.Context, node *core.IpfsNode, api iface.CoreAPI, p string) (ipld.Node, error) {
424 switch {
425 case strings.HasPrefix(p, "/ipfs/"):
426 - return api.ResolveNode(ctx, path.New(p))
426 + pth, err := path.NewPath(p)
427 + if err != nil {
428 + return nil, err
429 + }
430 +
431 + return api.ResolveNode(ctx, pth)
432 default:
433 fsn, err := mfs.Lookup(node.FilesRoot, p)
434 if err != nil {
core/commands/get.go
+5 -2
@@ -12,10 +12,10 @@ import (
12 "strings"
13
14 "github.com/ipfs/kubo/core/commands/cmdenv"
15 + "github.com/ipfs/kubo/core/commands/cmdutils"
16 "github.com/ipfs/kubo/core/commands/e"
17
18 "github.com/cheggaaa/pb"
18 - "github.com/ipfs/boxo/coreiface/path"
19 "github.com/ipfs/boxo/files"
20 "github.com/ipfs/boxo/tar"
21 cmds "github.com/ipfs/go-ipfs-cmds"
@@ -72,7 +72,10 @@ may also specify the level of compression by specifying '-l=<1-9>'.
72 return err
73 }
74
75 - p := path.New(req.Arguments[0])
75 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
76 + if err != nil {
77 + return err
78 + }
79
80 file, err := api.Unixfs().Get(ctx, p)
81 if err != nil {
core/commands/ls.go
+7 -2
@@ -8,10 +8,10 @@ import (
8 "text/tabwriter"
9
10 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
11 + "github.com/ipfs/kubo/core/commands/cmdutils"
12
13 iface "github.com/ipfs/boxo/coreiface"
14 options "github.com/ipfs/boxo/coreiface/options"
14 - path "github.com/ipfs/boxo/coreiface/path"
15 unixfs "github.com/ipfs/boxo/ipld/unixfs"
16 unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb"
17 cmds "github.com/ipfs/go-ipfs-cmds"
@@ -131,7 +131,12 @@ The JSON output contains type information.
131 }
132
133 for i, fpath := range paths {
134 - results, err := api.Unixfs().Ls(req.Context, path.New(fpath),
134 + pth, err := cmdutils.PathOrCidPath(fpath)
135 + if err != nil {
136 + return err
137 + }
138 +
139 + results, err := api.Unixfs().Ls(req.Context, pth,
140 options.Unixfs.ResolveChildren(resolveSize || resolveType))
141 if err != nil {
142 return err
core/commands/name/ipns.go
+9 -4
@@ -12,7 +12,7 @@ import (
12
13 options "github.com/ipfs/boxo/coreiface/options"
14 nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
15 - path "github.com/ipfs/boxo/path"
15 + "github.com/ipfs/boxo/path"
16 cmds "github.com/ipfs/go-ipfs-cmds"
17 logging "github.com/ipfs/go-log"
18 )
@@ -20,7 +20,7 @@ import (
20 var log = logging.Logger("core/commands/ipns")
21
22 type ResolvedPath struct {
23 - Path path.Path
23 + Path string
24 }
25
26 const (
@@ -134,7 +134,12 @@ Resolve the value of a dnslink:
134 return err
135 }
136
137 - return cmds.EmitOnce(res, &ResolvedPath{path.FromString(output.String())})
137 + pth, err := path.NewPath(output.String())
138 + if err != nil {
139 + return err
140 + }
141 +
142 + return cmds.EmitOnce(res, &ResolvedPath{pth.String()})
143 }
144
145 output, err := api.Name().Search(req.Context, name, opts...)
@@ -146,7 +151,7 @@ Resolve the value of a dnslink:
151 if v.Err != nil && (recursive || v.Err != namesys.ErrResolveRecursion) {
152 return v.Err
153 }
149 - if err := res.Emit(&ResolvedPath{path.FromString(v.Path.String())}); err != nil {
154 + if err := res.Emit(&ResolvedPath{v.Path.String()}); err != nil {
155 return err
156 }
157
core/commands/name/name.go
+4 -5
@@ -10,7 +10,6 @@ import (
10
11 "github.com/ipfs/boxo/ipns"
12 ipns_pb "github.com/ipfs/boxo/ipns/pb"
13 - "github.com/ipfs/boxo/path"
13 cmds "github.com/ipfs/go-ipfs-cmds"
14 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
15 "google.golang.org/protobuf/proto"
@@ -87,7 +86,7 @@ type IpnsInspectValidation struct {
86 // IpnsInspectEntry contains the deserialized values from an IPNS Entry:
87 // https://github.com/ipfs/specs/blob/main/ipns/IPNS.md#record-serialization-format
88 type IpnsInspectEntry struct {
90 - Value *path.Path
89 + Value string
90 ValidityType *ipns.ValidityType
91 Validity *time.Time
92 Sequence *uint64
@@ -157,7 +156,7 @@ Passing --verify will verify signature against provided public key.
156
157 // Best effort to get the fields. Show everything we can.
158 if v, err := rec.Value(); err == nil {
160 - result.Entry.Value = &v
159 + result.Entry.Value = v.String()
160 }
161
162 if v, err := rec.ValidityType(); err == nil {
@@ -221,8 +220,8 @@ Passing --verify will verify signature against provided public key.
220 tw := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0)
221 defer tw.Flush()
222
224 - if out.Entry.Value != nil {
225 - fmt.Fprintf(tw, "Value:\t%q\n", out.Entry.Value.String())
223 + if out.Entry.Value != "" {
224 + fmt.Fprintf(tw, "Value:\t%q\n", out.Entry.Value)
225 }
226
227 if out.Entry.ValidityType != nil {
core/commands/name/publish.go
+5 -2
@@ -7,10 +7,10 @@ import (
7 "time"
8
9 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
10 + "github.com/ipfs/kubo/core/commands/cmdutils"
11
12 iface "github.com/ipfs/boxo/coreiface"
13 options "github.com/ipfs/boxo/coreiface/options"
13 - path "github.com/ipfs/boxo/coreiface/path"
14 cmds "github.com/ipfs/go-ipfs-cmds"
15 ke "github.com/ipfs/kubo/core/commands/keyencode"
16 )
@@ -116,7 +116,10 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
116 opts = append(opts, options.Name.TTL(d))
117 }
118
119 - p := path.New(req.Arguments[0])
119 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
120 + if err != nil {
121 + return err
122 + }
123
124 if verifyExists, _ := req.Options[resolveOptionName].(bool); verifyExists {
125 _, err := api.ResolveNode(req.Context, p)
core/commands/object/diff.go
+12 -5
@@ -4,11 +4,11 @@ import (
4 "fmt"
5 "io"
6
7 - path "github.com/ipfs/boxo/coreiface/path"
7 "github.com/ipfs/boxo/ipld/merkledag/dagutils"
8 cmds "github.com/ipfs/go-ipfs-cmds"
9
10 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
11 + "github.com/ipfs/kubo/core/commands/cmdutils"
12 )
13
14 const (
@@ -60,8 +60,15 @@ Example:
60 return err
61 }
62
63 - pa := path.New(req.Arguments[0])
64 - pb := path.New(req.Arguments[1])
63 + pa, err := cmdutils.PathOrCidPath(req.Arguments[0])
64 + if err != nil {
65 + return err
66 + }
67 +
68 + pb, err := cmdutils.PathOrCidPath(req.Arguments[1])
69 + if err != nil {
70 + return err
71 + }
72
73 changes, err := api.Object().Diff(req.Context, pa, pb)
74 if err != nil {
@@ -76,11 +83,11 @@ Example:
83 }
84
85 if change.Before != nil {
79 - out[i].Before = change.Before.Cid()
86 + out[i].Before = change.Before.RootCid()
87 }
88
89 if change.After != nil {
83 - out[i].After = change.After.Cid()
90 + out[i].After = change.After.RootCid()
91 }
92 }
93
core/commands/object/object.go
+22 -8
@@ -9,10 +9,10 @@ import (
9
10 cmds "github.com/ipfs/go-ipfs-cmds"
11 "github.com/ipfs/kubo/core/commands/cmdenv"
12 + "github.com/ipfs/kubo/core/commands/cmdutils"
13
14 humanize "github.com/dustin/go-humanize"
15 "github.com/ipfs/boxo/coreiface/options"
15 - path "github.com/ipfs/boxo/coreiface/path"
16 dag "github.com/ipfs/boxo/ipld/merkledag"
17 "github.com/ipfs/go-cid"
18 ipld "github.com/ipfs/go-ipld-format"
@@ -95,7 +95,10 @@ is the raw data of the object.
95 return err
96 }
97
98 - path := path.New(req.Arguments[0])
98 + path, err := cmdutils.PathOrCidPath(req.Arguments[0])
99 + if err != nil {
100 + return err
101 + }
102
103 data, err := api.Object().Data(req.Context, path)
104 if err != nil {
@@ -135,9 +138,12 @@ multihash. Provided for legacy reasons. Use 'ipfs dag get' instead.
138 return err
139 }
140
138 - path := path.New(req.Arguments[0])
141 + path, err := cmdutils.PathOrCidPath(req.Arguments[0])
142 + if err != nil {
143 + return err
144 + }
145
140 - rp, err := api.ResolvePath(req.Context, path)
146 + rp, _, err := api.ResolvePath(req.Context, path)
147 if err != nil {
148 return err
149 }
@@ -157,7 +163,7 @@ multihash. Provided for legacy reasons. Use 'ipfs dag get' instead.
163 }
164
165 out := &Object{
160 - Hash: enc.Encode(rp.Cid()),
166 + Hash: enc.Encode(rp.RootCid()),
167 Links: outLinks,
168 }
169
@@ -212,7 +218,10 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs dag get' instead.
218 return err
219 }
220
215 - path := path.New(req.Arguments[0])
221 + path, err := cmdutils.PathOrCidPath(req.Arguments[0])
222 + if err != nil {
223 + return err
224 + }
225
226 datafieldenc, _ := req.Options[encodingOptionName].(string)
227 if err != nil {
@@ -333,7 +342,12 @@ DEPRECATED: Provided for legacy reasons. Modern replacements:
342 return err
343 }
344
336 - ns, err := api.Object().Stat(req.Context, path.New(req.Arguments[0]))
345 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
346 + if err != nil {
347 + return err
348 + }
349 +
350 + ns, err := api.Object().Stat(req.Context, p)
351 if err != nil {
352 return err
353 }
@@ -434,7 +448,7 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs dag put' instead.
448 return err
449 }
450
437 - return cmds.EmitOnce(res, &Object{Hash: enc.Encode(p.Cid())})
451 + return cmds.EmitOnce(res, &Object{Hash: enc.Encode(p.RootCid())})
452 },
453 Encoders: cmds.EncoderMap{
454 cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error {
core/commands/object/patch.go
+30 -14
@@ -9,7 +9,6 @@ import (
9 "github.com/ipfs/kubo/core/commands/cmdutils"
10
11 "github.com/ipfs/boxo/coreiface/options"
12 - "github.com/ipfs/boxo/coreiface/path"
12 )
13
14 var ObjectPatchCmd = &cmds.Command{
@@ -76,7 +75,10 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' inste
75 return err
76 }
77
79 - root := path.New(req.Arguments[0])
78 + root, err := cmdutils.PathOrCidPath(req.Arguments[0])
79 + if err != nil {
80 + return err
81 + }
82
83 file, err := cmdenv.GetFileArg(req.Files.Entries())
84 if err != nil {
@@ -88,11 +90,11 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' inste
90 return err
91 }
92
91 - if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil {
93 + if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil {
94 return err
95 }
96
95 - return cmds.EmitOnce(res, &Object{Hash: p.Cid().String()})
97 + return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()})
98 },
99 Type: &Object{},
100 Encoders: cmds.EncoderMap{
@@ -127,7 +129,10 @@ DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead
129 return err
130 }
131
130 - root := path.New(req.Arguments[0])
132 + root, err := cmdutils.PathOrCidPath(req.Arguments[0])
133 + if err != nil {
134 + return err
135 + }
136
137 file, err := cmdenv.GetFileArg(req.Files.Entries())
138 if err != nil {
@@ -139,11 +144,11 @@ DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead
144 return err
145 }
146
142 - if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil {
147 + if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil {
148 return err
149 }
150
146 - return cmds.EmitOnce(res, &Object{Hash: p.Cid().String()})
151 + return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()})
152 },
153 Type: Object{},
154 Encoders: cmds.EncoderMap{
@@ -174,7 +179,10 @@ DEPRECATED and provided for legacy reasons. Use 'files rm' instead.
179 return err
180 }
181
177 - root := path.New(req.Arguments[0])
182 + root, err := cmdutils.PathOrCidPath(req.Arguments[0])
183 + if err != nil {
184 + return err
185 + }
186
187 name := req.Arguments[1]
188 p, err := api.Object().RmLink(req.Context, root, name)
@@ -182,11 +190,11 @@ DEPRECATED and provided for legacy reasons. Use 'files rm' instead.
190 return err
191 }
192
185 - if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil {
193 + if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil {
194 return err
195 }
196
189 - return cmds.EmitOnce(res, &Object{Hash: p.Cid().String()})
197 + return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()})
198 },
199 Type: Object{},
200 Encoders: cmds.EncoderMap{
@@ -238,9 +246,17 @@ Use MFS and 'files' commands instead:
246 return err
247 }
248
241 - root := path.New(req.Arguments[0])
249 + root, err := cmdutils.PathOrCidPath(req.Arguments[0])
250 + if err != nil {
251 + return err
252 + }
253 +
254 name := req.Arguments[1]
243 - child := path.New(req.Arguments[2])
255 +
256 + child, err := cmdutils.PathOrCidPath(req.Arguments[2])
257 + if err != nil {
258 + return err
259 + }
260
261 create, _ := req.Options[createOptionName].(bool)
262 if err != nil {
@@ -253,11 +269,11 @@ Use MFS and 'files' commands instead:
269 return err
270 }
271
256 - if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil {
272 + if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil {
273 return err
274 }
275
260 - return cmds.EmitOnce(res, &Object{Hash: p.Cid().String()})
276 + return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()})
277 },
278 Type: Object{},
279 Encoders: cmds.EncoderMap{
core/commands/pin/pin.go
+36 -11
@@ -11,7 +11,6 @@ import (
11 bserv "github.com/ipfs/boxo/blockservice"
12 coreiface "github.com/ipfs/boxo/coreiface"
13 options "github.com/ipfs/boxo/coreiface/options"
14 - "github.com/ipfs/boxo/coreiface/path"
14 offline "github.com/ipfs/boxo/exchange/offline"
15 dag "github.com/ipfs/boxo/ipld/merkledag"
16 verifcid "github.com/ipfs/boxo/verifcid"
@@ -21,6 +20,7 @@ import (
20
21 core "github.com/ipfs/kubo/core"
22 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
23 + "github.com/ipfs/kubo/core/commands/cmdutils"
24 e "github.com/ipfs/kubo/core/commands/e"
25 )
26
@@ -184,7 +184,12 @@ var addPinCmd = &cmds.Command{
184 func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, paths []string, recursive bool) ([]string, error) {
185 added := make([]string, len(paths))
186 for i, b := range paths {
187 - rp, err := api.ResolvePath(ctx, path.New(b))
187 + p, err := cmdutils.PathOrCidPath(b)
188 + if err != nil {
189 + return nil, err
190 + }
191 +
192 + rp, _, err := api.ResolvePath(ctx, p)
193 if err != nil {
194 return nil, err
195 }
@@ -192,7 +197,7 @@ func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder,
197 if err := api.Pin().Add(ctx, rp, options.Pin.Recursive(recursive)); err != nil {
198 return nil, err
199 }
195 - added[i] = enc.Encode(rp.Cid())
200 + added[i] = enc.Encode(rp.RootCid())
201 }
202
203 return added, nil
@@ -242,12 +247,17 @@ ipfs pin ls -t indirect <cid>
247
248 pins := make([]string, 0, len(req.Arguments))
249 for _, b := range req.Arguments {
245 - rp, err := api.ResolvePath(req.Context, path.New(b))
250 + p, err := cmdutils.PathOrCidPath(b)
251 + if err != nil {
252 + return err
253 + }
254 +
255 + rp, _, err := api.ResolvePath(req.Context, p)
256 if err != nil {
257 return err
258 }
259
250 - id := enc.Encode(rp.Cid())
260 + id := enc.Encode(rp.RootCid())
261 pins = append(pins, id)
262 if err := api.Pin().Rm(req.Context, rp, options.Pin.RmRecursive(recursive)); err != nil {
263 return err
@@ -453,7 +463,12 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu
463 }
464
465 for _, p := range req.Arguments {
456 - rp, err := api.ResolvePath(req.Context, path.New(p))
466 + p, err := cmdutils.PathOrCidPath(p)
467 + if err != nil {
468 + return err
469 + }
470 +
471 + rp, _, err := api.ResolvePath(req.Context, p)
472 if err != nil {
473 return err
474 }
@@ -476,7 +491,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu
491 err = emit(PinLsOutputWrapper{
492 PinLsObject: PinLsObject{
493 Type: pinType,
479 - Cid: enc.Encode(rp.Cid()),
494 + Cid: enc.Encode(rp.RootCid()),
495 },
496 })
497 if err != nil {
@@ -517,7 +532,7 @@ func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fun
532 err = emit(PinLsOutputWrapper{
533 PinLsObject: PinLsObject{
534 Type: p.Type(),
520 - Cid: enc.Encode(p.Path().Cid()),
535 + Cid: enc.Encode(p.Path().RootCid()),
536 },
537 })
538 if err != nil {
@@ -568,12 +583,22 @@ pin.
583
584 unpin, _ := req.Options[pinUnpinOptionName].(bool)
585
586 + fromPath, err := cmdutils.PathOrCidPath(req.Arguments[0])
587 + if err != nil {
588 + return err
589 + }
590 +
591 + toPath, err := cmdutils.PathOrCidPath(req.Arguments[1])
592 + if err != nil {
593 + return err
594 + }
595 +
596 // Resolve the paths ahead of time so we can return the actual CIDs
572 - from, err := api.ResolvePath(req.Context, path.New(req.Arguments[0]))
597 + from, _, err := api.ResolvePath(req.Context, fromPath)
598 if err != nil {
599 return err
600 }
576 - to, err := api.ResolvePath(req.Context, path.New(req.Arguments[1]))
601 + to, _, err := api.ResolvePath(req.Context, toPath)
602 if err != nil {
603 return err
604 }
@@ -583,7 +608,7 @@ pin.
608 return err
609 }
610
586 - return cmds.EmitOnce(res, &PinOutput{Pins: []string{enc.Encode(from.Cid()), enc.Encode(to.Cid())}})
611 + return cmds.EmitOnce(res, &PinOutput{Pins: []string{enc.Encode(from.RootCid()), enc.Encode(to.RootCid())}})
612 },
613 Encoders: cmds.EncoderMap{
614 cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error {
core/commands/pin/remotepin.go
+9 -4
@@ -15,13 +15,13 @@ import (
15
16 "golang.org/x/sync/errgroup"
17
18 - path "github.com/ipfs/boxo/coreiface/path"
18 pinclient "github.com/ipfs/boxo/pinning/remote/client"
19 cid "github.com/ipfs/go-cid"
20 cmds "github.com/ipfs/go-ipfs-cmds"
21 logging "github.com/ipfs/go-log"
22 config "github.com/ipfs/kubo/config"
23 "github.com/ipfs/kubo/core/commands/cmdenv"
24 + "github.com/ipfs/kubo/core/commands/cmdutils"
25 fsrepo "github.com/ipfs/kubo/repo/fsrepo"
26 "github.com/libp2p/go-libp2p/core/host"
27 peer "github.com/libp2p/go-libp2p/core/peer"
@@ -157,7 +157,12 @@ NOTE: a comma-separated notation is supported in CLI for convenience:
157 if err != nil {
158 return err
159 }
160 - rp, err := api.ResolvePath(ctx, path.New(req.Arguments[0]))
160 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
161 + if err != nil {
162 + return err
163 + }
164 +
165 + rp, _, err := api.ResolvePath(ctx, p)
166 if err != nil {
167 return err
168 }
@@ -177,7 +182,7 @@ NOTE: a comma-separated notation is supported in CLI for convenience:
182 return err
183 }
184
180 - isInBlockstore, err := node.Blockstore.Has(req.Context, rp.Cid())
185 + isInBlockstore, err := node.Blockstore.Has(req.Context, rp.RootCid())
186 if err != nil {
187 return err
188 }
@@ -194,7 +199,7 @@ NOTE: a comma-separated notation is supported in CLI for convenience:
199
200 // Execute remote pin request
201 // TODO: fix panic when pinning service is down
197 - ps, err := c.Add(ctx, rp.Cid(), opts...)
202 + ps, err := c.Add(ctx, rp.RootCid(), opts...)
203 if err != nil {
204 return err
205 }
core/commands/refs.go
+7 -3
@@ -8,9 +8,9 @@ import (
8 "strings"
9
10 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
11 + "github.com/ipfs/kubo/core/commands/cmdutils"
12
13 iface "github.com/ipfs/boxo/coreiface"
13 - path "github.com/ipfs/boxo/coreiface/path"
14 merkledag "github.com/ipfs/boxo/ipld/merkledag"
15 cid "github.com/ipfs/go-cid"
16 cidenc "github.com/ipfs/go-cidutil/cidenc"
@@ -171,11 +171,15 @@ Displays the hashes of all local objects. NOTE: This treats all local objects as
171 func objectsForPaths(ctx context.Context, n iface.CoreAPI, paths []string) ([]cid.Cid, error) {
172 roots := make([]cid.Cid, len(paths))
173 for i, sp := range paths {
174 - o, err := n.ResolvePath(ctx, path.New(sp))
174 + p, err := cmdutils.PathOrCidPath(sp)
175 if err != nil {
176 return nil, err
177 }
178 - roots[i] = o.Cid()
178 + o, _, err := n.ResolvePath(ctx, p)
179 + if err != nil {
180 + return nil, err
181 + }
182 + roots[i] = o.RootCid()
183 }
184 return roots, nil
185 }
core/commands/resolve.go
+22 -10
@@ -8,14 +8,14 @@ import (
8 "time"
9
10 ns "github.com/ipfs/boxo/namesys"
11 + "github.com/ipfs/boxo/path"
12 + cidenc "github.com/ipfs/go-cidutil/cidenc"
13 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
14 + "github.com/ipfs/kubo/core/commands/cmdutils"
15 ncmd "github.com/ipfs/kubo/core/commands/name"
16
17 options "github.com/ipfs/boxo/coreiface/options"
18 nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
16 - path "github.com/ipfs/boxo/coreiface/path"
17 - ipfspath "github.com/ipfs/boxo/path"
18 - cidenc "github.com/ipfs/go-cidutil/cidenc"
19 cmds "github.com/ipfs/go-ipfs-cmds"
20 )
21
@@ -108,7 +108,7 @@ Resolve the value of an IPFS DAG path:
108 if err != nil && err != ns.ErrResolveRecursion {
109 return err
110 }
111 - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(p.String())})
111 + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: p.String()})
112 }
113
114 var enc cidenc.Encoder
@@ -128,22 +128,34 @@ Resolve the value of an IPFS DAG path:
128 }
129 }
130
131 + p, err := cmdutils.PathOrCidPath(name)
132 + if err != nil {
133 + return err
134 + }
135 +
136 // else, ipfs path or ipns with recursive flag
132 - rp, err := api.ResolvePath(req.Context, path.New(name))
137 + rp, remainder, err := api.ResolvePath(req.Context, p)
138 if err != nil {
139 return err
140 }
141
137 - encoded := "/" + rp.Namespace() + "/" + enc.Encode(rp.Cid())
138 - if remainder := rp.Remainder(); remainder != "" {
139 - encoded += "/" + remainder
142 + // Trick to encode path with correct encoding.
143 + encodedPath := "/" + rp.Namespace() + "/" + enc.Encode(rp.RootCid())
144 + if len(remainder) != 0 {
145 + encodedPath += path.SegmentsToString(remainder...)
146 + }
147 +
148 + // Ensure valid and sanitized.
149 + ep, err := path.NewPath(encodedPath)
150 + if err != nil {
151 + return err
152 }
153
142 - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(encoded)})
154 + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ep.String()})
155 },
156 Encoders: cmds.EncoderMap{
157 cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, rp *ncmd.ResolvedPath) error {
146 - fmt.Fprintln(w, rp.Path.String())
158 + fmt.Fprintln(w, rp.Path)
159 return nil
160 }),
161 },
core/commands/routing.go
+4 -3
@@ -6,6 +6,7 @@ import (
6 "errors"
7 "fmt"
8 "io"
9 + "strings"
10 "time"
11
12 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
@@ -13,7 +14,6 @@ import (
14 iface "github.com/ipfs/boxo/coreiface"
15 "github.com/ipfs/boxo/coreiface/options"
16 dag "github.com/ipfs/boxo/ipld/merkledag"
16 - path "github.com/ipfs/boxo/path"
17 cid "github.com/ipfs/go-cid"
18 cmds "github.com/ipfs/go-ipfs-cmds"
19 ipld "github.com/ipfs/go-ipld-format"
@@ -549,7 +549,7 @@ func printEvent(obj *routing.QueryEvent, out io.Writer, verbose bool, override p
549 }
550
551 func escapeDhtKey(s string) (string, error) {
552 - parts := path.SplitList(s)
552 + parts := strings.Split(s, "/")
553 if len(parts) != 3 ||
554 parts[0] != "" ||
555 !(parts[1] == "ipns" || parts[1] == "pk") {
@@ -560,5 +560,6 @@ func escapeDhtKey(s string) (string, error) {
560 if err != nil {
561 return "", err
562 }
563 - return path.Join(append(parts[:2], string(k))), nil
563 +
564 + return strings.Join(append(parts[:2], string(k)), "/"), nil
565 }
core/commands/tar.go
+7 -2
@@ -6,9 +6,9 @@ import (
6
7 cmds "github.com/ipfs/go-ipfs-cmds"
8 "github.com/ipfs/kubo/core/commands/cmdenv"
9 + "github.com/ipfs/kubo/core/commands/cmdutils"
10 tar "github.com/ipfs/kubo/tar"
11
11 - path "github.com/ipfs/boxo/coreiface/path"
12 dag "github.com/ipfs/boxo/ipld/merkledag"
13 )
14
@@ -93,7 +93,12 @@ var tarCatCmd = &cmds.Command{
93 return err
94 }
95
96 - root, err := api.ResolveNode(req.Context, path.New(req.Arguments[0]))
96 + p, err := cmdutils.PathOrCidPath(req.Arguments[0])
97 + if err != nil {
98 + return err
99 + }
100 +
101 + root, err := api.ResolveNode(req.Context, p)
102 if err != nil {
103 return err
104 }
core/commands/unixfs/ls.go
+7 -2
@@ -7,8 +7,8 @@ import (
7 "text/tabwriter"
8
9 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
10 + "github.com/ipfs/kubo/core/commands/cmdutils"
11
11 - path "github.com/ipfs/boxo/coreiface/path"
12 merkledag "github.com/ipfs/boxo/ipld/merkledag"
13 unixfs "github.com/ipfs/boxo/ipld/unixfs"
14 cmds "github.com/ipfs/go-ipfs-cmds"
@@ -96,7 +96,12 @@ If possible, please use 'ipfs ls' instead.
96 for _, p := range paths {
97 ctx := req.Context
98
99 - merkleNode, err := api.ResolveNode(ctx, path.New(p))
99 + pth, err := cmdutils.PathOrCidPath(p)
100 + if err != nil {
101 + return err
102 + }
103 +
104 + merkleNode, err := api.ResolveNode(ctx, pth)
105 if err != nil {
106 return err
107 }
core/commands/urlstore.go
+1 -1
@@ -92,7 +92,7 @@ settings for 'ipfs add'.
92 }
93 size, _ := file.Size()
94 return cmds.EmitOnce(res, &BlockStat{
95 - Key: enc.Encode(path.Cid()),
95 + Key: enc.Encode(path.RootCid()),
96 Size: int(size),
97 })
98 },
core/coreapi/block.go
+11 -11
@@ -8,7 +8,7 @@ import (
8
9 coreiface "github.com/ipfs/boxo/coreiface"
10 caopts "github.com/ipfs/boxo/coreiface/options"
11 - path "github.com/ipfs/boxo/coreiface/path"
11 + "github.com/ipfs/boxo/path"
12 pin "github.com/ipfs/boxo/pinning/pinner"
13 blocks "github.com/ipfs/go-block-format"
14 cid "github.com/ipfs/go-cid"
@@ -22,7 +22,7 @@ import (
22 type BlockAPI CoreAPI
23
24 type BlockStat struct {
25 - path path.Resolved
25 + path path.ImmutablePath
26 size int
27 }
28
@@ -68,18 +68,18 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc
68 }
69 }
70
71 - return &BlockStat{path: path.IpldPath(b.Cid()), size: len(data)}, nil
71 + return &BlockStat{path: path.FromCid(b.Cid()), size: len(data)}, nil
72 }
73
74 func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) {
75 ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Get", trace.WithAttributes(attribute.String("path", p.String())))
76 defer span.End()
77 - rp, err := api.core().ResolvePath(ctx, p)
77 + rp, _, err := api.core().ResolvePath(ctx, p)
78 if err != nil {
79 return nil, err
80 }
81
82 - b, err := api.blocks.GetBlock(ctx, rp.Cid())
82 + b, err := api.blocks.GetBlock(ctx, rp.RootCid())
83 if err != nil {
84 return nil, err
85 }
@@ -91,7 +91,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm
91 ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Rm", trace.WithAttributes(attribute.String("path", p.String())))
92 defer span.End()
93
94 - rp, err := api.core().ResolvePath(ctx, p)
94 + rp, _, err := api.core().ResolvePath(ctx, p)
95 if err != nil {
96 return err
97 }
@@ -100,7 +100,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm
100 if err != nil {
101 return err
102 }
103 - cids := []cid.Cid{rp.Cid()}
103 + cids := []cid.Cid{rp.RootCid()}
104 o := util.RmBlocksOpts{Force: settings.Force}
105
106 out, err := util.RmBlocks(ctx, api.blockstore, api.pinning, cids, o)
@@ -132,18 +132,18 @@ func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (coreiface.BlockStat
132 ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Stat", trace.WithAttributes(attribute.String("path", p.String())))
133 defer span.End()
134
135 - rp, err := api.core().ResolvePath(ctx, p)
135 + rp, _, err := api.core().ResolvePath(ctx, p)
136 if err != nil {
137 return nil, err
138 }
139
140 - b, err := api.blocks.GetBlock(ctx, rp.Cid())
140 + b, err := api.blocks.GetBlock(ctx, rp.RootCid())
141 if err != nil {
142 return nil, err
143 }
144
145 return &BlockStat{
146 - path: path.IpldPath(b.Cid()),
146 + path: path.FromCid(b.Cid()),
147 size: len(b.RawData()),
148 }, nil
149 }
@@ -152,7 +152,7 @@ func (bs *BlockStat) Size() int {
152 return bs.size
153 }
154
155 -func (bs *BlockStat) Path() path.Resolved {
155 +func (bs *BlockStat) Path() path.ImmutablePath {
156 return bs.path
157 }
158
core/coreapi/dht.go
+5 -5
@@ -8,9 +8,9 @@ import (
8 blockstore "github.com/ipfs/boxo/blockstore"
9 coreiface "github.com/ipfs/boxo/coreiface"
10 caopts "github.com/ipfs/boxo/coreiface/options"
11 - path "github.com/ipfs/boxo/coreiface/path"
11 offline "github.com/ipfs/boxo/exchange/offline"
12 dag "github.com/ipfs/boxo/ipld/merkledag"
13 + "github.com/ipfs/boxo/path"
14 cid "github.com/ipfs/go-cid"
15 cidutil "github.com/ipfs/go-cidutil"
16 "github.com/ipfs/kubo/tracing"
@@ -53,7 +53,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt
53 return nil, err
54 }
55
56 - rp, err := api.core().ResolvePath(ctx, p)
56 + rp, _, err := api.core().ResolvePath(ctx, p)
57 if err != nil {
58 return nil, err
59 }
@@ -63,7 +63,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt
63 return nil, fmt.Errorf("number of providers must be greater than 0")
64 }
65
66 - pchan := api.routing.FindProvidersAsync(ctx, rp.Cid(), numProviders)
66 + pchan := api.routing.FindProvidersAsync(ctx, rp.RootCid(), numProviders)
67 return pchan, nil
68 }
69
@@ -82,12 +82,12 @@ func (api *DhtAPI) Provide(ctx context.Context, path path.Path, opts ...caopts.D
82 return err
83 }
84
85 - rp, err := api.core().ResolvePath(ctx, path)
85 + rp, _, err := api.core().ResolvePath(ctx, path)
86 if err != nil {
87 return err
88 }
89
90 - c := rp.Cid()
90 + c := rp.RootCid()
91
92 has, err := api.blockstore.Has(ctx, c)
93 if err != nil {
core/coreapi/key.go
+36 -10
@@ -9,8 +9,8 @@ import (
9
10 coreiface "github.com/ipfs/boxo/coreiface"
11 caopts "github.com/ipfs/boxo/coreiface/options"
12 - path "github.com/ipfs/boxo/coreiface/path"
13 - ipfspath "github.com/ipfs/boxo/path"
12 + "github.com/ipfs/boxo/ipns"
13 + "github.com/ipfs/boxo/path"
14 "github.com/ipfs/kubo/tracing"
15 crypto "github.com/libp2p/go-libp2p/core/crypto"
16 peer "github.com/libp2p/go-libp2p/core/peer"
@@ -23,6 +23,19 @@ type KeyAPI CoreAPI
23 type key struct {
24 name string
25 peerID peer.ID
26 + path path.Path
27 +}
28 +
29 +func newKey(name string, pid peer.ID) (*key, error) {
30 + p, err := path.NewPath("/ipns/" + ipns.NameFromPeer(pid).String())
31 + if err != nil {
32 + return nil, err
33 + }
34 + return &key{
35 + name: name,
36 + peerID: pid,
37 + path: p,
38 + }, nil
39 }
40
41 // Name returns the key name
@@ -32,7 +45,7 @@ func (k *key) Name() string {
45
46 // Path returns the path of the key.
47 func (k *key) Path() path.Path {
35 - return path.New(ipfspath.Join([]string{"/ipns", coreiface.FormatKeyID(k.peerID)}))
48 + return k.path
49 }
50
51 // ID returns key PeerID
@@ -98,7 +111,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
111 return nil, err
112 }
113
101 - return &key{name, pid}, nil
114 + return newKey(name, pid)
115 }
116
117 // List returns a list keys stored in keystore.
@@ -114,7 +127,10 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) {
127 sort.Strings(keys)
128
129 out := make([]coreiface.Key, len(keys)+1)
117 - out[0] = &key{"self", api.identity}
130 + out[0], err = newKey("self", api.identity)
131 + if err != nil {
132 + return nil, err
133 + }
134
135 for n, k := range keys {
136 privKey, err := api.repo.Keystore().Get(k)
@@ -129,7 +145,10 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) {
145 return nil, err
146 }
147
132 - out[n+1] = &key{k, pid}
148 + out[n+1], err = newKey(k, pid)
149 + if err != nil {
150 + return nil, err
151 + }
152 }
153 return out, nil
154 }
@@ -171,7 +190,8 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o
190 // This is important, because future code will delete key `oldName`
191 // even if it is the same as newName.
192 if newName == oldName {
174 - return &key{oldName, pid}, false, nil
193 + k, err := newKey(oldName, pid)
194 + return k, false, err
195 }
196
197 overwrite := false
@@ -195,7 +215,13 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o
215 return nil, false, err
216 }
217
198 - return &key{newName, pid}, overwrite, ks.Delete(oldName)
218 + err = ks.Delete(oldName)
219 + if err != nil {
220 + return nil, false, err
221 + }
222 +
223 + k, err := newKey(newName, pid)
224 + return k, overwrite, err
225 }
226
227 // Remove removes keys from keystore. Returns ipns path of the removed key.
@@ -226,7 +252,7 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Key, erro
252 return nil, err
253 }
254
229 - return &key{"", pid}, nil
255 + return newKey("", pid)
256 }
257
258 func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) {
@@ -234,5 +260,5 @@ func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) {
260 return nil, errors.New("identity not loaded")
261 }
262
237 - return &key{"self", api.identity}, nil
263 + return newKey("self", api.identity)
264 }
core/coreapi/name.go
+3 -9
@@ -16,8 +16,7 @@ import (
16 coreiface "github.com/ipfs/boxo/coreiface"
17 caopts "github.com/ipfs/boxo/coreiface/options"
18 nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
19 - path "github.com/ipfs/boxo/coreiface/path"
20 - ipath "github.com/ipfs/boxo/path"
19 + "github.com/ipfs/boxo/path"
20 ci "github.com/libp2p/go-libp2p/core/crypto"
21 peer "github.com/libp2p/go-libp2p/core/peer"
22 )
@@ -51,11 +50,6 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam
50 return ipns.Name{}, err
51 }
52
54 - pth, err := ipath.ParsePath(p.String())
55 - if err != nil {
56 - return ipns.Name{}, err
57 - }
58 -
53 k, err := keylookup(api.privateKey, api.repo.Keystore(), options.Key)
54 if err != nil {
55 return ipns.Name{}, err
@@ -72,7 +66,7 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam
66 publishOptions = append(publishOptions, nsopts.PublishWithTTL(*options.TTL))
67 }
68
75 - err = api.namesys.Publish(ctx, k, pth, publishOptions...)
69 + err = api.namesys.Publish(ctx, k, p, publishOptions...)
70 if err != nil {
71 return ipns.Name{}, err
72 }
@@ -120,7 +114,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name
114 defer close(out)
115 for res := range resolver.ResolveAsync(ctx, name, options.ResolveOpts...) {
116 select {
123 - case out <- coreiface.IpnsResult{Path: path.New(res.Path.String()), Err: res.Err}:
117 + case out <- coreiface.IpnsResult{Path: res.Path, Err: res.Err}:
118 case <-ctx.Done():
119 return
120 }
core/coreapi/object.go
+19 -19
@@ -12,10 +12,10 @@ import (
12
13 coreiface "github.com/ipfs/boxo/coreiface"
14 caopts "github.com/ipfs/boxo/coreiface/options"
15 - ipath "github.com/ipfs/boxo/coreiface/path"
15 dag "github.com/ipfs/boxo/ipld/merkledag"
16 "github.com/ipfs/boxo/ipld/merkledag/dagutils"
17 ft "github.com/ipfs/boxo/ipld/unixfs"
18 + "github.com/ipfs/boxo/path"
19 pin "github.com/ipfs/boxo/pinning/pinner"
20 cid "github.com/ipfs/go-cid"
21 ipld "github.com/ipfs/go-ipld-format"
@@ -65,7 +65,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (
65 return n, nil
66 }
67
68 -func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (ipath.Resolved, error) {
68 +func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) {
69 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Put")
70 defer span.End()
71
@@ -143,16 +143,16 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj
143 }
144 }
145
146 - return ipath.IpfsPath(dagnode.Cid()), nil
146 + return path.FromCid(dagnode.Cid()), nil
147 }
148
149 -func (api *ObjectAPI) Get(ctx context.Context, path ipath.Path) (ipld.Node, error) {
149 +func (api *ObjectAPI) Get(ctx context.Context, path path.Path) (ipld.Node, error) {
150 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Get", trace.WithAttributes(attribute.String("path", path.String())))
151 defer span.End()
152 return api.core().ResolveNode(ctx, path)
153 }
154
155 -func (api *ObjectAPI) Data(ctx context.Context, path ipath.Path) (io.Reader, error) {
155 +func (api *ObjectAPI) Data(ctx context.Context, path path.Path) (io.Reader, error) {
156 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Data", trace.WithAttributes(attribute.String("path", path.String())))
157 defer span.End()
158
@@ -169,7 +169,7 @@ func (api *ObjectAPI) Data(ctx context.Context, path ipath.Path) (io.Reader, err
169 return bytes.NewReader(pbnd.Data()), nil
170 }
171
172 -func (api *ObjectAPI) Links(ctx context.Context, path ipath.Path) ([]*ipld.Link, error) {
172 +func (api *ObjectAPI) Links(ctx context.Context, path path.Path) ([]*ipld.Link, error) {
173 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Links", trace.WithAttributes(attribute.String("path", path.String())))
174 defer span.End()
175
@@ -187,7 +187,7 @@ func (api *ObjectAPI) Links(ctx context.Context, path ipath.Path) ([]*ipld.Link,
187 return out, nil
188 }
189
190 -func (api *ObjectAPI) Stat(ctx context.Context, path ipath.Path) (*coreiface.ObjectStat, error) {
190 +func (api *ObjectAPI) Stat(ctx context.Context, path path.Path) (*coreiface.ObjectStat, error) {
191 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Stat", trace.WithAttributes(attribute.String("path", path.String())))
192 defer span.End()
193
@@ -213,7 +213,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, path ipath.Path) (*coreiface.Obj
213 return out, nil
214 }
215
216 -func (api *ObjectAPI) AddLink(ctx context.Context, base ipath.Path, name string, child ipath.Path, opts ...caopts.ObjectAddLinkOption) (ipath.Resolved, error) {
216 +func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) {
217 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AddLink", trace.WithAttributes(
218 attribute.String("base", base.String()),
219 attribute.String("name", name),
@@ -259,10 +259,10 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base ipath.Path, name string,
259 return nil, err
260 }
261
262 - return ipath.IpfsPath(nnode.Cid()), nil
262 + return path.FromCid(nnode.Cid()), nil
263 }
264
265 -func (api *ObjectAPI) RmLink(ctx context.Context, base ipath.Path, link string) (ipath.Resolved, error) {
265 +func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) {
266 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "RmLink", trace.WithAttributes(
267 attribute.String("base", base.String()),
268 attribute.String("link", link)),
@@ -291,25 +291,25 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base ipath.Path, link string)
291 return nil, err
292 }
293
294 - return ipath.IpfsPath(nnode.Cid()), nil
294 + return path.FromCid(nnode.Cid()), nil
295 }
296
297 -func (api *ObjectAPI) AppendData(ctx context.Context, path ipath.Path, r io.Reader) (ipath.Resolved, error) {
297 +func (api *ObjectAPI) AppendData(ctx context.Context, path path.Path, r io.Reader) (path.ImmutablePath, error) {
298 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AppendData", trace.WithAttributes(attribute.String("path", path.String())))
299 defer span.End()
300
301 return api.patchData(ctx, path, r, true)
302 }
303
304 -func (api *ObjectAPI) SetData(ctx context.Context, path ipath.Path, r io.Reader) (ipath.Resolved, error) {
304 +func (api *ObjectAPI) SetData(ctx context.Context, path path.Path, r io.Reader) (path.ImmutablePath, error) {
305 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "SetData", trace.WithAttributes(attribute.String("path", path.String())))
306 defer span.End()
307
308 return api.patchData(ctx, path, r, false)
309 }
310
311 -func (api *ObjectAPI) patchData(ctx context.Context, path ipath.Path, r io.Reader, appendData bool) (ipath.Resolved, error) {
312 - nd, err := api.core().ResolveNode(ctx, path)
311 +func (api *ObjectAPI) patchData(ctx context.Context, p path.Path, r io.Reader, appendData bool) (path.ImmutablePath, error) {
312 + nd, err := api.core().ResolveNode(ctx, p)
313 if err != nil {
314 return nil, err
315 }
@@ -334,10 +334,10 @@ func (api *ObjectAPI) patchData(ctx context.Context, path ipath.Path, r io.Reade
334 return nil, err
335 }
336
337 - return ipath.IpfsPath(pbnd.Cid()), nil
337 + return path.FromCid(pbnd.Cid()), nil
338 }
339
340 -func (api *ObjectAPI) Diff(ctx context.Context, before ipath.Path, after ipath.Path) ([]coreiface.ObjectChange, error) {
340 +func (api *ObjectAPI) Diff(ctx context.Context, before path.Path, after path.Path) ([]coreiface.ObjectChange, error) {
341 ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Diff", trace.WithAttributes(
342 attribute.String("before", before.String()),
343 attribute.String("after", after.String()),
@@ -367,11 +367,11 @@ func (api *ObjectAPI) Diff(ctx context.Context, before ipath.Path, after ipath.P
367 }
368
369 if change.Before.Defined() {
370 - out[i].Before = ipath.IpfsPath(change.Before)
370 + out[i].Before = path.FromCid(change.Before)
371 }
372
373 if change.After.Defined() {
374 - out[i].After = ipath.IpfsPath(change.After)
374 + out[i].After = path.FromCid(change.After)
375 }
376 }
377
core/coreapi/path.go
+30 -29
@@ -3,7 +3,6 @@ package coreapi
3 import (
4 "context"
5 "fmt"
6 - gopath "path"
6
7 "github.com/ipfs/boxo/namesys/resolve"
8 "github.com/ipfs/kubo/tracing"
@@ -12,10 +11,8 @@ import (
11 "go.opentelemetry.io/otel/trace"
12
13 coreiface "github.com/ipfs/boxo/coreiface"
15 - path "github.com/ipfs/boxo/coreiface/path"
16 - ipfspath "github.com/ipfs/boxo/path"
14 + "github.com/ipfs/boxo/path"
15 ipfspathresolver "github.com/ipfs/boxo/path/resolver"
18 - "github.com/ipfs/go-cid"
16 ipld "github.com/ipfs/go-ipld-format"
17 )
18
@@ -25,12 +22,12 @@ func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, er
22 ctx, span := tracing.Span(ctx, "CoreAPI", "ResolveNode", trace.WithAttributes(attribute.String("path", p.String())))
23 defer span.End()
24
28 - rp, err := api.ResolvePath(ctx, p)
25 + rp, _, err := api.ResolvePath(ctx, p)
26 if err != nil {
27 return nil, err
28 }
29
33 - node, err := api.dag.Get(ctx, rp.Cid())
30 + node, err := api.dag.Get(ctx, rp.RootCid())
31 if err != nil {
32 return nil, err
33 }
@@ -39,45 +36,49 @@ func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, er
36
37 // ResolvePath resolves the path `p` using Unixfs resolver, returns the
38 // resolved path.
42 -func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) {
39 +func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.ImmutablePath, []string, error) {
40 ctx, span := tracing.Span(ctx, "CoreAPI", "ResolvePath", trace.WithAttributes(attribute.String("path", p.String())))
41 defer span.End()
42
46 - if _, ok := p.(path.Resolved); ok {
47 - return p.(path.Resolved), nil
48 - }
49 - if err := p.IsValid(); err != nil {
50 - return nil, err
51 - }
52 -
53 - ipath := ipfspath.Path(p.String())
54 - ipath, err := resolve.ResolveIPNS(ctx, api.namesys, ipath)
43 + p, err := resolve.ResolveIPNS(ctx, api.namesys, p)
44 if err == resolve.ErrNoNamesys {
56 - return nil, coreiface.ErrOffline
45 + return nil, nil, coreiface.ErrOffline
46 } else if err != nil {
58 - return nil, err
59 - }
60 -
61 - if ipath.Segments()[0] != "ipfs" && ipath.Segments()[0] != "ipld" {
62 - return nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace())
47 + return nil, nil, err
48 }
49
50 var resolver ipfspathresolver.Resolver
66 - if ipath.Segments()[0] == "ipld" {
51 + switch p.Namespace() {
52 + case path.IPLDNamespace:
53 resolver = api.ipldPathResolver
68 - } else {
54 + case path.IPFSNamespace:
55 resolver = api.unixFSPathResolver
56 + default:
57 + return nil, nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace())
58 }
59
72 - node, rest, err := resolver.ResolveToLastNode(ctx, ipath)
60 + imPath, err := path.NewImmutablePath(p)
61 if err != nil {
74 - return nil, err
62 + return nil, nil, err
63 }
64
77 - root, err := cid.Parse(ipath.Segments()[1])
65 + node, remainder, err := resolver.ResolveToLastNode(ctx, imPath)
66 if err != nil {
79 - return nil, err
67 + return nil, nil, err
68 + }
69 +
70 + segments := []string{p.Namespace(), node.String()}
71 + segments = append(segments, remainder...)
72 +
73 + p, err = path.NewPathFromSegments(segments...)
74 + if err != nil {
75 + return nil, nil, err
76 + }
77 +
78 + imPath, err = path.NewImmutablePath(p)
79 + if err != nil {
80 + return nil, nil, err
81 }
82
82 - return path.NewResolvedPath(ipath, node, root, gopath.Join(rest...)), nil
83 + return imPath, remainder, nil
84 }
core/coreapi/pin.go
+14 -14
@@ -7,9 +7,9 @@ import (
7 bserv "github.com/ipfs/boxo/blockservice"
8 coreiface "github.com/ipfs/boxo/coreiface"
9 caopts "github.com/ipfs/boxo/coreiface/options"
10 - "github.com/ipfs/boxo/coreiface/path"
10 offline "github.com/ipfs/boxo/exchange/offline"
11 "github.com/ipfs/boxo/ipld/merkledag"
12 + "github.com/ipfs/boxo/path"
13 pin "github.com/ipfs/boxo/pinning/pinner"
14 "github.com/ipfs/go-cid"
15 "go.opentelemetry.io/otel/attribute"
@@ -74,7 +74,7 @@ func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.Pin
74 ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "IsPinned", trace.WithAttributes(attribute.String("path", p.String())))
75 defer span.End()
76
77 - resolved, err := api.core().ResolvePath(ctx, p)
77 + resolved, _, err := api.core().ResolvePath(ctx, p)
78 if err != nil {
79 return "", false, fmt.Errorf("error resolving path: %s", err)
80 }
@@ -91,7 +91,7 @@ func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.Pin
91 return "", false, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.WithType)
92 }
93
94 - return api.pinning.IsPinnedWithType(ctx, resolved.Cid(), mode)
94 + return api.pinning.IsPinnedWithType(ctx, resolved.RootCid(), mode)
95 }
96
97 // Rm pin rm api
@@ -99,7 +99,7 @@ func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOpti
99 ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "Rm", trace.WithAttributes(attribute.String("path", p.String())))
100 defer span.End()
101
102 - rp, err := api.core().ResolvePath(ctx, p)
102 + rp, _, err := api.core().ResolvePath(ctx, p)
103 if err != nil {
104 return err
105 }
@@ -115,7 +115,7 @@ func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOpti
115 // to take a lock to prevent a concurrent garbage collection
116 defer api.blockstore.PinLock(ctx).Unlock(ctx)
117
118 - if err = api.pinning.Unpin(ctx, rp.Cid(), settings.Recursive); err != nil {
118 + if err = api.pinning.Unpin(ctx, rp.RootCid(), settings.Recursive); err != nil {
119 return err
120 }
121
@@ -136,19 +136,19 @@ func (api *PinAPI) Update(ctx context.Context, from path.Path, to path.Path, opt
136
137 span.SetAttributes(attribute.Bool("unpin", settings.Unpin))
138
139 - fp, err := api.core().ResolvePath(ctx, from)
139 + fp, _, err := api.core().ResolvePath(ctx, from)
140 if err != nil {
141 return err
142 }
143
144 - tp, err := api.core().ResolvePath(ctx, to)
144 + tp, _, err := api.core().ResolvePath(ctx, to)
145 if err != nil {
146 return err
147 }
148
149 defer api.blockstore.PinLock(ctx).Unlock(ctx)
150
151 - err = api.pinning.Update(ctx, fp.Cid(), tp.Cid(), settings.Unpin)
151 + err = api.pinning.Update(ctx, fp.RootCid(), tp.RootCid(), settings.Unpin)
152 if err != nil {
153 return err
154 }
@@ -165,7 +165,7 @@ type pinStatus struct {
165
166 // BadNode is used in PinVerifyRes
167 type badNode struct {
168 - path path.Resolved
168 + path path.ImmutablePath
169 err error
170 }
171
@@ -181,7 +181,7 @@ func (s *pinStatus) Err() error {
181 return s.err
182 }
183
184 -func (n *badNode) Path() path.Resolved {
184 +func (n *badNode) Path() path.ImmutablePath {
185 return n.path
186 }
187
@@ -210,7 +210,7 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro
210 links, err := getLinks(ctx, root)
211 if err != nil {
212 status := &pinStatus{ok: false, cid: root}
213 - status.badNodes = []coreiface.BadPinNode{&badNode{path: path.IpldPath(root), err: err}}
213 + status.badNodes = []coreiface.BadPinNode{&badNode{path: path.FromCid(root), err: err}}
214 visited[root] = status
215 return status
216 }
@@ -251,11 +251,11 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro
251
252 type pinInfo struct {
253 pinType string
254 - path path.Resolved
254 + path path.ImmutablePath
255 err error
256 }
257
258 -func (p *pinInfo) Path() path.Resolved {
258 +func (p *pinInfo) Path() path.ImmutablePath {
259 return p.path
260 }
261
@@ -281,7 +281,7 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac
281 select {
282 case out <- &pinInfo{
283 pinType: typeStr,
284 - path: path.IpldPath(c),
284 + path: path.FromCid(c),
285 }:
286 case <-ctx.Done():
287 return ctx.Err()
core/coreapi/routing.go
+3 -3
@@ -3,10 +3,10 @@ package coreapi
3 import (
4 "context"
5 "errors"
6 + "strings"
7
8 coreiface "github.com/ipfs/boxo/coreiface"
9 caopts "github.com/ipfs/boxo/coreiface/options"
9 - "github.com/ipfs/boxo/path"
10 peer "github.com/libp2p/go-libp2p/core/peer"
11 )
12
@@ -45,7 +45,7 @@ func (r *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts ...
45 }
46
47 func normalizeKey(s string) (string, error) {
48 - parts := path.SplitList(s)
48 + parts := strings.Split(s, "/")
49 if len(parts) != 3 ||
50 parts[0] != "" ||
51 !(parts[1] == "ipns" || parts[1] == "pk") {
@@ -56,5 +56,5 @@ func normalizeKey(s string) (string, error) {
56 if err != nil {
57 return "", err
58 }
59 - return path.Join(append(parts[:2], string(k))), nil
59 + return strings.Join(append(parts[:2], string(k)), "/"), nil
60 }
core/coreapi/test/path_test.go
+9 -4
@@ -7,10 +7,10 @@ import (
7 "time"
8
9 "github.com/ipfs/boxo/coreiface/options"
10 - "github.com/ipfs/boxo/coreiface/path"
10 "github.com/ipfs/boxo/files"
11 "github.com/ipfs/boxo/ipld/merkledag"
12 uio "github.com/ipfs/boxo/ipld/unixfs/io"
13 + "github.com/ipfs/boxo/path"
14 "github.com/ipld/go-ipld-prime"
15 )
16
@@ -45,7 +45,7 @@ func TestPathUnixFSHAMTPartial(t *testing.T) {
45 }
46
47 // Get the root of the directory
48 - nd, err := a.Dag().Get(ctx, r.Cid())
48 + nd, err := a.Dag().Get(ctx, r.RootCid())
49 if err != nil {
50 t.Fatal(err)
51 }
@@ -55,7 +55,7 @@ func TestPathUnixFSHAMTPartial(t *testing.T) {
55 pbNode := nd.(*merkledag.ProtoNode)
56
57 // Remove one of the sharded directory blocks
58 - if err := a.Block().Rm(ctx, path.IpfsPath(pbNode.Links()[0].Cid)); err != nil {
58 + if err := a.Block().Rm(ctx, path.FromCid(pbNode.Links()[0].Cid)); err != nil {
59 t.Fatal(err)
60 }
61
@@ -67,7 +67,12 @@ func TestPathUnixFSHAMTPartial(t *testing.T) {
67 // The node will go out to the (non-existent) network looking for the missing block. Make sure we're erroring
68 // because we exceeded the timeout on our query
69 timeoutCtx, timeoutCancel := context.WithTimeout(ctx, time.Second*1)
70 - _, err := a.ResolveNode(timeoutCtx, path.Join(r, k))
70 + newPath, err := path.Join(r, k)
71 + if err != nil {
72 + t.Fatal(err)
73 + }
74 +
75 + _, err = a.ResolveNode(timeoutCtx, newPath)
76 if err != nil {
77 if timeoutCtx.Err() == nil {
78 t.Fatal(err)
core/coreapi/unixfs.go
+3 -3
@@ -16,7 +16,6 @@ import (
16 bstore "github.com/ipfs/boxo/blockstore"
17 coreiface "github.com/ipfs/boxo/coreiface"
18 options "github.com/ipfs/boxo/coreiface/options"
19 - path "github.com/ipfs/boxo/coreiface/path"
19 "github.com/ipfs/boxo/files"
20 filestore "github.com/ipfs/boxo/filestore"
21 merkledag "github.com/ipfs/boxo/ipld/merkledag"
@@ -25,6 +24,7 @@ import (
24 unixfile "github.com/ipfs/boxo/ipld/unixfs/file"
25 uio "github.com/ipfs/boxo/ipld/unixfs/io"
26 mfs "github.com/ipfs/boxo/mfs"
27 + "github.com/ipfs/boxo/path"
28 cid "github.com/ipfs/go-cid"
29 cidutil "github.com/ipfs/go-cidutil"
30 ipld "github.com/ipfs/go-ipld-format"
@@ -58,7 +58,7 @@ func getOrCreateNilNode() (*core.IpfsNode, error) {
58
59 // Add builds a merkledag node from a reader, adds it to the blockstore,
60 // and returns the key representing that node.
61 -func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options.UnixfsAddOption) (path.Resolved, error) {
61 +func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options.UnixfsAddOption) (path.ImmutablePath, error) {
62 ctx, span := tracing.Span(ctx, "CoreAPI.UnixfsAPI", "Add")
63 defer span.End()
64
@@ -201,7 +201,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options
201 }
202 }
203
204 - return path.IpfsPath(nd.Cid()), nil
204 + return path.FromCid(nd.Cid()), nil
205 }
206
207 func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) {
core/corehttp/commands.go
+1 -2
@@ -9,7 +9,6 @@ import (
9 "strconv"
10 "strings"
11
12 - path "github.com/ipfs/boxo/path"
12 cmds "github.com/ipfs/go-ipfs-cmds"
13 cmdsHttp "github.com/ipfs/go-ipfs-cmds/http"
14 version "github.com/ipfs/kubo"
@@ -171,7 +170,7 @@ func CheckVersionOption() ServeOption {
170 parent.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
171 if strings.HasPrefix(r.URL.Path, APIPath) {
172 cmdqry := r.URL.Path[len(APIPath):]
174 - pth := path.SplitList(cmdqry)
173 + pth := strings.Split(cmdqry, "/")
174
175 // backwards compatibility to previous version check
176 if len(pth) >= 2 && pth[1] != "version" {
core/corehttp/gateway.go
+8 -8
@@ -10,11 +10,11 @@ import (
10
11 "github.com/ipfs/boxo/blockservice"
12 iface "github.com/ipfs/boxo/coreiface"
13 - "github.com/ipfs/boxo/coreiface/path"
13 "github.com/ipfs/boxo/exchange/offline"
14 "github.com/ipfs/boxo/files"
15 "github.com/ipfs/boxo/gateway"
16 "github.com/ipfs/boxo/namesys"
17 + "github.com/ipfs/boxo/path"
18 offlineroute "github.com/ipfs/boxo/routing/offline"
19 "github.com/ipfs/go-cid"
20 version "github.com/ipfs/kubo"
@@ -149,37 +149,37 @@ func offlineErrWrap(err error) error {
149 return err
150 }
151
152 -func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path gateway.ImmutablePath, ranges ...gateway.ByteRange) (gateway.ContentPathMetadata, *gateway.GetResponse, error) {
152 +func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path path.ImmutablePath, ranges ...gateway.ByteRange) (gateway.ContentPathMetadata, *gateway.GetResponse, error) {
153 md, n, err := o.gwimpl.Get(ctx, path, ranges...)
154 err = offlineErrWrap(err)
155 return md, n, err
156 }
157
158 -func (o *offlineGatewayErrWrapper) GetAll(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) {
158 +func (o *offlineGatewayErrWrapper) GetAll(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) {
159 md, n, err := o.gwimpl.GetAll(ctx, path)
160 err = offlineErrWrap(err)
161 return md, n, err
162 }
163
164 -func (o *offlineGatewayErrWrapper) GetBlock(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.File, error) {
164 +func (o *offlineGatewayErrWrapper) GetBlock(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, files.File, error) {
165 md, n, err := o.gwimpl.GetBlock(ctx, path)
166 err = offlineErrWrap(err)
167 return md, n, err
168 }
169
170 -func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, *gateway.HeadResponse, error) {
170 +func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, *gateway.HeadResponse, error) {
171 md, n, err := o.gwimpl.Head(ctx, path)
172 err = offlineErrWrap(err)
173 return md, n, err
174 }
175
176 -func (o *offlineGatewayErrWrapper) ResolvePath(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, error) {
176 +func (o *offlineGatewayErrWrapper) ResolvePath(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, error) {
177 md, err := o.gwimpl.ResolvePath(ctx, path)
178 err = offlineErrWrap(err)
179 return md, err
180 }
181
182 -func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path gateway.ImmutablePath, params gateway.CarParams) (gateway.ContentPathMetadata, io.ReadCloser, error) {
182 +func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path path.ImmutablePath, params gateway.CarParams) (gateway.ContentPathMetadata, io.ReadCloser, error) {
183 md, data, err := o.gwimpl.GetCAR(ctx, path, params)
184 err = offlineErrWrap(err)
185 return md, data, err
@@ -195,7 +195,7 @@ func (o *offlineGatewayErrWrapper) GetIPNSRecord(ctx context.Context, c cid.Cid)
195 return rec, err
196 }
197
198 -func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (gateway.ImmutablePath, error) {
198 +func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (path.ImmutablePath, error) {
199 imPath, err := o.gwimpl.ResolveMutable(ctx, path)
200 err = offlineErrWrap(err)
201 return imPath, err
core/corehttp/gateway_test.go
+1 -1
@@ -46,7 +46,7 @@ func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...nsopts.Re
46 var ok bool
47 value, ok = m[name]
48 if !ok {
49 - return "", namesys.ErrResolveFailed
49 + return nil, namesys.ErrResolveFailed
50 }
51 name = value.String()
52 }
core/coreunix/add.go
+2 -2
@@ -11,7 +11,6 @@ import (
11 bstore "github.com/ipfs/boxo/blockstore"
12 chunker "github.com/ipfs/boxo/chunker"
13 coreiface "github.com/ipfs/boxo/coreiface"
14 - "github.com/ipfs/boxo/coreiface/path"
14 "github.com/ipfs/boxo/files"
15 posinfo "github.com/ipfs/boxo/filestore/posinfo"
16 dag "github.com/ipfs/boxo/ipld/merkledag"
@@ -20,6 +19,7 @@ import (
19 ihelper "github.com/ipfs/boxo/ipld/unixfs/importer/helpers"
20 "github.com/ipfs/boxo/ipld/unixfs/importer/trickle"
21 "github.com/ipfs/boxo/mfs"
22 + "github.com/ipfs/boxo/path"
23 pin "github.com/ipfs/boxo/pinning/pinner"
24 "github.com/ipfs/go-cid"
25 ipld "github.com/ipfs/go-ipld-format"
@@ -506,7 +506,7 @@ func getOutput(dagnode ipld.Node) (*coreiface.AddEvent, error) {
506 }
507
508 output := &coreiface.AddEvent{
509 - Path: path.IpfsPath(c),
509 + Path: path.FromCid(c),
510 Size: strconv.FormatUint(s, 10),
511 }
512
core/coreunix/add_test.go
+4 -4
@@ -133,7 +133,7 @@ func TestAddMultipleGCLive(t *testing.T) {
133 }
134
135 for o := range out {
136 - if _, ok := removedHashes[o.(*coreiface.AddEvent).Path.Cid().String()]; ok {
136 + if _, ok := removedHashes[o.(*coreiface.AddEvent).Path.RootCid().String()]; ok {
137 t.Fatal("gc'ed a hash we just added")
138 }
139 }
@@ -187,7 +187,7 @@ func TestAddGCLive(t *testing.T) {
187 addedHashes := make(map[string]struct{})
188 select {
189 case o := <-out:
190 - addedHashes[o.(*coreiface.AddEvent).Path.Cid().String()] = struct{}{}
190 + addedHashes[o.(*coreiface.AddEvent).Path.RootCid().String()] = struct{}{}
191 case <-addDone:
192 t.Fatal("add shouldn't complete yet")
193 }
@@ -217,7 +217,7 @@ func TestAddGCLive(t *testing.T) {
217
218 // receive next object from adder
219 o := <-out
220 - addedHashes[o.(*coreiface.AddEvent).Path.Cid().String()] = struct{}{}
220 + addedHashes[o.(*coreiface.AddEvent).Path.RootCid().String()] = struct{}{}
221
222 <-gcstarted
223
@@ -233,7 +233,7 @@ func TestAddGCLive(t *testing.T) {
233 var last cid.Cid
234 for a := range out {
235 // wait for it to finish
236 - c, err := cid.Decode(a.(*coreiface.AddEvent).Path.Cid().String())
236 + c, err := cid.Decode(a.(*coreiface.AddEvent).Path.RootCid().String())
237 if err != nil {
238 t.Fatal(err)
239 }
docs/examples/kubo-as-a-library/go.mod
+1 -1
@@ -7,7 +7,7 @@ go 1.20
7 replace github.com/ipfs/kubo => ./../../..
8
9 require (
10 - github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0
10 + github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664
11 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
12 github.com/libp2p/go-libp2p v0.31.0
13 github.com/multiformats/go-multiaddr v0.11.0
docs/examples/kubo-as-a-library/go.sum
+2 -2
@@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
300 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
301 github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
302 github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
303 -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs=
304 -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
303 +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24=
304 +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
305 github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
306 github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
307 github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
docs/examples/kubo-as-a-library/main.go
+3 -3
@@ -12,8 +12,8 @@ import (
12 "sync"
13
14 icore "github.com/ipfs/boxo/coreiface"
15 - icorepath "github.com/ipfs/boxo/coreiface/path"
15 "github.com/ipfs/boxo/files"
16 + "github.com/ipfs/boxo/path"
17 ma "github.com/multiformats/go-multiaddr"
18
19 "github.com/ipfs/kubo/config"
@@ -320,11 +320,11 @@ func main() {
320 }
321 }()
322
323 - exampleCIDStr := peerCidFile.Cid().String()
323 + exampleCIDStr := peerCidFile.RootCid().String()
324
325 fmt.Printf("Fetching a file from the network with CID %s\n", exampleCIDStr)
326 outputPath := outputBasePath + exampleCIDStr
327 - testCID := icorepath.New(exampleCIDStr)
327 + testCID := path.FromCid(peerCidFile.RootCid())
328
329 rootNode, err := ipfsB.Unixfs().Get(ctx, testCID)
330 if err != nil {
fuse/ipns/common.go
+1 -1
@@ -5,7 +5,7 @@ import (
5
6 ft "github.com/ipfs/boxo/ipld/unixfs"
7 nsys "github.com/ipfs/boxo/namesys"
8 - path "github.com/ipfs/boxo/path"
8 + "github.com/ipfs/boxo/path"
9 "github.com/ipfs/kubo/core"
10 ci "github.com/libp2p/go-libp2p/core/crypto"
11 )
fuse/ipns/ipns_unix.go
+3 -3
@@ -14,9 +14,9 @@ import (
14 "strings"
15 "syscall"
16
17 - path "github.com/ipfs/boxo/coreiface/path"
17 dag "github.com/ipfs/boxo/ipld/merkledag"
18 ft "github.com/ipfs/boxo/ipld/unixfs"
19 + "github.com/ipfs/boxo/path"
20
21 fuse "bazil.org/fuse"
22 fs "bazil.org/fuse/fs"
@@ -86,7 +86,7 @@ type Root struct {
86
87 func ipnsPubFunc(ipfs iface.CoreAPI, key iface.Key) mfs.PubFunc {
88 return func(ctx context.Context, c cid.Cid) error {
89 - _, err := ipfs.Name().Publish(ctx, path.IpfsPath(c), options.Name.Key(key.Name()))
89 + _, err := ipfs.Name().Publish(ctx, path.FromCid(c), options.Name.Key(key.Name()))
90 return err
91 }
92 }
@@ -186,7 +186,7 @@ func (r *Root) Lookup(ctx context.Context, name string) (fs.Node, error) {
186 return nil, syscall.Errno(syscall.ENOENT)
187 }
188
189 - if resolved.Namespace() != "ipfs" {
189 + if resolved.Namespace() != path.IPFSNamespace {
190 return nil, errors.New("invalid path from ipns record")
191 }
192
fuse/readonly/ipfs_test.go
+13 -9
@@ -11,7 +11,7 @@ import (
11 "io"
12 "math/rand"
13 "os"
14 - "path"
14 + gopath "path"
15 "strings"
16 "sync"
17 "testing"
@@ -24,11 +24,11 @@ import (
24
25 fstest "bazil.org/fuse/fs/fstestutil"
26 chunker "github.com/ipfs/boxo/chunker"
27 - ipath "github.com/ipfs/boxo/coreiface/path"
27 "github.com/ipfs/boxo/files"
28 dag "github.com/ipfs/boxo/ipld/merkledag"
29 importer "github.com/ipfs/boxo/ipld/unixfs/importer"
30 uio "github.com/ipfs/boxo/ipld/unixfs/io"
31 + "github.com/ipfs/boxo/path"
32 u "github.com/ipfs/boxo/util"
33 ipld "github.com/ipfs/go-ipld-format"
34 ci "github.com/libp2p/go-libp2p-testing/ci"
@@ -89,7 +89,7 @@ func TestIpfsBasicRead(t *testing.T) {
89
90 fi, data := randObj(t, nd, 10000)
91 k := fi.Cid()
92 - fname := path.Join(mnt.Dir, k.String())
92 + fname := gopath.Join(mnt.Dir, k.String())
93 rbuf, err := os.ReadFile(fname)
94 if err != nil {
95 t.Fatal(err)
@@ -116,7 +116,7 @@ func getPaths(t *testing.T, ipfs *core.IpfsNode, name string, n *dag.ProtoNode)
116 t.Fatal(dag.ErrNotProtobuf)
117 }
118
119 - sub := getPaths(t, ipfs, path.Join(name, lnk.Name), childpb)
119 + sub := getPaths(t, ipfs, gopath.Join(name, lnk.Name), childpb)
120 out = append(out, sub...)
121 }
122 return out
@@ -184,10 +184,14 @@ func TestIpfsStressRead(t *testing.T) {
184 defer wg.Done()
185
186 for i := 0; i < 2000; i++ {
187 - item := ipath.New(paths[rand.Intn(len(paths))])
187 + item, err := path.NewPath(paths[rand.Intn(len(paths))])
188 + if err != nil {
189 + errs <- err
190 + continue
191 + }
192
193 relpath := strings.Replace(item.String(), item.Namespace(), "", 1)
190 - fname := path.Join(mnt.Dir, relpath)
194 + fname := gopath.Join(mnt.Dir, relpath)
195
196 rbuf, err := os.ReadFile(fname)
197 if err != nil {
@@ -257,8 +261,8 @@ func TestIpfsBasicDirRead(t *testing.T) {
261 t.Fatal(err)
262 }
263
260 - dirname := path.Join(mnt.Dir, d1nd.Cid().String())
261 - fname := path.Join(dirname, "actual")
264 + dirname := gopath.Join(mnt.Dir, d1nd.Cid().String())
265 + fname := gopath.Join(dirname, "actual")
266 rbuf, err := os.ReadFile(fname)
267 if err != nil {
268 t.Fatal(err)
@@ -291,7 +295,7 @@ func TestFileSizeReporting(t *testing.T) {
295 fi, data := randObj(t, nd, 10000)
296 k := fi.Cid()
297
294 - fname := path.Join(mnt.Dir, k.String())
298 + fname := gopath.Join(mnt.Dir, k.String())
299
300 finfo, err := os.Stat(fname)
301 if err != nil {
fuse/readonly/readonly_unix.go
+9 -3
@@ -16,7 +16,7 @@ import (
16 mdag "github.com/ipfs/boxo/ipld/merkledag"
17 ft "github.com/ipfs/boxo/ipld/unixfs"
18 uio "github.com/ipfs/boxo/ipld/unixfs/io"
19 - path "github.com/ipfs/boxo/path"
19 + "github.com/ipfs/boxo/path"
20 "github.com/ipfs/go-cid"
21 ipld "github.com/ipfs/go-ipld-format"
22 logging "github.com/ipfs/go-log"
@@ -62,13 +62,19 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) {
62 return nil, syscall.Errno(syscall.ENOENT)
63 }
64
65 - p, err := path.ParsePath(name)
65 + p, err := path.NewPath(name)
66 if err != nil {
67 log.Debugf("fuse failed to parse path: %q: %s", name, err)
68 return nil, syscall.Errno(syscall.ENOENT)
69 }
70
71 - nd, ndLnk, err := s.Ipfs.UnixFSPathResolver.ResolvePath(ctx, p)
71 + imPath, err := path.NewImmutablePath(p)
72 + if err != nil {
73 + log.Debugf("fuse failed to convert path: %q: %s", name, err)
74 + return nil, syscall.Errno(syscall.ENOENT)
75 + }
76 +
77 + nd, ndLnk, err := s.Ipfs.UnixFSPathResolver.ResolvePath(ctx, imPath)
78 if err != nil {
79 // todo: make this error more versatile.
80 return nil, syscall.Errno(syscall.ENOENT)
go.mod
+1 -1
@@ -15,7 +15,7 @@ require (
15 github.com/fsnotify/fsnotify v1.6.0
16 github.com/google/uuid v1.3.1
17 github.com/hashicorp/go-multierror v1.1.1
18 - github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0
18 + github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664
19 github.com/ipfs/go-block-format v0.2.0
20 github.com/ipfs/go-cid v0.4.1
21 github.com/ipfs/go-cidutil v0.1.0
go.sum
+2 -2
@@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
335 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
336 github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
337 github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
338 -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs=
339 -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
338 +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24=
339 +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
340 github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
341 github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
342 github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ=
repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go
+9 -11
@@ -7,14 +7,14 @@ import (
7 "io"
8 "net/url"
9 "os"
10 - "path"
10 + gopath "path"
11 "strings"
12 "sync"
13
14 iface "github.com/ipfs/boxo/coreiface"
15 "github.com/ipfs/boxo/coreiface/options"
16 - ipath "github.com/ipfs/boxo/coreiface/path"
16 "github.com/ipfs/boxo/files"
17 + "github.com/ipfs/boxo/path"
18 "github.com/ipfs/kubo/config"
19 "github.com/ipfs/kubo/core"
20 "github.com/ipfs/kubo/core/coreapi"
@@ -46,7 +46,7 @@ type IpfsFetcher struct {
46 ipfsTmpDir string
47 ipfsStopFunc func()
48
49 - fetched []ipath.Path
49 + fetched []path.Path
50 mutex sync.Mutex
51
52 addrInfo peer.AddrInfo
@@ -108,7 +108,7 @@ func (f *IpfsFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error
108 return nil, f.openErr
109 }
110
111 - iPath, err := parsePath(path.Join(f.distPath, filePath))
111 + iPath, err := parsePath(gopath.Join(f.distPath, filePath))
112 if err != nil {
113 return nil, err
114 }
@@ -156,13 +156,13 @@ func (f *IpfsFetcher) AddrInfo() peer.AddrInfo {
156 }
157
158 // FetchedPaths returns the IPFS paths of all items fetched by this fetcher.
159 -func (f *IpfsFetcher) FetchedPaths() []ipath.Path {
159 +func (f *IpfsFetcher) FetchedPaths() []path.Path {
160 f.mutex.Lock()
161 defer f.mutex.Unlock()
162 return f.fetched
163 }
164
165 -func (f *IpfsFetcher) recordFetched(fetchedPath ipath.Path) {
165 +func (f *IpfsFetcher) recordFetched(fetchedPath path.Path) {
166 // Mutex protects against update by concurrent calls to Fetch
167 f.mutex.Lock()
168 defer f.mutex.Unlock()
@@ -267,9 +267,8 @@ func (f *IpfsFetcher) startTempNode(ctx context.Context) error {
267 return nil
268 }
269
270 -func parsePath(fetchPath string) (ipath.Path, error) {
271 - ipfsPath := ipath.New(fetchPath)
272 - if ipfsPath.IsValid() == nil {
270 +func parsePath(fetchPath string) (path.Path, error) {
271 + if ipfsPath, err := path.NewPath(fetchPath); err == nil {
272 return ipfsPath, nil
273 }
274
@@ -280,11 +279,10 @@ func parsePath(fetchPath string) (ipath.Path, error) {
279
280 switch proto := u.Scheme; proto {
281 case "ipfs", "ipld", "ipns":
283 - ipfsPath = ipath.New(path.Join("/", proto, u.Host, u.Path))
282 + return path.NewPath(gopath.Join("/", proto, u.Host, u.Path))
283 default:
284 return nil, fmt.Errorf("%q is not an IPFS path", fetchPath)
285 }
287 - return ipfsPath, ipfsPath.IsValid()
286 }
287
288 func readIpfsConfig(repoRoot *string, userConfigFile string) (bootstrap []string, peers []peer.AddrInfo) {
tar/format.go
+3 -3
@@ -6,13 +6,13 @@ import (
6 "context"
7 "errors"
8 "io"
9 + "path"
10 "strings"
11
12 dag "github.com/ipfs/boxo/ipld/merkledag"
13 "github.com/ipfs/boxo/ipld/merkledag/dagutils"
14 importer "github.com/ipfs/boxo/ipld/unixfs/importer"
15 uio "github.com/ipfs/boxo/ipld/unixfs/io"
15 - path "github.com/ipfs/boxo/path"
16
17 chunker "github.com/ipfs/boxo/chunker"
18 ipld "github.com/ipfs/go-ipld-format"
@@ -95,11 +95,11 @@ func ImportTar(ctx context.Context, r io.Reader, ds ipld.DAGService) (*dag.Proto
95 // adds a '-' to the beginning of each path element so we can use 'data' as a
96 // special link in the structure without having to worry about.
97 func escapePath(pth string) string {
98 - elems := path.SplitList(strings.Trim(pth, "/"))
98 + elems := strings.Split(strings.Trim(pth, "/"), "/")
99 for i, e := range elems {
100 elems[i] = "-" + e
101 }
102 - return path.Join(elems)
102 + return path.Join(elems...)
103 }
104
105 type tarReader struct {
test/cli/gateway_test.go
+2 -2
@@ -408,9 +408,9 @@ func TestGateway(t *testing.T) {
408 t.Parallel()
409 gatewayAddr := URLStrToMultiaddr(node.GatewayURL())
410 res := node.RunIPFS("--api", gatewayAddr.String(), "refs", "local")
411 - assert.Equal(t,
412 - `Error: invalid path "local": invalid cid: selected encoding not supported`,
411 + assert.Contains(t,
412 res.Stderr.Trimmed(),
413 + `Error: invalid path "local":`,
414 )
415 })
416
test/dependencies/go.mod
+1 -1
@@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../
7 require (
8 github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd
9 github.com/golangci/golangci-lint v1.54.1
10 - github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0
10 + github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664
11 github.com/ipfs/go-cid v0.4.1
12 github.com/ipfs/go-cidutil v0.1.0
13 github.com/ipfs/go-datastore v0.6.0
test/dependencies/go.sum
+2 -2
@@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
396 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
397 github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
398 github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
399 -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0 h1:oss04OCg1/QW0h3OfSCZJiUQErpYPOsz7+X4tpgwODs=
400 -github.com/ipfs/boxo v0.13.2-0.20231002142647-c28c847582f0/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
399 +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664 h1:wserB+u/lpguBpxuKNNzwJR+rOSHxWufm3ZzNgN3d24=
400 +github.com/ipfs/boxo v0.13.2-0.20231006140423-85c180e26664/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
401 github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
402 github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
403 github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs=
test/sharness/t0090-get.sh
+1 -2
@@ -129,9 +129,8 @@ test_get_cmd() {
129 '
130
131 test_expect_success "ipfs get ../.. should fail" '
132 - echo "Error: invalid path \"../..\": invalid cid: selected encoding not supported" >expected &&
132 test_must_fail ipfs get ../.. 2>actual &&
134 - test_cmp expected actual
133 + test_should_contain "Error: invalid path \"../..\"" actual
134 '
135
136 test_expect_success "create small file" '