From d14a1721a64293e1809c2de1557578ae856c8f92 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 11 Aug 2023 14:06:37 +0200 Subject: [PATCH] refactor: boxo path consolidation --- assets/assets.go | 4 +- client/rpc/api_test.go | 14 +++- client/rpc/apifile.go | 8 +- client/rpc/block.go | 6 +- client/rpc/dag.go | 8 +- client/rpc/dht.go | 2 +- client/rpc/key.go | 74 ++++++++++++------- client/rpc/name.go | 10 ++- client/rpc/object.go | 26 +++---- client/rpc/path.go | 17 ++--- client/rpc/pin.go | 12 +-- client/rpc/unixfs.go | 8 +- cmd/ipfs/add_migrations.go | 6 +- cmd/ipfs/init.go | 4 +- core/commands/block.go | 23 +++++- core/commands/cat.go | 11 ++- core/commands/cmdutils/utils.go | 17 +++++ core/commands/dag/dag.go | 4 +- core/commands/dag/get.go | 9 ++- core/commands/dag/resolve.go | 9 ++- core/commands/dag/stat.go | 8 +- core/commands/dns.go | 4 +- core/commands/files.go | 9 ++- core/commands/get.go | 7 +- core/commands/ls.go | 9 ++- core/commands/name/ipns.go | 13 +++- core/commands/name/name.go | 9 +-- core/commands/name/publish.go | 7 +- core/commands/object/diff.go | 13 +++- core/commands/object/object.go | 24 ++++-- core/commands/object/patch.go | 28 +++++-- core/commands/pin/pin.go | 37 ++++++++-- core/commands/pin/remotepin.go | 9 ++- core/commands/refs.go | 8 +- core/commands/resolve.go | 30 +++++--- core/commands/routing.go | 7 +- core/commands/tar.go | 9 ++- core/commands/unixfs/ls.go | 9 ++- core/coreapi/block.go | 10 +-- core/coreapi/dht.go | 2 +- core/coreapi/key.go | 46 +++++++++--- core/coreapi/name.go | 12 +-- core/coreapi/object.go | 38 +++++----- core/coreapi/path.go | 32 +++----- core/coreapi/pin.go | 14 ++-- core/coreapi/routing.go | 6 +- core/coreapi/test/path_test.go | 11 ++- core/coreapi/unixfs.go | 6 +- core/corehttp/commands.go | 3 +- core/corehttp/gateway.go | 16 ++-- core/corehttp/gateway_test.go | 2 +- core/coreunix/add.go | 4 +- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +- docs/examples/kubo-as-a-library/main.go | 4 +- fuse/ipns/common.go | 4 +- fuse/ipns/ipns_unix.go | 6 +- fuse/readonly/ipfs_test.go | 24 +++--- fuse/readonly/readonly_unix.go | 4 +- go.mod | 2 +- go.sum | 4 +- .../migrations/ipfsfetcher/ipfsfetcher.go | 20 +++-- tar/format.go | 6 +- test/cli/gateway_test.go | 4 +- test/dependencies/go.mod | 2 +- test/dependencies/go.sum | 4 +- test/sharness/t0090-get.sh | 3 +- 67 files changed, 507 insertions(+), 300 deletions(-) diff --git a/assets/assets.go b/assets/assets.go index 9dff80e074ed..3b33293f73be 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -9,8 +9,8 @@ import ( "github.com/ipfs/kubo/core/coreapi" options "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" ) @@ -44,7 +44,7 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { return cid.Cid{}, err } - basePath := path.IpfsPath(dirb.Cid()) + basePath := path.NewIPFSPath(dirb.Cid()) for _, p := range l { d, err := Asset.ReadFile(p) diff --git a/client/rpc/api_test.go b/client/rpc/api_test.go index 51f8cf89d8e3..e2838cb16c60 100644 --- a/client/rpc/api_test.go +++ b/client/rpc/api_test.go @@ -12,8 +12,8 @@ import ( "time" iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/coreiface/tests" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/test/cli/harness" ma "github.com/multiformats/go-multiaddr" "go.uber.org/multierr" @@ -70,7 +70,11 @@ func (np NodeProvider) MakeAPISwarm(t *testing.T, ctx context.Context, fullIdent apis[i] = api // empty node is pinned even with --empty-repo, we don't want that - emptyNode := path.New("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") + emptyNode, err := path.NewPath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") + if err != nil { + return err + } + if err := api.Pin().Rm(ctx, emptyNode); err != nil { return err } @@ -126,7 +130,11 @@ func Test_NewURLApiWithClient_With_Headers(t *testing.T) { t.Fatal(err) } api.Headers.Set(headerToTest, expectedHeaderValue) - if err := api.Pin().Rm(context.Background(), path.New("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv")); err != nil { + p, err := path.NewPath("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv") + if err != nil { + t.Fatal(err) + } + if err := api.Pin().Rm(context.Background(), p); err != nil { t.Fatal(err) } } diff --git a/client/rpc/apifile.go b/client/rpc/apifile.go index 873a67b7be05..8c28d8dd9e69 100644 --- a/client/rpc/apifile.go +++ b/client/rpc/apifile.go @@ -6,16 +6,16 @@ import ( "fmt" "io" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" unixfs "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ) const forwardSeekLimit = 1 << 14 // 16k func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) { - if p.Mutable() { // use resolved path in case we are dealing with IPNS / MFS + if p.Namespace().Mutable() { // use resolved path in case we are dealing with IPNS / MFS var err error p, err = api.core().ResolvePath(ctx, p) if err != nil { @@ -195,13 +195,13 @@ func (it *apiIter) Next() bool { switch it.cur.Type { case unixfs.THAMTShard, unixfs.TMetadata, unixfs.TDirectory: - it.curFile, err = it.core.getDir(it.ctx, path.IpfsPath(c), int64(it.cur.Size)) + it.curFile, err = it.core.getDir(it.ctx, path.NewIPFSPath(c), int64(it.cur.Size)) if err != nil { it.err = err return false } case unixfs.TFile: - it.curFile, err = it.core.getFile(it.ctx, path.IpfsPath(c), int64(it.cur.Size)) + it.curFile, err = it.core.getFile(it.ctx, path.NewIPFSPath(c), int64(it.cur.Size)) if err != nil { it.err = err return false diff --git a/client/rpc/block.go b/client/rpc/block.go index 2b0048380beb..ac304f377e6d 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -8,7 +8,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" mc "github.com/multiformats/go-multicodec" mh "github.com/multiformats/go-multihash" @@ -27,8 +27,8 @@ func (s *blockStat) Size() int { return s.BSize } -func (s *blockStat) Path() path.Resolved { - return path.IpldPath(s.cid) +func (s *blockStat) Path() path.ImmutablePath { + return path.NewIPLDPath(s.cid) } func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) { diff --git a/client/rpc/dag.go b/client/rpc/dag.go index f4c9be351f29..c5279507f962 100644 --- a/client/rpc/dag.go +++ b/client/rpc/dag.go @@ -7,8 +7,8 @@ import ( "io" "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/go-block-format" + "github.com/ipfs/boxo/path" + blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" format "github.com/ipfs/go-ipld-format" multicodec "github.com/multiformats/go-multicodec" @@ -21,7 +21,7 @@ type ( ) func (api *HttpDagServ) Get(ctx context.Context, c cid.Cid) (format.Node, error) { - r, err := api.core().Block().Get(ctx, path.IpldPath(c)) + r, err := api.core().Block().Get(ctx, path.NewIPLDPath(c)) if err != nil { return nil, err } @@ -116,7 +116,7 @@ func (api *HttpDagServ) Pinning() format.NodeAdder { } func (api *HttpDagServ) Remove(ctx context.Context, c cid.Cid) error { - return api.core().Block().Rm(ctx, path.IpldPath(c)) // TODO: should we force rm? + return api.core().Block().Rm(ctx, path.NewIPLDPath(c)) // TODO: should we force rm? } func (api *HttpDagServ) RemoveMany(ctx context.Context, cids []cid.Cid) error { diff --git a/client/rpc/dht.go b/client/rpc/dht.go index 1d3b246438a8..d5cca37d796e 100644 --- a/client/rpc/dht.go +++ b/client/rpc/dht.go @@ -5,7 +5,7 @@ import ( "encoding/json" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" ) diff --git a/client/rpc/key.go b/client/rpc/key.go index 487c14c3d1b1..40027aa464e8 100644 --- a/client/rpc/key.go +++ b/client/rpc/key.go @@ -6,31 +6,50 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" "github.com/libp2p/go-libp2p/core/peer" ) type KeyAPI HttpApi -type keyOutput struct { - JName string `json:"Name"` - Id string +type key struct { + name string + pid peer.ID + path path.Path +} + +func newKey(name, pidStr string) (*key, error) { + pid, err := peer.Decode(pidStr) + if err != nil { + return nil, err + } - pid peer.ID + path, err := path.NewPath("/ipns/" + ipns.NameFromPeer(pid).String()) + if err != nil { + return nil, err + } + + return &key{name: name, pid: pid, path: path}, nil } -func (k *keyOutput) Name() string { - return k.JName +func (k *key) Name() string { + return k.name } -func (k *keyOutput) Path() path.Path { - return path.New("/ipns/" + k.Id) +func (k *key) Path() path.Path { + return k.path } -func (k *keyOutput) ID() peer.ID { +func (k *key) ID() peer.ID { return k.pid } +type keyOutput struct { + Name string + Id string +} + func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (iface.Key, error) { options, err := caopts.KeyGenerateOptions(opts...) if err != nil { @@ -45,8 +64,8 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key if err != nil { return nil, err } - out.pid, err = peer.Decode(out.Id) - return &out, err + + return newKey(out.Name, out.Id) } 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 return nil, false, err } - id := &keyOutput{JName: out.Now, Id: out.Id} - id.pid, err = peer.Decode(id.Id) - return id, out.Overwrite, err + key, err := newKey(out.Now, out.Id) + if err != nil { + return nil, false, err + } + + return key, out.Overwrite, err } func (api *KeyAPI) List(ctx context.Context) ([]iface.Key, error) { - var out struct{ Keys []*keyOutput } + var out struct { + Keys []keyOutput + } if err := api.core().Request("key/list").Exec(ctx, &out); err != nil { return nil, err } res := make([]iface.Key, len(out.Keys)) for i, k := range out.Keys { - var err error - k.pid, err = peer.Decode(k.Id) + key, err := newKey(k.Name, k.Id) if err != nil { return nil, err } - res[i] = k + res[i] = key } return res, nil @@ -98,14 +121,13 @@ func (api *KeyAPI) Self(ctx context.Context) (iface.Key, error) { return nil, err } - var err error - out := keyOutput{JName: "self", Id: id.ID} - out.pid, err = peer.Decode(out.Id) - return &out, err + return newKey("self", id.ID) } func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { - var out struct{ Keys []keyOutput } + var out struct { + Keys []keyOutput + } if err := api.core().Request("key/rm", name).Exec(ctx, &out); err != nil { return nil, err } @@ -113,9 +135,7 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (iface.Key, error) { return nil, errors.New("got unexpected number of keys back") } - var err error - out.Keys[0].pid, err = peer.Decode(out.Keys[0].Id) - return &out.Keys[0], err + return newKey(out.Keys[0].Name, out.Keys[0].Id) } func (api *KeyAPI) core() *HttpApi { diff --git a/client/rpc/name.go b/client/rpc/name.go index 5ad9d16cb8a9..223b7a226956 100644 --- a/client/rpc/name.go +++ b/client/rpc/name.go @@ -9,8 +9,8 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" ) type NameAPI HttpApi @@ -84,7 +84,11 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name } var ires iface.IpnsResult if err == nil { - ires.Path = path.New(out.Path) + p, err := path.NewPath(out.Path) + if err != nil { + return + } + ires.Path = p } select { @@ -122,7 +126,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam return nil, err } - return path.New(out.Path), nil + return path.NewPath(out.Path) } func (api *NameAPI) core() *HttpApi { diff --git a/client/rpc/object.go b/client/rpc/object.go index 7464cea1a728..c2fe8bacef62 100644 --- a/client/rpc/object.go +++ b/client/rpc/object.go @@ -8,9 +8,9 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) @@ -40,7 +40,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( return n, nil } -func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.Resolved, error) { +func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) { options, err := caopts.ObjectPutOptions(opts...) if err != nil { return nil, err @@ -62,7 +62,7 @@ func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.Objec return nil, err } - return path.IpfsPath(c), nil + return path.NewIPFSPath(c), nil } 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, }, nil } -func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.Resolved, error) { +func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) { options, err := caopts.ObjectAddLinkOptions(opts...) if err != nil { return nil, err @@ -172,10 +172,10 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, return nil, err } - return path.IpfsPath(c), nil + return path.NewIPFSPath(c), nil } -func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error) { +func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) { var out objectOut err := api.core().Request("object/patch/rm-link", base.String(), link). Exec(ctx, &out) @@ -188,10 +188,10 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) ( return nil, err } - return path.IpfsPath(c), nil + return path.NewIPFSPath(c), nil } -func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) (path.Resolved, error) { +func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) (path.ImmutablePath, error) { var out objectOut err := api.core().Request("object/patch/append-data", p.String()). FileBody(r). @@ -205,10 +205,10 @@ func (api *ObjectAPI) AppendData(ctx context.Context, p path.Path, r io.Reader) return nil, err } - return path.IpfsPath(c), nil + return path.NewIPFSPath(c), nil } -func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (path.Resolved, error) { +func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (path.ImmutablePath, error) { var out objectOut err := api.core().Request("object/patch/set-data", p.String()). FileBody(r). @@ -222,7 +222,7 @@ func (api *ObjectAPI) SetData(ctx context.Context, p path.Path, r io.Reader) (pa return nil, err } - return path.IpfsPath(c), nil + return path.NewIPFSPath(c), nil } type change struct { @@ -246,10 +246,10 @@ func (api *ObjectAPI) Diff(ctx context.Context, a path.Path, b path.Path) ([]ifa Path: ch.Path, } if ch.Before != cid.Undef { - res[i].Before = path.IpfsPath(ch.Before) + res[i].Before = path.NewIPFSPath(ch.Before) } if ch.After != cid.Undef { - res[i].After = path.IpfsPath(ch.After) + res[i].After = path.NewIPFSPath(ch.After) } } return res, nil diff --git a/client/rpc/path.go b/client/rpc/path.go index 1b88eb07d266..57ba242bf911 100644 --- a/client/rpc/path.go +++ b/client/rpc/path.go @@ -3,13 +3,12 @@ package rpc import ( "context" - "github.com/ipfs/boxo/coreiface/path" - ipfspath "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) -func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) { +func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.ImmutablePath, error) { var out struct { Cid cid.Cid RemPath string @@ -18,7 +17,7 @@ func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Resolved // TODO: this is hacky, fixing https://github.com/ipfs/go-ipfs/issues/5703 would help var err error - if p.Namespace() == "ipns" { + if p.Namespace() == path.IPNSNamespace { if p, err = api.Name().Resolve(ctx, p.String()); err != nil { return nil, err } @@ -28,18 +27,12 @@ func (api *HttpApi) ResolvePath(ctx context.Context, p path.Path) (path.Resolved return nil, err } - // TODO: - ipath, err := ipfspath.FromSegments("/"+p.Namespace()+"/", out.Cid.String(), out.RemPath) + p, err = path.NewPathFromSegments(p.Namespace().String(), out.Cid.String(), out.RemPath) if err != nil { return nil, err } - root, err := cid.Parse(ipfspath.Path(p.String()).Segments()[1]) - if err != nil { - return nil, err - } - - return path.NewResolvedPath(ipath, out.Cid, root, out.RemPath), nil + return path.NewImmutablePath(p) } func (api *HttpApi) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, error) { diff --git a/client/rpc/pin.go b/client/rpc/pin.go index e8aecf11cf61..a1323fb7f1a3 100644 --- a/client/rpc/pin.go +++ b/client/rpc/pin.go @@ -8,7 +8,7 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" "github.com/pkg/errors" ) @@ -24,7 +24,7 @@ type pinRefKeyList struct { } type pin struct { - path path.Resolved + path path.ImmutablePath typ string err error } @@ -33,7 +33,7 @@ func (p pin) Err() error { return p.err } -func (p pin) Path() path.Resolved { +func (p pin) Path() path.ImmutablePath { return p.path } @@ -102,7 +102,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan i } select { - case ch <- pin{typ: out.Type, path: path.IpldPath(c)}: + case ch <- pin{typ: out.Type, path: path.NewIPLDPath(c)}: case <-ctx.Done(): return } @@ -182,8 +182,8 @@ type badNode struct { cid cid.Cid } -func (n badNode) Path() path.Resolved { - return path.IpldPath(n.cid) +func (n badNode) Path() path.ImmutablePath { + return path.NewIPLDPath(n.cid) } func (n badNode) Err() error { diff --git a/client/rpc/unixfs.go b/client/rpc/unixfs.go index e19deec220c4..39e3f72013d7 100644 --- a/client/rpc/unixfs.go +++ b/client/rpc/unixfs.go @@ -9,10 +9,10 @@ import ( iface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" unixfs "github.com/ipfs/boxo/ipld/unixfs" unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" mh "github.com/multiformats/go-multihash" ) @@ -26,7 +26,7 @@ type addEvent struct { type UnixfsAPI HttpApi -func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (path.Resolved, error) { +func (api *UnixfsAPI) Add(ctx context.Context, f files.Node, opts ...caopts.UnixfsAddOption) (path.ImmutablePath, error) { options, _, err := caopts.UnixfsAddOptions(opts...) if err != nil { return nil, err @@ -105,7 +105,7 @@ loop: return nil, err } - ifevt.Path = path.IpfsPath(c) + ifevt.Path = path.NewIPFSPath(c) } select { @@ -121,7 +121,7 @@ loop: return nil, err } - return path.IpfsPath(c), nil + return path.NewIPFSPath(c), nil } type lsLink struct { diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/add_migrations.go index e01381121120..566158d0f7e5 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/add_migrations.go @@ -10,8 +10,8 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" - ipath "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" "github.com/ipfs/kubo/repo/fsrepo/migrations" @@ -98,7 +98,7 @@ func addMigrationFiles(ctx context.Context, node *core.IpfsNode, paths []string, // addMigrationPaths adds the files at paths to IPFS, optionally pinning // them. This is done after connecting to the peer. -func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.AddrInfo, paths []ipath.Path, pin bool) error { +func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.AddrInfo, paths []path.Path, pin bool) error { if len(paths) == 0 { return errors.New("nothing downloaded by ipfs fetcher") } @@ -142,7 +142,7 @@ func addMigrationPaths(ctx context.Context, node *core.IpfsNode, peerInfo peer.A return nil } -func ipfsGet(ctx context.Context, ufs coreiface.UnixfsAPI, ipfsPath ipath.Path) error { +func ipfsGet(ctx context.Context, ufs coreiface.UnixfsAPI, ipfsPath path.Path) error { nd, err := ufs.Get(ctx, ipfsPath) if err != nil { return err diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 0c5223d7fce5..895236d9ecc3 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -11,7 +11,7 @@ import ( "strings" unixfs "github.com/ipfs/boxo/ipld/unixfs" - path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" assets "github.com/ipfs/kubo/assets" oldcmds "github.com/ipfs/kubo/commands" core "github.com/ipfs/kubo/core" @@ -262,5 +262,5 @@ func initializeIpnsKeyspace(repoRoot string) error { return err } - return nd.Namesys.Publish(ctx, nd.PrivateKey, path.FromCid(emptyDir.Cid())) + return nd.Namesys.Publish(ctx, nd.PrivateKey, path.NewIPFSPath(emptyDir.Cid())) } diff --git a/core/commands/block.go b/core/commands/block.go index 45b8f2a72c83..4d0c1742af61 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -12,7 +12,7 @@ import ( "github.com/ipfs/kubo/core/commands/cmdutils" options "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" + cmds "github.com/ipfs/go-ipfs-cmds" mh "github.com/multiformats/go-multihash" ) @@ -66,7 +66,12 @@ on raw IPFS blocks. It outputs the following to stdout: return err } - b, err := api.Block().Stat(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + b, err := api.Block().Stat(req.Context, p) if err != nil { return err } @@ -103,7 +108,12 @@ It takes a , and outputs the block to stdout. return err } - r, err := api.Block().Get(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + r, err := api.Block().Get(req.Context, p) if err != nil { return err } @@ -255,7 +265,12 @@ It takes a list of CIDs to remove from the local datastore.. // TODO: use batching coreapi when done for _, b := range req.Arguments { - rp, err := api.ResolvePath(req.Context, path.New(b)) + p, err := cmdutils.PathOrCidPath(b) + if err != nil { + return err + } + + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } diff --git a/core/commands/cat.go b/core/commands/cat.go index 92b045235c37..79e78cc772d7 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -7,10 +7,10 @@ import ( "os" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/cheggaaa/pb" iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" cmds "github.com/ipfs/go-ipfs-cmds" ) @@ -127,8 +127,13 @@ func cat(ctx context.Context, api iface.CoreAPI, paths []string, offset int64, m if max == 0 { return nil, 0, nil } - for _, p := range paths { - f, err := api.Unixfs().Get(ctx, path.New(p)) + for _, pString := range paths { + p, err := cmdutils.PathOrCidPath(pString) + if err != nil { + return nil, 0, err + } + + f, err := api.Unixfs().Get(ctx, p) if err != nil { return nil, 0, err } diff --git a/core/commands/cmdutils/utils.go b/core/commands/cmdutils/utils.go index 954f476b6bff..87ddb9655ed2 100644 --- a/core/commands/cmdutils/utils.go +++ b/core/commands/cmdutils/utils.go @@ -6,6 +6,7 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" coreiface "github.com/ipfs/boxo/coreiface" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ) @@ -48,3 +49,19 @@ func CheckBlockSize(req *cmds.Request, size uint64) error { } return nil } + +// PathOrCidPath returns a path.Path built from the argument. It keeps the old +// behaviour by building a path from a CID string. +func PathOrCidPath(str string) (path.Path, error) { + p, err := path.NewPath(str) + if err == nil { + return p, nil + } + + if p, err := path.NewPath("/ipfs/" + str); err == nil { + return p, nil + } + + // Send back original err. + return nil, err +} diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index 07851eb316f7..56aae4105daa 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "io" + "path" "github.com/ipfs/kubo/core/commands/cmdenv" "github.com/ipfs/kubo/core/commands/cmdutils" - ipfspath "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" @@ -157,7 +157,7 @@ var DagResolveCmd = &cmds.Command{ } p := enc.Encode(out.Cid) if out.RemPath != "" { - p = ipfspath.Join([]string{p, out.RemPath}) + p = path.Join(p, out.RemPath) } fmt.Fprint(w, p) diff --git a/core/commands/dag/get.go b/core/commands/dag/get.go index 1252293a8e4f..b03cfa9e86d1 100644 --- a/core/commands/dag/get.go +++ b/core/commands/dag/get.go @@ -4,9 +4,9 @@ import ( "fmt" "io" - "github.com/ipfs/boxo/coreiface/path" ipldlegacy "github.com/ipfs/go-ipld-legacy" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/multicodec" @@ -28,7 +28,12 @@ func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e return err } - rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } diff --git a/core/commands/dag/resolve.go b/core/commands/dag/resolve.go index 0f252be9db35..88bff3fcc92f 100644 --- a/core/commands/dag/resolve.go +++ b/core/commands/dag/resolve.go @@ -1,8 +1,8 @@ package dagcmd import ( - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" cmds "github.com/ipfs/go-ipfs-cmds" ) @@ -13,7 +13,12 @@ func dagResolve(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environmen return err } - rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } diff --git a/core/commands/dag/stat.go b/core/commands/dag/stat.go index 23f4ab481671..57473c0550b1 100644 --- a/core/commands/dag/stat.go +++ b/core/commands/dag/stat.go @@ -5,12 +5,12 @@ import ( "io" "os" - "github.com/ipfs/boxo/coreiface/path" mdag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/traverse" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipfs/kubo/core/commands/e" ) @@ -29,7 +29,11 @@ func dagStat(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) cidSet := cid.NewSet() dagStatSummary := &DagStatSummary{DagStatsArray: []*DagStat{}} for _, a := range req.Arguments { - rp, err := api.ResolvePath(req.Context, path.New(a)) + p, err := cmdutils.PathOrCidPath(a) + if err != nil { + return err + } + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } diff --git a/core/commands/dns.go b/core/commands/dns.go index fda0cb6c3335..8ab76e64d2eb 100644 --- a/core/commands/dns.go +++ b/core/commands/dns.go @@ -56,11 +56,11 @@ It will work across multiple DNSLinks and IPNS keys. if err != nil && (recursive || err != namesys.ErrResolveRecursion) { return err } - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: output}) + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: output.String()}) }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ncmd.ResolvedPath) error { - fmt.Fprintln(w, cmdenv.EscNonPrint(out.Path.String())) + fmt.Fprintln(w, cmdenv.EscNonPrint(out.Path)) return nil }), }, diff --git a/core/commands/files.go b/core/commands/files.go index ce1cf1cfc815..73ce9c8264f4 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -16,11 +16,11 @@ import ( bservice "github.com/ipfs/boxo/blockservice" iface "github.com/ipfs/boxo/coreiface" - path "github.com/ipfs/boxo/coreiface/path" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" mfs "github.com/ipfs/boxo/mfs" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" @@ -423,7 +423,12 @@ being GC'ed. func getNodeFromPath(ctx context.Context, node *core.IpfsNode, api iface.CoreAPI, p string) (ipld.Node, error) { switch { case strings.HasPrefix(p, "/ipfs/"): - return api.ResolveNode(ctx, path.New(p)) + pth, err := path.NewPath(p) + if err != nil { + return nil, err + } + + return api.ResolveNode(ctx, pth) default: fsn, err := mfs.Lookup(node.FilesRoot, p) if err != nil { diff --git a/core/commands/get.go b/core/commands/get.go index 35cd45c9de5a..5b64c281bbd2 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -12,10 +12,10 @@ import ( "strings" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipfs/kubo/core/commands/e" "github.com/cheggaaa/pb" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/tar" cmds "github.com/ipfs/go-ipfs-cmds" @@ -72,7 +72,10 @@ may also specify the level of compression by specifying '-l=<1-9>'. return err } - p := path.New(req.Arguments[0]) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } file, err := api.Unixfs().Get(ctx, p) if err != nil { diff --git a/core/commands/ls.go b/core/commands/ls.go index 10d378562563..ee360796fb14 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -8,10 +8,10 @@ import ( "text/tabwriter" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" iface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" unixfs "github.com/ipfs/boxo/ipld/unixfs" unixfs_pb "github.com/ipfs/boxo/ipld/unixfs/pb" cmds "github.com/ipfs/go-ipfs-cmds" @@ -131,7 +131,12 @@ The JSON output contains type information. } for i, fpath := range paths { - results, err := api.Unixfs().Ls(req.Context, path.New(fpath), + pth, err := cmdutils.PathOrCidPath(fpath) + if err != nil { + return err + } + + results, err := api.Unixfs().Ls(req.Context, pth, options.Unixfs.ResolveChildren(resolveSize || resolveType)) if err != nil { return err diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index 8c2b755d585a..9791f071fc0d 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -12,7 +12,7 @@ import ( options "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" ) @@ -20,7 +20,7 @@ import ( var log = logging.Logger("core/commands/ipns") type ResolvedPath struct { - Path path.Path + Path string } const ( @@ -134,7 +134,12 @@ Resolve the value of a dnslink: return err } - return cmds.EmitOnce(res, &ResolvedPath{path.FromString(output.String())}) + pth, err := path.NewPath(output.String()) + if err != nil { + return err + } + + return cmds.EmitOnce(res, &ResolvedPath{pth.String()}) } output, err := api.Name().Search(req.Context, name, opts...) @@ -146,7 +151,7 @@ Resolve the value of a dnslink: if v.Err != nil && (recursive || v.Err != namesys.ErrResolveRecursion) { return v.Err } - if err := res.Emit(&ResolvedPath{path.FromString(v.Path.String())}); err != nil { + if err := res.Emit(&ResolvedPath{v.Path.String()}); err != nil { return err } diff --git a/core/commands/name/name.go b/core/commands/name/name.go index 3bcb5c8e4157..37ab4df5352d 100644 --- a/core/commands/name/name.go +++ b/core/commands/name/name.go @@ -10,7 +10,6 @@ import ( "github.com/ipfs/boxo/ipns" ipns_pb "github.com/ipfs/boxo/ipns/pb" - "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" "google.golang.org/protobuf/proto" @@ -87,7 +86,7 @@ type IpnsInspectValidation struct { // IpnsInspectEntry contains the deserialized values from an IPNS Entry: // https://github.com/ipfs/specs/blob/main/ipns/IPNS.md#record-serialization-format type IpnsInspectEntry struct { - Value *path.Path + Value string ValidityType *ipns.ValidityType Validity *time.Time Sequence *uint64 @@ -157,7 +156,7 @@ Passing --verify will verify signature against provided public key. // Best effort to get the fields. Show everything we can. if v, err := rec.Value(); err == nil { - result.Entry.Value = &v + result.Entry.Value = v.String() } if v, err := rec.ValidityType(); err == nil { @@ -221,8 +220,8 @@ Passing --verify will verify signature against provided public key. tw := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0) defer tw.Flush() - if out.Entry.Value != nil { - fmt.Fprintf(tw, "Value:\t%q\n", out.Entry.Value.String()) + if out.Entry.Value != "" { + fmt.Fprintf(tw, "Value:\t%q\n", out.Entry.Value) } if out.Entry.ValidityType != nil { diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 6cc51df14bd5..a817d52f9420 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -7,10 +7,10 @@ import ( "time" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" iface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" cmds "github.com/ipfs/go-ipfs-cmds" ke "github.com/ipfs/kubo/core/commands/keyencode" ) @@ -116,7 +116,10 @@ Alternatively, publish an using a valid PeerID (as listed by opts = append(opts, options.Name.TTL(d)) } - p := path.New(req.Arguments[0]) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } if verifyExists, _ := req.Options[resolveOptionName].(bool); verifyExists { _, err := api.ResolveNode(req.Context, p) diff --git a/core/commands/object/diff.go b/core/commands/object/diff.go index fca026ac1c0b..aa1e91c83bda 100644 --- a/core/commands/object/diff.go +++ b/core/commands/object/diff.go @@ -4,11 +4,11 @@ import ( "fmt" "io" - path "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/ipld/merkledag/dagutils" cmds "github.com/ipfs/go-ipfs-cmds" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" ) const ( @@ -60,8 +60,15 @@ Example: return err } - pa := path.New(req.Arguments[0]) - pb := path.New(req.Arguments[1]) + pa, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + pb, err := cmdutils.PathOrCidPath(req.Arguments[1]) + if err != nil { + return err + } changes, err := api.Object().Diff(req.Context, pa, pb) if err != nil { diff --git a/core/commands/object/object.go b/core/commands/object/object.go index febcf3470760..0459d44ad722 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -9,10 +9,10 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" humanize "github.com/dustin/go-humanize" "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -95,7 +95,10 @@ is the raw data of the object. return err } - path := path.New(req.Arguments[0]) + path, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } data, err := api.Object().Data(req.Context, path) if err != nil { @@ -135,7 +138,10 @@ multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. return err } - path := path.New(req.Arguments[0]) + path, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } rp, err := api.ResolvePath(req.Context, path) if err != nil { @@ -212,7 +218,10 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs dag get' instead. return err } - path := path.New(req.Arguments[0]) + path, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } datafieldenc, _ := req.Options[encodingOptionName].(string) if err != nil { @@ -333,7 +342,12 @@ DEPRECATED: Provided for legacy reasons. Modern replacements: return err } - ns, err := api.Object().Stat(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + ns, err := api.Object().Stat(req.Context, p) if err != nil { return err } diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index 8ec5b35168bb..830b803622a7 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -9,7 +9,6 @@ import ( "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" ) var ObjectPatchCmd = &cmds.Command{ @@ -76,7 +75,10 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' inste return err } - root := path.New(req.Arguments[0]) + root, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } file, err := cmdenv.GetFileArg(req.Files.Entries()) if err != nil { @@ -127,7 +129,10 @@ DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead return err } - root := path.New(req.Arguments[0]) + root, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } file, err := cmdenv.GetFileArg(req.Files.Entries()) if err != nil { @@ -174,7 +179,10 @@ DEPRECATED and provided for legacy reasons. Use 'files rm' instead. return err } - root := path.New(req.Arguments[0]) + root, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } name := req.Arguments[1] p, err := api.Object().RmLink(req.Context, root, name) @@ -238,9 +246,17 @@ Use MFS and 'files' commands instead: return err } - root := path.New(req.Arguments[0]) + root, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + name := req.Arguments[1] - child := path.New(req.Arguments[2]) + + child, err := cmdutils.PathOrCidPath(req.Arguments[2]) + if err != nil { + return err + } create, _ := req.Options[createOptionName].(bool) if err != nil { diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index 9402f5b2ce00..dfed08533059 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -11,7 +11,6 @@ import ( bserv "github.com/ipfs/boxo/blockservice" coreiface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" verifcid "github.com/ipfs/boxo/verifcid" @@ -21,6 +20,7 @@ import ( core "github.com/ipfs/kubo/core" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" e "github.com/ipfs/kubo/core/commands/e" ) @@ -184,7 +184,12 @@ var addPinCmd = &cmds.Command{ func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, paths []string, recursive bool) ([]string, error) { added := make([]string, len(paths)) for i, b := range paths { - rp, err := api.ResolvePath(ctx, path.New(b)) + p, err := cmdutils.PathOrCidPath(b) + if err != nil { + return nil, err + } + + rp, err := api.ResolvePath(ctx, p) if err != nil { return nil, err } @@ -242,7 +247,12 @@ ipfs pin ls -t indirect pins := make([]string, 0, len(req.Arguments)) for _, b := range req.Arguments { - rp, err := api.ResolvePath(req.Context, path.New(b)) + p, err := cmdutils.PathOrCidPath(b) + if err != nil { + return err + } + + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } @@ -453,7 +463,12 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu } for _, p := range req.Arguments { - rp, err := api.ResolvePath(req.Context, path.New(p)) + p, err := cmdutils.PathOrCidPath(p) + if err != nil { + return err + } + + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } @@ -568,12 +583,22 @@ pin. unpin, _ := req.Options[pinUnpinOptionName].(bool) + fromPath, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + toPath, err := cmdutils.PathOrCidPath(req.Arguments[1]) + if err != nil { + return err + } + // Resolve the paths ahead of time so we can return the actual CIDs - from, err := api.ResolvePath(req.Context, path.New(req.Arguments[0])) + from, err := api.ResolvePath(req.Context, fromPath) if err != nil { return err } - to, err := api.ResolvePath(req.Context, path.New(req.Arguments[1])) + to, err := api.ResolvePath(req.Context, toPath) if err != nil { return err } diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 2fe615c147b6..7af040304d23 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -15,13 +15,13 @@ import ( "golang.org/x/sync/errgroup" - path "github.com/ipfs/boxo/coreiface/path" pinclient "github.com/ipfs/boxo/pinning/remote/client" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" logging "github.com/ipfs/go-log" config "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" fsrepo "github.com/ipfs/kubo/repo/fsrepo" "github.com/libp2p/go-libp2p/core/host" peer "github.com/libp2p/go-libp2p/core/peer" @@ -157,7 +157,12 @@ NOTE: a comma-separated notation is supported in CLI for convenience: if err != nil { return err } - rp, err := api.ResolvePath(ctx, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + rp, err := api.ResolvePath(ctx, p) if err != nil { return err } diff --git a/core/commands/refs.go b/core/commands/refs.go index de5206a65c26..62c7639ff392 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -8,9 +8,9 @@ import ( "strings" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" iface "github.com/ipfs/boxo/coreiface" - path "github.com/ipfs/boxo/coreiface/path" merkledag "github.com/ipfs/boxo/ipld/merkledag" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" @@ -171,7 +171,11 @@ Displays the hashes of all local objects. NOTE: This treats all local objects as func objectsForPaths(ctx context.Context, n iface.CoreAPI, paths []string) ([]cid.Cid, error) { roots := make([]cid.Cid, len(paths)) for i, sp := range paths { - o, err := n.ResolvePath(ctx, path.New(sp)) + p, err := cmdutils.PathOrCidPath(sp) + if err != nil { + return nil, err + } + o, err := n.ResolvePath(ctx, p) if err != nil { return nil, err } diff --git a/core/commands/resolve.go b/core/commands/resolve.go index 38de57b21096..7c589b5b206e 100644 --- a/core/commands/resolve.go +++ b/core/commands/resolve.go @@ -8,14 +8,14 @@ import ( "time" ns "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/path" + cidenc "github.com/ipfs/go-cidutil/cidenc" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" ncmd "github.com/ipfs/kubo/core/commands/name" options "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - path "github.com/ipfs/boxo/coreiface/path" - ipfspath "github.com/ipfs/boxo/path" - cidenc "github.com/ipfs/go-cidutil/cidenc" cmds "github.com/ipfs/go-ipfs-cmds" ) @@ -108,7 +108,7 @@ Resolve the value of an IPFS DAG path: if err != nil && err != ns.ErrResolveRecursion { return err } - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(p.String())}) + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: p.String()}) } var enc cidenc.Encoder @@ -128,22 +128,34 @@ Resolve the value of an IPFS DAG path: } } + p, err := cmdutils.PathOrCidPath(name) + if err != nil { + return err + } + // else, ipfs path or ipns with recursive flag - rp, err := api.ResolvePath(req.Context, path.New(name)) + rp, err := api.ResolvePath(req.Context, p) if err != nil { return err } - encoded := "/" + rp.Namespace() + "/" + enc.Encode(rp.Cid()) + // Trick to encode path with correct encoding. + encodedPath := "/" + rp.Namespace().String() + "/" + enc.Encode(rp.Cid()) if remainder := rp.Remainder(); remainder != "" { - encoded += "/" + remainder + encodedPath += "/" + remainder + } + + // Ensure valid and sanitized. + ep, err := path.NewPath(encodedPath) + if err != nil { + return err } - return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(encoded)}) + return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ep.String()}) }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, rp *ncmd.ResolvedPath) error { - fmt.Fprintln(w, rp.Path.String()) + fmt.Fprintln(w, rp.Path) return nil }), }, diff --git a/core/commands/routing.go b/core/commands/routing.go index e2071fd40a80..acc5ceff6289 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "strings" "time" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" @@ -13,7 +14,6 @@ import ( iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" dag "github.com/ipfs/boxo/ipld/merkledag" - path "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" ipld "github.com/ipfs/go-ipld-format" @@ -549,7 +549,7 @@ func printEvent(obj *routing.QueryEvent, out io.Writer, verbose bool, override p } func escapeDhtKey(s string) (string, error) { - parts := path.SplitList(s) + parts := strings.Split(s, "/") if len(parts) != 3 || parts[0] != "" || !(parts[1] == "ipns" || parts[1] == "pk") { @@ -560,5 +560,6 @@ func escapeDhtKey(s string) (string, error) { if err != nil { return "", err } - return path.Join(append(parts[:2], string(k))), nil + + return strings.Join(append(parts[:2], string(k)), "/"), nil } diff --git a/core/commands/tar.go b/core/commands/tar.go index 50bd6794340b..e1094a59fb9a 100644 --- a/core/commands/tar.go +++ b/core/commands/tar.go @@ -6,9 +6,9 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" tar "github.com/ipfs/kubo/tar" - path "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" ) @@ -93,7 +93,12 @@ var tarCatCmd = &cmds.Command{ return err } - root, err := api.ResolveNode(req.Context, path.New(req.Arguments[0])) + p, err := cmdutils.PathOrCidPath(req.Arguments[0]) + if err != nil { + return err + } + + root, err := api.ResolveNode(req.Context, p) if err != nil { return err } diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index 120b760342f5..c2d75c929714 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -7,8 +7,8 @@ import ( "text/tabwriter" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" - path "github.com/ipfs/boxo/coreiface/path" merkledag "github.com/ipfs/boxo/ipld/merkledag" unixfs "github.com/ipfs/boxo/ipld/unixfs" cmds "github.com/ipfs/go-ipfs-cmds" @@ -96,7 +96,12 @@ If possible, please use 'ipfs ls' instead. for _, p := range paths { ctx := req.Context - merkleNode, err := api.ResolveNode(ctx, path.New(p)) + pth, err := cmdutils.PathOrCidPath(p) + if err != nil { + return err + } + + merkleNode, err := api.ResolveNode(ctx, pth) if err != nil { return err } diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 55810de7e9df..45095e619143 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -8,7 +8,7 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" + "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" @@ -22,7 +22,7 @@ import ( type BlockAPI CoreAPI type BlockStat struct { - path path.Resolved + path path.ImmutablePath size int } @@ -68,7 +68,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc } } - return &BlockStat{path: path.IpldPath(b.Cid()), size: len(data)}, nil + return &BlockStat{path: path.NewIPLDPath(b.Cid()), size: len(data)}, nil } func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { @@ -143,7 +143,7 @@ func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (coreiface.BlockStat } return &BlockStat{ - path: path.IpldPath(b.Cid()), + path: path.NewIPLDPath(b.Cid()), size: len(b.RawData()), }, nil } @@ -152,7 +152,7 @@ func (bs *BlockStat) Size() int { return bs.size } -func (bs *BlockStat) Path() path.Resolved { +func (bs *BlockStat) Path() path.ImmutablePath { return bs.path } diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index 4feb8a76c074..ded762e4a5b5 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -8,9 +8,9 @@ import ( blockstore "github.com/ipfs/boxo/blockstore" coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" offline "github.com/ipfs/boxo/exchange/offline" dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" "github.com/ipfs/kubo/tracing" diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 925748a37d28..4c914ff3d208 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -9,8 +9,8 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" - ipfspath "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/ipns" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/tracing" crypto "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" @@ -23,6 +23,19 @@ type KeyAPI CoreAPI type key struct { name string peerID peer.ID + path path.Path +} + +func newKey(name string, pid peer.ID) (*key, error) { + p, err := path.NewPath("/ipns/" + ipns.NameFromPeer(pid).String()) + if err != nil { + return nil, err + } + return &key{ + name: name, + peerID: pid, + path: p, + }, nil } // Name returns the key name @@ -32,7 +45,7 @@ func (k *key) Name() string { // Path returns the path of the key. func (k *key) Path() path.Path { - return path.New(ipfspath.Join([]string{"/ipns", coreiface.FormatKeyID(k.peerID)})) + return k.path } // ID returns key PeerID @@ -98,7 +111,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key return nil, err } - return &key{name, pid}, nil + return newKey(name, pid) } // List returns a list keys stored in keystore. @@ -114,7 +127,10 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { sort.Strings(keys) out := make([]coreiface.Key, len(keys)+1) - out[0] = &key{"self", api.identity} + out[0], err = newKey("self", api.identity) + if err != nil { + return nil, err + } for n, k := range keys { privKey, err := api.repo.Keystore().Get(k) @@ -129,7 +145,10 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { return nil, err } - out[n+1] = &key{k, pid} + out[n+1], err = newKey(k, pid) + if err != nil { + return nil, err + } } return out, nil } @@ -171,7 +190,8 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o // This is important, because future code will delete key `oldName` // even if it is the same as newName. if newName == oldName { - return &key{oldName, pid}, false, nil + k, err := newKey(oldName, pid) + return k, false, err } overwrite := false @@ -195,7 +215,13 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o return nil, false, err } - return &key{newName, pid}, overwrite, ks.Delete(oldName) + err = ks.Delete(oldName) + if err != nil { + return nil, false, err + } + + k, err := newKey(newName, pid) + return k, overwrite, err } // 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 return nil, err } - return &key{"", pid}, nil + return newKey("", pid) } func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) { @@ -234,5 +260,5 @@ func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) { return nil, errors.New("identity not loaded") } - return &key{"self", api.identity}, nil + return newKey("self", api.identity) } diff --git a/core/coreapi/name.go b/core/coreapi/name.go index 3bf59a00c4e8..0a398ef265a3 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -16,8 +16,7 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" nsopts "github.com/ipfs/boxo/coreiface/options/namesys" - path "github.com/ipfs/boxo/coreiface/path" - ipath "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" ci "github.com/libp2p/go-libp2p/core/crypto" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -51,11 +50,6 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam return ipns.Name{}, err } - pth, err := ipath.ParsePath(p.String()) - if err != nil { - return ipns.Name{}, err - } - k, err := keylookup(api.privateKey, api.repo.Keystore(), options.Key) if err != nil { return ipns.Name{}, err @@ -72,7 +66,7 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam publishOptions = append(publishOptions, nsopts.PublishWithTTL(*options.TTL)) } - err = api.namesys.Publish(ctx, k, pth, publishOptions...) + err = api.namesys.Publish(ctx, k, p, publishOptions...) if err != nil { return ipns.Name{}, err } @@ -120,7 +114,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name defer close(out) for res := range resolver.ResolveAsync(ctx, name, options.ResolveOpts...) { select { - case out <- coreiface.IpnsResult{Path: path.New(res.Path.String()), Err: res.Err}: + case out <- coreiface.IpnsResult{Path: res.Path, Err: res.Err}: case <-ctx.Done(): return } diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 1b1caea6575f..0b9550255e65 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -12,10 +12,10 @@ import ( coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - ipath "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/dagutils" ft "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" cid "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -65,7 +65,7 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( return n, nil } -func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (ipath.Resolved, error) { +func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Put") defer span.End() @@ -143,16 +143,16 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj } } - return ipath.IpfsPath(dagnode.Cid()), nil + return path.NewIPFSPath(dagnode.Cid()), nil } -func (api *ObjectAPI) Get(ctx context.Context, path ipath.Path) (ipld.Node, error) { +func (api *ObjectAPI) Get(ctx context.Context, path path.Path) (ipld.Node, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Get", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() return api.core().ResolveNode(ctx, path) } -func (api *ObjectAPI) Data(ctx context.Context, path ipath.Path) (io.Reader, error) { +func (api *ObjectAPI) Data(ctx context.Context, path path.Path) (io.Reader, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Data", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() @@ -169,7 +169,7 @@ func (api *ObjectAPI) Data(ctx context.Context, path ipath.Path) (io.Reader, err return bytes.NewReader(pbnd.Data()), nil } -func (api *ObjectAPI) Links(ctx context.Context, path ipath.Path) ([]*ipld.Link, error) { +func (api *ObjectAPI) Links(ctx context.Context, path path.Path) ([]*ipld.Link, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Links", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() @@ -187,7 +187,7 @@ func (api *ObjectAPI) Links(ctx context.Context, path ipath.Path) ([]*ipld.Link, return out, nil } -func (api *ObjectAPI) Stat(ctx context.Context, path ipath.Path) (*coreiface.ObjectStat, error) { +func (api *ObjectAPI) Stat(ctx context.Context, path path.Path) (*coreiface.ObjectStat, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Stat", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() @@ -213,7 +213,7 @@ func (api *ObjectAPI) Stat(ctx context.Context, path ipath.Path) (*coreiface.Obj return out, nil } -func (api *ObjectAPI) AddLink(ctx context.Context, base ipath.Path, name string, child ipath.Path, opts ...caopts.ObjectAddLinkOption) (ipath.Resolved, error) { +func (api *ObjectAPI) AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...caopts.ObjectAddLinkOption) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AddLink", trace.WithAttributes( attribute.String("base", base.String()), attribute.String("name", name), @@ -259,10 +259,10 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base ipath.Path, name string, return nil, err } - return ipath.IpfsPath(nnode.Cid()), nil + return path.NewIPFSPath(nnode.Cid()), nil } -func (api *ObjectAPI) RmLink(ctx context.Context, base ipath.Path, link string) (ipath.Resolved, error) { +func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "RmLink", trace.WithAttributes( attribute.String("base", base.String()), attribute.String("link", link)), @@ -291,25 +291,25 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base ipath.Path, link string) return nil, err } - return ipath.IpfsPath(nnode.Cid()), nil + return path.NewIPFSPath(nnode.Cid()), nil } -func (api *ObjectAPI) AppendData(ctx context.Context, path ipath.Path, r io.Reader) (ipath.Resolved, error) { +func (api *ObjectAPI) AppendData(ctx context.Context, path path.Path, r io.Reader) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AppendData", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() return api.patchData(ctx, path, r, true) } -func (api *ObjectAPI) SetData(ctx context.Context, path ipath.Path, r io.Reader) (ipath.Resolved, error) { +func (api *ObjectAPI) SetData(ctx context.Context, path path.Path, r io.Reader) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "SetData", trace.WithAttributes(attribute.String("path", path.String()))) defer span.End() return api.patchData(ctx, path, r, false) } -func (api *ObjectAPI) patchData(ctx context.Context, path ipath.Path, r io.Reader, appendData bool) (ipath.Resolved, error) { - nd, err := api.core().ResolveNode(ctx, path) +func (api *ObjectAPI) patchData(ctx context.Context, p path.Path, r io.Reader, appendData bool) (path.ImmutablePath, error) { + nd, err := api.core().ResolveNode(ctx, p) if err != nil { return nil, err } @@ -334,10 +334,10 @@ func (api *ObjectAPI) patchData(ctx context.Context, path ipath.Path, r io.Reade return nil, err } - return ipath.IpfsPath(pbnd.Cid()), nil + return path.NewIPFSPath(pbnd.Cid()), nil } -func (api *ObjectAPI) Diff(ctx context.Context, before ipath.Path, after ipath.Path) ([]coreiface.ObjectChange, error) { +func (api *ObjectAPI) Diff(ctx context.Context, before path.Path, after path.Path) ([]coreiface.ObjectChange, error) { ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Diff", trace.WithAttributes( attribute.String("before", before.String()), attribute.String("after", after.String()), @@ -367,11 +367,11 @@ func (api *ObjectAPI) Diff(ctx context.Context, before ipath.Path, after ipath.P } if change.Before.Defined() { - out[i].Before = ipath.IpfsPath(change.Before) + out[i].Before = path.NewIPFSPath(change.Before) } if change.After.Defined() { - out[i].After = ipath.IpfsPath(change.After) + out[i].After = path.NewIPFSPath(change.After) } } diff --git a/core/coreapi/path.go b/core/coreapi/path.go index db07c64281a8..0ed565723fe0 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -3,7 +3,6 @@ package coreapi import ( "context" "fmt" - gopath "path" "github.com/ipfs/boxo/namesys/resolve" "github.com/ipfs/kubo/tracing" @@ -12,10 +11,8 @@ import ( "go.opentelemetry.io/otel/trace" coreiface "github.com/ipfs/boxo/coreiface" - path "github.com/ipfs/boxo/coreiface/path" - ipfspath "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" ipfspathresolver "github.com/ipfs/boxo/path/resolver" - "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) @@ -39,45 +36,40 @@ func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, er // ResolvePath resolves the path `p` using Unixfs resolver, returns the // resolved path. -func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) { +func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI", "ResolvePath", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() - if _, ok := p.(path.Resolved); ok { - return p.(path.Resolved), nil - } - if err := p.IsValid(); err != nil { - return nil, err - } - - ipath := ipfspath.Path(p.String()) - ipath, err := resolve.ResolveIPNS(ctx, api.namesys, ipath) + p, err := resolve.ResolveIPNS(ctx, api.namesys, p) if err == resolve.ErrNoNamesys { return nil, coreiface.ErrOffline } else if err != nil { return nil, err } - if ipath.Segments()[0] != "ipfs" && ipath.Segments()[0] != "ipld" { - return nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace()) + if p.Namespace() != path.IPFSNamespace && p.Namespace() != path.IPLDNamespace { + return nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace().String()) } var resolver ipfspathresolver.Resolver - if ipath.Segments()[0] == "ipld" { + if p.Namespace() == path.IPLDNamespace { resolver = api.ipldPathResolver } else { resolver = api.unixFSPathResolver } - node, rest, err := resolver.ResolveToLastNode(ctx, ipath) + node, rest, err := resolver.ResolveToLastNode(ctx, p) if err != nil { return nil, err } - root, err := cid.Parse(ipath.Segments()[1]) + segments := []string{p.Namespace().String(), node.String()} + segments = append(segments, rest...) + + p, err = path.NewPathFromSegments(segments...) if err != nil { return nil, err } - return path.NewResolvedPath(ipath, node, root, gopath.Join(rest...)), nil + return path.NewImmutablePath(p) } diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index ec2cedb83fd4..64e311a7a766 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -7,9 +7,9 @@ import ( bserv "github.com/ipfs/boxo/blockservice" coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" offline "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/go-cid" "go.opentelemetry.io/otel/attribute" @@ -165,7 +165,7 @@ type pinStatus struct { // BadNode is used in PinVerifyRes type badNode struct { - path path.Resolved + path path.ImmutablePath err error } @@ -181,7 +181,7 @@ func (s *pinStatus) Err() error { return s.err } -func (n *badNode) Path() path.Resolved { +func (n *badNode) Path() path.ImmutablePath { return n.path } @@ -210,7 +210,7 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro links, err := getLinks(ctx, root) if err != nil { status := &pinStatus{ok: false, cid: root} - status.badNodes = []coreiface.BadPinNode{&badNode{path: path.IpldPath(root), err: err}} + status.badNodes = []coreiface.BadPinNode{&badNode{path: path.NewIPLDPath(root), err: err}} visited[root] = status return status } @@ -251,11 +251,11 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro type pinInfo struct { pinType string - path path.Resolved + path path.ImmutablePath err error } -func (p *pinInfo) Path() path.Resolved { +func (p *pinInfo) Path() path.ImmutablePath { return p.path } @@ -281,7 +281,7 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac select { case out <- &pinInfo{ pinType: typeStr, - path: path.IpldPath(c), + path: path.NewIPLDPath(c), }: case <-ctx.Done(): return ctx.Err() diff --git a/core/coreapi/routing.go b/core/coreapi/routing.go index 95b50aa631d2..3b28e0472c1b 100644 --- a/core/coreapi/routing.go +++ b/core/coreapi/routing.go @@ -3,10 +3,10 @@ package coreapi import ( "context" "errors" + "strings" coreiface "github.com/ipfs/boxo/coreiface" caopts "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/path" peer "github.com/libp2p/go-libp2p/core/peer" ) @@ -45,7 +45,7 @@ func (r *RoutingAPI) Put(ctx context.Context, key string, value []byte, opts ... } func normalizeKey(s string) (string, error) { - parts := path.SplitList(s) + parts := strings.Split(s, "/") if len(parts) != 3 || parts[0] != "" || !(parts[1] == "ipns" || parts[1] == "pk") { @@ -56,5 +56,5 @@ func normalizeKey(s string) (string, error) { if err != nil { return "", err } - return path.Join(append(parts[:2], string(k))), nil + return strings.Join(append(parts[:2], string(k)), "/"), nil } diff --git a/core/coreapi/test/path_test.go b/core/coreapi/test/path_test.go index 0dce72627990..cbfddd538cb8 100644 --- a/core/coreapi/test/path_test.go +++ b/core/coreapi/test/path_test.go @@ -7,10 +7,10 @@ import ( "time" "github.com/ipfs/boxo/coreiface/options" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/ipld/merkledag" uio "github.com/ipfs/boxo/ipld/unixfs/io" + "github.com/ipfs/boxo/path" "github.com/ipld/go-ipld-prime" ) @@ -55,7 +55,7 @@ func TestPathUnixFSHAMTPartial(t *testing.T) { pbNode := nd.(*merkledag.ProtoNode) // Remove one of the sharded directory blocks - if err := a.Block().Rm(ctx, path.IpfsPath(pbNode.Links()[0].Cid)); err != nil { + if err := a.Block().Rm(ctx, path.NewIPFSPath(pbNode.Links()[0].Cid)); err != nil { t.Fatal(err) } @@ -67,7 +67,12 @@ func TestPathUnixFSHAMTPartial(t *testing.T) { // The node will go out to the (non-existent) network looking for the missing block. Make sure we're erroring // because we exceeded the timeout on our query timeoutCtx, timeoutCancel := context.WithTimeout(ctx, time.Second*1) - _, err := a.ResolveNode(timeoutCtx, path.Join(r, k)) + newPath, err := path.Join(r, k) + if err != nil { + t.Fatal(err) + } + + _, err = a.ResolveNode(timeoutCtx, newPath) if err != nil { if timeoutCtx.Err() == nil { t.Fatal(err) diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index e1a607d7397e..778fef5c1b69 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -16,7 +16,6 @@ import ( bstore "github.com/ipfs/boxo/blockstore" coreiface "github.com/ipfs/boxo/coreiface" options "github.com/ipfs/boxo/coreiface/options" - path "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" filestore "github.com/ipfs/boxo/filestore" merkledag "github.com/ipfs/boxo/ipld/merkledag" @@ -25,6 +24,7 @@ import ( unixfile "github.com/ipfs/boxo/ipld/unixfs/file" uio "github.com/ipfs/boxo/ipld/unixfs/io" mfs "github.com/ipfs/boxo/mfs" + "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" cidutil "github.com/ipfs/go-cidutil" ipld "github.com/ipfs/go-ipld-format" @@ -58,7 +58,7 @@ func getOrCreateNilNode() (*core.IpfsNode, error) { // Add builds a merkledag node from a reader, adds it to the blockstore, // and returns the key representing that node. -func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options.UnixfsAddOption) (path.Resolved, error) { +func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options.UnixfsAddOption) (path.ImmutablePath, error) { ctx, span := tracing.Span(ctx, "CoreAPI.UnixfsAPI", "Add") defer span.End() @@ -201,7 +201,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options } } - return path.IpfsPath(nd.Cid()), nil + return path.NewIPFSPath(nd.Cid()), nil } func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) { diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 63abc5922fc4..6edb2c119519 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -9,7 +9,6 @@ import ( "strconv" "strings" - path "github.com/ipfs/boxo/path" cmds "github.com/ipfs/go-ipfs-cmds" cmdsHttp "github.com/ipfs/go-ipfs-cmds/http" version "github.com/ipfs/kubo" @@ -171,7 +170,7 @@ func CheckVersionOption() ServeOption { parent.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if strings.HasPrefix(r.URL.Path, APIPath) { cmdqry := r.URL.Path[len(APIPath):] - pth := path.SplitList(cmdqry) + pth := strings.Split(cmdqry, "/") // backwards compatibility to previous version check if len(pth) >= 2 && pth[1] != "version" { diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 105fa89af757..4650c806dacb 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -10,11 +10,11 @@ import ( "github.com/ipfs/boxo/blockservice" iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/exchange/offline" "github.com/ipfs/boxo/files" "github.com/ipfs/boxo/gateway" "github.com/ipfs/boxo/namesys" + "github.com/ipfs/boxo/path" offlineroute "github.com/ipfs/boxo/routing/offline" "github.com/ipfs/go-cid" version "github.com/ipfs/kubo" @@ -124,37 +124,37 @@ func offlineErrWrap(err error) error { return err } -func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path gateway.ImmutablePath, ranges ...gateway.ByteRange) (gateway.ContentPathMetadata, *gateway.GetResponse, error) { +func (o *offlineGatewayErrWrapper) Get(ctx context.Context, path path.ImmutablePath, ranges ...gateway.ByteRange) (gateway.ContentPathMetadata, *gateway.GetResponse, error) { md, n, err := o.gwimpl.Get(ctx, path, ranges...) err = offlineErrWrap(err) return md, n, err } -func (o *offlineGatewayErrWrapper) GetAll(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { +func (o *offlineGatewayErrWrapper) GetAll(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { md, n, err := o.gwimpl.GetAll(ctx, path) err = offlineErrWrap(err) return md, n, err } -func (o *offlineGatewayErrWrapper) GetBlock(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.File, error) { +func (o *offlineGatewayErrWrapper) GetBlock(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, files.File, error) { md, n, err := o.gwimpl.GetBlock(ctx, path) err = offlineErrWrap(err) return md, n, err } -func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { +func (o *offlineGatewayErrWrapper) Head(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, files.Node, error) { md, n, err := o.gwimpl.Head(ctx, path) err = offlineErrWrap(err) return md, n, err } -func (o *offlineGatewayErrWrapper) ResolvePath(ctx context.Context, path gateway.ImmutablePath) (gateway.ContentPathMetadata, error) { +func (o *offlineGatewayErrWrapper) ResolvePath(ctx context.Context, path path.ImmutablePath) (gateway.ContentPathMetadata, error) { md, err := o.gwimpl.ResolvePath(ctx, path) err = offlineErrWrap(err) return md, err } -func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path gateway.ImmutablePath, params gateway.CarParams) (gateway.ContentPathMetadata, io.ReadCloser, error) { +func (o *offlineGatewayErrWrapper) GetCAR(ctx context.Context, path path.ImmutablePath, params gateway.CarParams) (gateway.ContentPathMetadata, io.ReadCloser, error) { md, data, err := o.gwimpl.GetCAR(ctx, path, params) err = offlineErrWrap(err) return md, data, err @@ -170,7 +170,7 @@ func (o *offlineGatewayErrWrapper) GetIPNSRecord(ctx context.Context, c cid.Cid) return rec, err } -func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (gateway.ImmutablePath, error) { +func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (path.ImmutablePath, error) { imPath, err := o.gwimpl.ResolveMutable(ctx, path) err = offlineErrWrap(err) return imPath, err diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 172988bba998..86143bda6875 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -46,7 +46,7 @@ func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...nsopts.Re var ok bool value, ok = m[name] if !ok { - return "", namesys.ErrResolveFailed + return nil, namesys.ErrResolveFailed } name = value.String() } diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 31a867b037d1..3a2b91c4bab7 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -11,7 +11,6 @@ import ( bstore "github.com/ipfs/boxo/blockstore" chunker "github.com/ipfs/boxo/chunker" coreiface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" posinfo "github.com/ipfs/boxo/filestore/posinfo" dag "github.com/ipfs/boxo/ipld/merkledag" @@ -20,6 +19,7 @@ import ( ihelper "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" "github.com/ipfs/boxo/ipld/unixfs/importer/trickle" "github.com/ipfs/boxo/mfs" + "github.com/ipfs/boxo/path" pin "github.com/ipfs/boxo/pinning/pinner" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" @@ -506,7 +506,7 @@ func getOutput(dagnode ipld.Node) (*coreiface.AddEvent, error) { } output := &coreiface.AddEvent{ - Path: path.IpfsPath(c), + Path: path.NewIPFSPath(c), Size: strconv.FormatUint(s, 10), } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index bb88ad996964..d6e5e700e6e7 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.20 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd + github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.30.0 github.com/multiformats/go-multiaddr v0.11.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 0ab47be1aef6..ab4e7ef20d0d 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581 h1:kJbzfNofJ8r36W8QFVp9lw+A7bUjF5D8XN+lxIff7sc= +github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/docs/examples/kubo-as-a-library/main.go b/docs/examples/kubo-as-a-library/main.go index 785973c5baae..aed916982fab 100644 --- a/docs/examples/kubo-as-a-library/main.go +++ b/docs/examples/kubo-as-a-library/main.go @@ -12,8 +12,8 @@ import ( "sync" icore "github.com/ipfs/boxo/coreiface" - icorepath "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" ma "github.com/multiformats/go-multiaddr" "github.com/ipfs/kubo/config" @@ -324,7 +324,7 @@ func main() { fmt.Printf("Fetching a file from the network with CID %s\n", exampleCIDStr) outputPath := outputBasePath + exampleCIDStr - testCID := icorepath.New(exampleCIDStr) + testCID := path.NewIPFSPath(peerCidFile.Cid()) rootNode, err := ipfsB.Unixfs().Get(ctx, testCID) if err != nil { diff --git a/fuse/ipns/common.go b/fuse/ipns/common.go index db231fe4570d..ad8ff8a6b6da 100644 --- a/fuse/ipns/common.go +++ b/fuse/ipns/common.go @@ -5,7 +5,7 @@ import ( ft "github.com/ipfs/boxo/ipld/unixfs" nsys "github.com/ipfs/boxo/namesys" - path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core" ci "github.com/libp2p/go-libp2p/core/crypto" ) @@ -30,5 +30,5 @@ func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error { pub := nsys.NewIpnsPublisher(n.Routing, n.Repo.Datastore()) - return pub.Publish(ctx, key, path.FromCid(emptyDir.Cid())) + return pub.Publish(ctx, key, path.NewIPFSPath(emptyDir.Cid())) } diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index b666340158b6..8cf6969696a6 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -14,9 +14,9 @@ import ( "strings" "syscall" - path "github.com/ipfs/boxo/coreiface/path" dag "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" + "github.com/ipfs/boxo/path" fuse "bazil.org/fuse" fs "bazil.org/fuse/fs" @@ -86,7 +86,7 @@ type Root struct { func ipnsPubFunc(ipfs iface.CoreAPI, key iface.Key) mfs.PubFunc { return func(ctx context.Context, c cid.Cid) error { - _, err := ipfs.Name().Publish(ctx, path.IpfsPath(c), options.Name.Key(key.Name())) + _, err := ipfs.Name().Publish(ctx, path.NewIPFSPath(c), options.Name.Key(key.Name())) return err } } @@ -186,7 +186,7 @@ func (r *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, syscall.Errno(syscall.ENOENT) } - if resolved.Namespace() != "ipfs" { + if resolved.Namespace() != path.IPFSNamespace { return nil, errors.New("invalid path from ipns record") } diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index bc6204abb6a8..76f7a3cdfbb4 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -11,7 +11,7 @@ import ( "io" "math/rand" "os" - "path" + gopath "path" "strings" "sync" "testing" @@ -24,11 +24,11 @@ import ( fstest "bazil.org/fuse/fs/fstestutil" chunker "github.com/ipfs/boxo/chunker" - ipath "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" dag "github.com/ipfs/boxo/ipld/merkledag" importer "github.com/ipfs/boxo/ipld/unixfs/importer" uio "github.com/ipfs/boxo/ipld/unixfs/io" + "github.com/ipfs/boxo/path" u "github.com/ipfs/boxo/util" ipld "github.com/ipfs/go-ipld-format" ci "github.com/libp2p/go-libp2p-testing/ci" @@ -89,7 +89,7 @@ func TestIpfsBasicRead(t *testing.T) { fi, data := randObj(t, nd, 10000) k := fi.Cid() - fname := path.Join(mnt.Dir, k.String()) + fname := gopath.Join(mnt.Dir, k.String()) rbuf, err := os.ReadFile(fname) if err != nil { t.Fatal(err) @@ -116,7 +116,7 @@ func getPaths(t *testing.T, ipfs *core.IpfsNode, name string, n *dag.ProtoNode) t.Fatal(dag.ErrNotProtobuf) } - sub := getPaths(t, ipfs, path.Join(name, lnk.Name), childpb) + sub := getPaths(t, ipfs, gopath.Join(name, lnk.Name), childpb) out = append(out, sub...) } return out @@ -184,10 +184,14 @@ func TestIpfsStressRead(t *testing.T) { defer wg.Done() for i := 0; i < 2000; i++ { - item := ipath.New(paths[rand.Intn(len(paths))]) + item, err := path.NewPath(paths[rand.Intn(len(paths))]) + if err != nil { + errs <- err + continue + } - relpath := strings.Replace(item.String(), item.Namespace(), "", 1) - fname := path.Join(mnt.Dir, relpath) + relpath := strings.Replace(item.String(), item.Namespace().String(), "", 1) + fname := gopath.Join(mnt.Dir, relpath) rbuf, err := os.ReadFile(fname) if err != nil { @@ -257,8 +261,8 @@ func TestIpfsBasicDirRead(t *testing.T) { t.Fatal(err) } - dirname := path.Join(mnt.Dir, d1nd.Cid().String()) - fname := path.Join(dirname, "actual") + dirname := gopath.Join(mnt.Dir, d1nd.Cid().String()) + fname := gopath.Join(dirname, "actual") rbuf, err := os.ReadFile(fname) if err != nil { t.Fatal(err) @@ -291,7 +295,7 @@ func TestFileSizeReporting(t *testing.T) { fi, data := randObj(t, nd, 10000) k := fi.Cid() - fname := path.Join(mnt.Dir, k.String()) + fname := gopath.Join(mnt.Dir, k.String()) finfo, err := os.Stat(fname) if err != nil { diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index 3ecda1cf3587..f38f2c52e368 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -16,7 +16,7 @@ import ( mdag "github.com/ipfs/boxo/ipld/merkledag" ft "github.com/ipfs/boxo/ipld/unixfs" uio "github.com/ipfs/boxo/ipld/unixfs/io" - path "github.com/ipfs/boxo/path" + "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" @@ -62,7 +62,7 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { return nil, syscall.Errno(syscall.ENOENT) } - p, err := path.ParsePath(name) + p, err := path.NewPath(name) if err != nil { log.Debugf("fuse failed to parse path: %q: %s", name, err) return nil, syscall.Errno(syscall.ENOENT) diff --git a/go.mod b/go.mod index d3ff353c6762..437ed9c8e910 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd + github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index e478ea733386..96fb5a5e9ec6 100644 --- a/go.sum +++ b/go.sum @@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581 h1:kJbzfNofJ8r36W8QFVp9lw+A7bUjF5D8XN+lxIff7sc= +github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go index b35cab683d8c..cd6a5182ee12 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go @@ -7,14 +7,14 @@ import ( "io" "net/url" "os" - "path" + gopath "path" "strings" "sync" iface "github.com/ipfs/boxo/coreiface" "github.com/ipfs/boxo/coreiface/options" - ipath "github.com/ipfs/boxo/coreiface/path" "github.com/ipfs/boxo/files" + "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/core" "github.com/ipfs/kubo/core/coreapi" @@ -46,7 +46,7 @@ type IpfsFetcher struct { ipfsTmpDir string ipfsStopFunc func() - fetched []ipath.Path + fetched []path.Path mutex sync.Mutex addrInfo peer.AddrInfo @@ -108,7 +108,7 @@ func (f *IpfsFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error return nil, f.openErr } - iPath, err := parsePath(path.Join(f.distPath, filePath)) + iPath, err := parsePath(gopath.Join(f.distPath, filePath)) if err != nil { return nil, err } @@ -156,13 +156,13 @@ func (f *IpfsFetcher) AddrInfo() peer.AddrInfo { } // FetchedPaths returns the IPFS paths of all items fetched by this fetcher. -func (f *IpfsFetcher) FetchedPaths() []ipath.Path { +func (f *IpfsFetcher) FetchedPaths() []path.Path { f.mutex.Lock() defer f.mutex.Unlock() return f.fetched } -func (f *IpfsFetcher) recordFetched(fetchedPath ipath.Path) { +func (f *IpfsFetcher) recordFetched(fetchedPath path.Path) { // Mutex protects against update by concurrent calls to Fetch f.mutex.Lock() defer f.mutex.Unlock() @@ -267,9 +267,8 @@ func (f *IpfsFetcher) startTempNode(ctx context.Context) error { return nil } -func parsePath(fetchPath string) (ipath.Path, error) { - ipfsPath := ipath.New(fetchPath) - if ipfsPath.IsValid() == nil { +func parsePath(fetchPath string) (path.Path, error) { + if ipfsPath, err := path.NewPath(fetchPath); err == nil { return ipfsPath, nil } @@ -280,11 +279,10 @@ func parsePath(fetchPath string) (ipath.Path, error) { switch proto := u.Scheme; proto { case "ipfs", "ipld", "ipns": - ipfsPath = ipath.New(path.Join("/", proto, u.Host, u.Path)) + return path.NewPath(gopath.Join("/", proto, u.Host, u.Path)) default: return nil, fmt.Errorf("%q is not an IPFS path", fetchPath) } - return ipfsPath, ipfsPath.IsValid() } func readIpfsConfig(repoRoot *string, userConfigFile string) (bootstrap []string, peers []peer.AddrInfo) { diff --git a/tar/format.go b/tar/format.go index bde92398057e..a1fe455b4a5b 100644 --- a/tar/format.go +++ b/tar/format.go @@ -6,13 +6,13 @@ import ( "context" "errors" "io" + "path" "strings" dag "github.com/ipfs/boxo/ipld/merkledag" "github.com/ipfs/boxo/ipld/merkledag/dagutils" importer "github.com/ipfs/boxo/ipld/unixfs/importer" uio "github.com/ipfs/boxo/ipld/unixfs/io" - path "github.com/ipfs/boxo/path" chunker "github.com/ipfs/boxo/chunker" ipld "github.com/ipfs/go-ipld-format" @@ -95,11 +95,11 @@ func ImportTar(ctx context.Context, r io.Reader, ds ipld.DAGService) (*dag.Proto // adds a '-' to the beginning of each path element so we can use 'data' as a // special link in the structure without having to worry about. func escapePath(pth string) string { - elems := path.SplitList(strings.Trim(pth, "/")) + elems := strings.Split(strings.Trim(pth, "/"), "/") for i, e := range elems { elems[i] = "-" + e } - return path.Join(elems) + return path.Join(elems...) } type tarReader struct { diff --git a/test/cli/gateway_test.go b/test/cli/gateway_test.go index 168acfdb9990..c585a277e49c 100644 --- a/test/cli/gateway_test.go +++ b/test/cli/gateway_test.go @@ -408,9 +408,9 @@ func TestGateway(t *testing.T) { t.Parallel() gatewayAddr := URLStrToMultiaddr(node.GatewayURL()) res := node.RunIPFS("--api", gatewayAddr.String(), "refs", "local") - assert.Equal(t, - `Error: invalid path "local": invalid cid: selected encoding not supported`, + assert.Contains(t, res.Stderr.Trimmed(), + `Error: invalid path "local":`, ) }) diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index 094cd9797b2a..c8ac59e848b1 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../ require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd github.com/golangci/golangci-lint v1.54.1 - github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd + github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index 3c8cb6f87e3f..1d92464fa37a 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -396,8 +396,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd h1:uAp9W7FRQ7W16FENlURZqBh7/3PnakG0DjHpKPirKVY= -github.com/ipfs/boxo v0.12.1-0.20230825151903-13569468babd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= +github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581 h1:kJbzfNofJ8r36W8QFVp9lw+A7bUjF5D8XN+lxIff7sc= +github.com/ipfs/boxo v0.12.1-0.20230906083417-32140848b581/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index 2f3838db475b..67fee89093a2 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -129,9 +129,8 @@ test_get_cmd() { ' test_expect_success "ipfs get ../.. should fail" ' - echo "Error: invalid path \"../..\": invalid cid: selected encoding not supported" >expected && test_must_fail ipfs get ../.. 2>actual && - test_cmp expected actual + test_should_contain "Error: invalid path \"../..\"" actual ' test_expect_success "create small file" '