From 9047fed8d5c3b6935c9a2358de2689451fcb7047 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 22 Mar 2024 09:32:30 +0100 Subject: [PATCH] core/commands!: remove deprecated object APIs (#10375) --- assets/assets.go | 24 +- bin/ipns-republish | 2 +- client/rpc/object.go | 172 ------ core/commands/commands_test.go | 5 + core/commands/dht.go | 18 +- core/commands/object/object.go | 540 +----------------- core/commands/object/patch.go | 116 +--- core/coreapi/object.go | 263 --------- core/coreiface/object.go | 49 -- core/coreiface/options/object.go | 90 --- core/coreiface/tests/object.go | 467 +++------------ core/coreiface/tests/unixfs.go | 20 +- docs/changelogs/v0.28.md | 5 + docs/implement-api-bindings.md | 5 +- test/cli/basic_commands_test.go | 3 - .../testPut.pb | 0 test/sharness/t0050-block.sh | 22 +- .../sharness/t0051-object-data/UTF-8-test.txt | Bin 20350 -> 0 bytes .../sharness/t0051-object-data/brokenPut.json | 5 - test/sharness/t0051-object-data/brokenPut.xml | 1 - .../t0051-object-data/expected_getOut | 1 - test/sharness/t0051-object-data/mixed.json | 5 - test/sharness/t0051-object-data/testPut.json | 3 - test/sharness/t0051-object-data/testPut.xml | 1 - test/sharness/t0051-object.sh | 363 +----------- test/sharness/t0081-repo-pinning.sh | 6 +- test/sharness/t0090-get.sh | 6 +- test/sharness/t0252-files-gc.sh | 4 +- 28 files changed, 163 insertions(+), 2033 deletions(-) rename test/sharness/{t0051-object-data => t0050-block-data}/testPut.pb (100%) delete mode 100644 test/sharness/t0051-object-data/UTF-8-test.txt delete mode 100644 test/sharness/t0051-object-data/brokenPut.json delete mode 100644 test/sharness/t0051-object-data/brokenPut.xml delete mode 100644 test/sharness/t0051-object-data/expected_getOut delete mode 100644 test/sharness/t0051-object-data/mixed.json delete mode 100644 test/sharness/t0051-object-data/testPut.json delete mode 100644 test/sharness/t0051-object-data/testPut.xml diff --git a/assets/assets.go b/assets/assets.go index 17bfa89413a..6196ed22f89 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -9,9 +9,7 @@ import ( "github.com/ipfs/kubo/core/coreapi" "github.com/ipfs/boxo/files" - "github.com/ipfs/boxo/path" cid "github.com/ipfs/go-cid" - options "github.com/ipfs/kubo/core/coreiface/options" ) //go:embed init-doc @@ -39,12 +37,7 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { return cid.Cid{}, err } - dirb, err := api.Object().New(nd.Context(), options.Object.Type("unixfs-dir")) - if err != nil { - return cid.Cid{}, err - } - - basePath := path.FromCid(dirb.Cid()) + dirMap := map[string]files.Node{} for _, p := range l { d, err := Asset.ReadFile(p) @@ -52,17 +45,12 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { return cid.Cid{}, fmt.Errorf("assets: could load Asset '%s': %s", p, err) } - fp, err := api.Unixfs().Add(nd.Context(), files.NewBytesFile(d)) - if err != nil { - return cid.Cid{}, err - } - - fname := gopath.Base(p) + dirMap[gopath.Base(p)] = files.NewBytesFile(d) + } - basePath, err = api.Object().AddLink(nd.Context(), basePath, fname, fp) - if err != nil { - return cid.Cid{}, err - } + basePath, err := api.Unixfs().Add(nd.Context(), files.NewMapDirectory(dirMap)) + if err != nil { + return cid.Cid{}, err } if err := api.Pin().Add(nd.Context(), basePath); err != nil { diff --git a/bin/ipns-republish b/bin/ipns-republish index f5535ee4c4a..5fc81cd5724 100755 --- a/bin/ipns-republish +++ b/bin/ipns-republish @@ -19,7 +19,7 @@ if [ $? -ne 0 ]; then fi # check the object is there -ipfs object stat "$1" >/dev/null +ipfs dag stat "$1" >/dev/null if [ $? -ne 0 ]; then echo "error: ipfs cannot find $1" exit 1 diff --git a/client/rpc/object.go b/client/rpc/object.go index 9e00bfb7711..5c9d323e87b 100644 --- a/client/rpc/object.go +++ b/client/rpc/object.go @@ -1,16 +1,10 @@ package rpc import ( - "bytes" "context" - "fmt" - "io" - "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" iface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" ) @@ -21,138 +15,6 @@ type objectOut struct { Hash string } -func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (ipld.Node, error) { - options, err := caopts.ObjectNewOptions(opts...) - if err != nil { - return nil, err - } - - var n ipld.Node - switch options.Type { - case "empty": - n = new(merkledag.ProtoNode) - case "unixfs-dir": - n = ft.EmptyDirNode() - default: - return nil, fmt.Errorf("unknown object type: %s", options.Type) - } - - return n, nil -} - -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 path.ImmutablePath{}, err - } - - var out objectOut - err = api.core().Request("object/put"). - Option("inputenc", options.InputEnc). - Option("datafieldenc", options.DataType). - Option("pin", options.Pin). - FileBody(r). - Exec(ctx, &out) - if err != nil { - return path.ImmutablePath{}, err - } - - c, err := cid.Parse(out.Hash) - if err != nil { - return path.ImmutablePath{}, err - } - - return path.FromCid(c), nil -} - -func (api *ObjectAPI) Get(ctx context.Context, p path.Path) (ipld.Node, error) { - r, err := api.core().Block().Get(ctx, p) - if err != nil { - return nil, err - } - b, err := io.ReadAll(r) - if err != nil { - return nil, err - } - - return merkledag.DecodeProtobuf(b) -} - -func (api *ObjectAPI) Data(ctx context.Context, p path.Path) (io.Reader, error) { - resp, err := api.core().Request("object/data", p.String()).Send(ctx) - if err != nil { - return nil, err - } - if resp.Error != nil { - return nil, resp.Error - } - - // TODO: make Data return ReadCloser to avoid copying - defer resp.Close() - b := new(bytes.Buffer) - if _, err := io.Copy(b, resp.Output); err != nil { - return nil, err - } - - return b, nil -} - -func (api *ObjectAPI) Links(ctx context.Context, p path.Path) ([]*ipld.Link, error) { - var out struct { - Links []struct { - Name string - Hash string - Size uint64 - } - } - if err := api.core().Request("object/links", p.String()).Exec(ctx, &out); err != nil { - return nil, err - } - res := make([]*ipld.Link, len(out.Links)) - for i, l := range out.Links { - c, err := cid.Parse(l.Hash) - if err != nil { - return nil, err - } - - res[i] = &ipld.Link{ - Cid: c, - Name: l.Name, - Size: l.Size, - } - } - - return res, nil -} - -func (api *ObjectAPI) Stat(ctx context.Context, p path.Path) (*iface.ObjectStat, error) { - var out struct { - Hash string - NumLinks int - BlockSize int - LinksSize int - DataSize int - CumulativeSize int - } - if err := api.core().Request("object/stat", p.String()).Exec(ctx, &out); err != nil { - return nil, err - } - - c, err := cid.Parse(out.Hash) - if err != nil { - return nil, err - } - - return &iface.ObjectStat{ - Cid: c, - NumLinks: out.NumLinks, - BlockSize: out.BlockSize, - LinksSize: out.LinksSize, - DataSize: out.DataSize, - CumulativeSize: out.CumulativeSize, - }, nil -} - 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 { @@ -191,40 +53,6 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) ( return path.FromCid(c), nil } -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). - Exec(ctx, &out) - if err != nil { - return path.ImmutablePath{}, err - } - - c, err := cid.Parse(out.Hash) - if err != nil { - return path.ImmutablePath{}, err - } - - return path.FromCid(c), nil -} - -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). - Exec(ctx, &out) - if err != nil { - return path.ImmutablePath{}, err - } - - c, err := cid.Parse(out.Hash) - if err != nil { - return path.ImmutablePath{}, err - } - - return path.FromCid(c), nil -} - type change struct { Type iface.ChangeType Path string diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 9e4da274cb7..38172fd66d9 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -61,6 +61,11 @@ func TestCommands(t *testing.T) { "/dag/stat", "/dht", "/dht/query", + "/dht/findprovs", + "/dht/findpeer", + "/dht/get", + "/dht/provide", + "/dht/put", "/routing", "/routing/put", "/routing/get", diff --git a/core/commands/dht.go b/core/commands/dht.go index c86b6262f8b..1d46201819b 100644 --- a/core/commands/dht.go +++ b/core/commands/dht.go @@ -15,13 +15,19 @@ import ( var ErrNotDHT = errors.New("routing service is not a DHT") var DhtCmd = &cmds.Command{ + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Issue commands directly through the DHT.", ShortDescription: ``, }, Subcommands: map[string]*cmds.Command{ - "query": queryDhtCmd, + "query": queryDhtCmd, + "findprovs": RemovedDHTCmd, + "findpeer": RemovedDHTCmd, + "get": RemovedDHTCmd, + "put": RemovedDHTCmd, + "provide": RemovedDHTCmd, }, } @@ -32,6 +38,7 @@ type kademlia interface { } var queryDhtCmd = &cmds.Command{ + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Find the closest Peer IDs to a given Peer ID by querying the DHT.", ShortDescription: "Outputs a list of newline-delimited Peer IDs.", @@ -114,3 +121,12 @@ var queryDhtCmd = &cmds.Command{ }, Type: routing.QueryEvent{}, } +var RemovedDHTCmd = &cmds.Command{ + Status: cmds.Removed, + Helptext: cmds.HelpText{ + Tagline: "Removed, use 'ipfs routing' instead.", + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + return errors.New("removed, use 'ipfs routing' instead") + }, +} diff --git a/core/commands/object/object.go b/core/commands/object/object.go index 5a8577cf295..380ca253389 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -1,28 +1,11 @@ package objectcmd import ( - "encoding/base64" "errors" - "fmt" - "io" - "text/tabwriter" 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" - dag "github.com/ipfs/boxo/ipld/merkledag" - "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" - "github.com/ipfs/kubo/core/coreiface/options" ) -type Node struct { - Links []Link - Data string -} - type Link struct { Name, Hash string Size uint64 @@ -35,16 +18,6 @@ type Object struct { var ErrDataEncoding = errors.New("unknown data field encoding") -const ( - headersOptionName = "headers" - encodingOptionName = "data-encoding" - inputencOptionName = "inputenc" - datafieldencOptionName = "datafieldenc" - pinOptionName = "pin" - quietOptionName = "quiet" - humanOptionName = "human" -) - var ObjectCmd = &cmds.Command{ Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 Helptext: cmds.HelpText{ @@ -55,516 +28,23 @@ directly. Deprecated, use more modern 'ipfs dag' and 'ipfs files' instead.`, }, Subcommands: map[string]*cmds.Command{ - "data": ObjectDataCmd, + "data": RemovedObjectCmd, "diff": ObjectDiffCmd, - "get": ObjectGetCmd, - "links": ObjectLinksCmd, - "new": ObjectNewCmd, + "get": RemovedObjectCmd, + "links": RemovedObjectCmd, + "new": RemovedObjectCmd, "patch": ObjectPatchCmd, - "put": ObjectPutCmd, - "stat": ObjectStatCmd, - }, -} - -// ObjectDataCmd object data command -var ObjectDataCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to read the raw bytes of a dag-pb object: use 'dag get' instead.", - ShortDescription: ` -'ipfs object data' is a deprecated plumbing command for retrieving the raw -bytes stored in a dag-pb node. It outputs to stdout, and is a base58 -encoded multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. -`, - LongDescription: ` -'ipfs object data' is a deprecated plumbing command for retrieving the raw -bytes stored in a dag-pb node. It outputs to stdout, and is a base58 -encoded multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. - -Note that the "--encoding" option does not affect the output, since the output -is the raw data of the object. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - path, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - data, err := api.Object().Data(req.Context, path) - if err != nil { - return err - } - - return res.Emit(data) - }, -} - -// ObjectLinksCmd object links command -var ObjectLinksCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to output links in the specified dag-pb object: use 'dag get' instead.", - ShortDescription: ` -'ipfs object links' is a plumbing command for retrieving the links from -a dag-pb node. It outputs to stdout, and is a base58 encoded -multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "Key of the dag-pb object to retrieve, in base58-encoded multihash format.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.BoolOption(headersOptionName, "v", "Print table headers (Hash, Size, Name)."), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - path, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - rp, _, err := api.ResolvePath(req.Context, path) - if err != nil { - return err - } - - links, err := api.Object().Links(req.Context, rp) - if err != nil { - return err - } - - outLinks := make([]Link, len(links)) - for i, link := range links { - outLinks[i] = Link{ - Hash: enc.Encode(link.Cid), - Name: link.Name, - Size: link.Size, - } - } - - out := &Object{ - Hash: enc.Encode(rp.RootCid()), - Links: outLinks, - } - - return cmds.EmitOnce(res, out) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { - tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0) - headers, _ := req.Options[headersOptionName].(bool) - if headers { - fmt.Fprintln(tw, "Hash\tSize\tName") - } - for _, link := range out.Links { - fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, cmdenv.EscNonPrint(link.Name)) - } - tw.Flush() - - return nil - }), - }, - Type: &Object{}, -} - -// ObjectGetCmd object get command -var ObjectGetCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to get and serialize the dag-pb node. Use 'dag get' instead", - ShortDescription: ` -'ipfs object get' is a plumbing command for retrieving dag-pb nodes. -It serializes the DAG node to the format specified by the "--encoding" -flag. It outputs to stdout, and is a base58 encoded multihash. - -DEPRECATED and provided for legacy reasons. Use 'ipfs dag get' instead. -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "Key of the dag-pb object to retrieve, in base58-encoded multihash format.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.StringOption(encodingOptionName, "Encoding type of the data field, either \"text\" or \"base64\".").WithDefault("text"), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - path, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - datafieldenc, _ := req.Options[encodingOptionName].(string) - if err != nil { - return err - } - - nd, err := api.Object().Get(req.Context, path) - if err != nil { - return err - } - - r, err := api.Object().Data(req.Context, path) - if err != nil { - return err - } - - data, err := io.ReadAll(r) - if err != nil { - return err - } - - out, err := encodeData(data, datafieldenc) - if err != nil { - return err - } - - node := &Node{ - Links: make([]Link, len(nd.Links())), - Data: out, - } - - for i, link := range nd.Links() { - node.Links[i] = Link{ - Hash: enc.Encode(link.Cid), - Name: link.Name, - Size: link.Size, - } - } - - return cmds.EmitOnce(res, node) - }, - Type: Node{}, - Encoders: cmds.EncoderMap{ - cmds.Protobuf: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Node) error { - // deserialize the Data field as text as this was the standard behaviour - object, err := deserializeNode(out, "text") - if err != nil { - return nil - } - - marshaled, err := object.Marshal() - if err != nil { - return err - } - _, err = w.Write(marshaled) - return err - }), - }, -} - -// ObjectStatCmd object stat command -var ObjectStatCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to read stats for the dag-pb node. Use 'files stat' instead.", - ShortDescription: ` -'ipfs object stat' is a plumbing command to print dag-pb node statistics. - is a base58 encoded multihash. - -DEPRECATED: modern replacements are 'files stat' and 'dag stat' -`, - LongDescription: ` -'ipfs object stat' is a plumbing command to print dag-pb node statistics. - is a base58 encoded multihash. It outputs to stdout: - - NumLinks int number of links in link table - BlockSize int size of the raw, encoded data - LinksSize int size of the links segment - DataSize int size of the data segment - CumulativeSize int cumulative size of object and its references - -DEPRECATED: Provided for legacy reasons. Modern replacements: - - For unixfs, 'ipfs files stat' can be used: - - $ ipfs files stat --with-local /ipfs/QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX - QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX - Size: 5 - CumulativeSize: 13 - ChildBlocks: 0 - Type: file - Local: 13 B of 13 B (100.00%) - - Reported sizes are based on metadata present in root block, and should not be - trusted. A slower, but more secure alternative is 'ipfs dag stat', which - will work for every DAG type. It comes with a benefit of calculating the - size by walking the DAG: - - $ ipfs dag stat /ipfs/QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX - Size: 13, NumBlocks: 1 -`, - }, - - Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.BoolOption(humanOptionName, "Print sizes in human readable format (e.g., 1K 234M 2G)"), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - 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 - } - - oldStat := &ipld.NodeStat{ - Hash: enc.Encode(ns.Cid), - NumLinks: ns.NumLinks, - BlockSize: ns.BlockSize, - LinksSize: ns.LinksSize, - DataSize: ns.DataSize, - CumulativeSize: ns.CumulativeSize, - } - - return cmds.EmitOnce(res, oldStat) - }, - Type: ipld.NodeStat{}, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ipld.NodeStat) error { - wtr := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0) - defer wtr.Flush() - fw := func(s string, n int) { - fmt.Fprintf(wtr, "%s:\t%d\n", s, n) - } - human, _ := req.Options[humanOptionName].(bool) - fw("NumLinks", out.NumLinks) - fw("BlockSize", out.BlockSize) - fw("LinksSize", out.LinksSize) - fw("DataSize", out.DataSize) - if human { - fmt.Fprintf(wtr, "%s:\t%s\n", "CumulativeSize", humanize.Bytes(uint64(out.CumulativeSize))) - } else { - fw("CumulativeSize", out.CumulativeSize) - } - - return nil - }), - }, -} - -// ObjectPutCmd object put command -var ObjectPutCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to store input as a DAG object. Use 'dag put' instead.", - ShortDescription: ` -'ipfs object put' is a plumbing command for storing dag-pb nodes. -It reads from stdin, and the output is a base58 encoded multihash. - -DEPRECATED and provided for legacy reasons. Use 'ipfs dag put' instead. -`, - }, - - Arguments: []cmds.Argument{ - cmds.FileArg("data", true, false, "Data to be stored as a dag-pb object.").EnableStdin(), - }, - Options: []cmds.Option{ - cmds.StringOption(inputencOptionName, "Encoding type of input data. One of: {\"protobuf\", \"json\"}.").WithDefault("json"), - cmds.StringOption(datafieldencOptionName, "Encoding type of the data field, either \"text\" or \"base64\".").WithDefault("text"), - cmds.BoolOption(pinOptionName, "Pin this object when adding."), - cmds.BoolOption(quietOptionName, "q", "Write minimal output."), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - file, err := cmdenv.GetFileArg(req.Files.Entries()) - if err != nil { - return err - } - - inputenc, _ := req.Options[inputencOptionName].(string) - if err != nil { - return err - } - - datafieldenc, _ := req.Options[datafieldencOptionName].(string) - if err != nil { - return err - } - - dopin, _ := req.Options[pinOptionName].(bool) - if err != nil { - return err - } - - p, err := api.Object().Put(req.Context, file, - options.Object.DataType(datafieldenc), - options.Object.InputEnc(inputenc), - options.Object.Pin(dopin)) - if err != nil { - return err - } - - return cmds.EmitOnce(res, &Object{Hash: enc.Encode(p.RootCid())}) - }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { - quiet, _ := req.Options[quietOptionName].(bool) - - o := out.Hash - if !quiet { - o = "added " + o - } - - fmt.Fprintln(w, o) - - return nil - }), + "put": RemovedObjectCmd, + "stat": RemovedObjectCmd, }, - Type: Object{}, } -// ObjectNewCmd object new command -var ObjectNewCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 +var RemovedObjectCmd = &cmds.Command{ + Status: cmds.Removed, Helptext: cmds.HelpText{ - Tagline: "Deprecated way to create a new dag-pb object from a template.", - ShortDescription: ` -'ipfs object new' is a plumbing command for creating new dag-pb nodes. -DEPRECATED and provided for legacy reasons. Use 'dag put' and 'files' instead. -`, - LongDescription: ` -'ipfs object new' is a plumbing command for creating new dag-pb nodes. -By default it creates and returns a new empty merkledag node, but -you may pass an optional template argument to create a preformatted -node. - -Available templates: - * unixfs-dir - -DEPRECATED and provided for legacy reasons. Use 'dag put' and 'files' instead. -`, - }, - Arguments: []cmds.Argument{ - cmds.StringArg("template", false, false, "Template to use. Optional."), + Tagline: "Removed, use 'ipfs dag' or 'ipfs files' instead.", }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - enc, err := cmdenv.GetLowLevelCidEncoder(req) - if err != nil { - return err - } - - template := "empty" - if len(req.Arguments) == 1 { - template = req.Arguments[0] - } - - nd, err := api.Object().New(req.Context, options.Object.Type(template)) - if err != nil && err != io.EOF { - return err - } - - return cmds.EmitOnce(res, &Object{Hash: enc.Encode(nd.Cid())}) + return errors.New("removed, use 'ipfs dag' or 'ipfs files' instead") }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { - fmt.Fprintln(w, out.Hash) - return nil - }), - }, - Type: Object{}, -} - -// converts the Node object into a real dag.ProtoNode -func deserializeNode(nd *Node, dataFieldEncoding string) (*dag.ProtoNode, error) { - dagnode := new(dag.ProtoNode) - switch dataFieldEncoding { - case "text": - dagnode.SetData([]byte(nd.Data)) - case "base64": - data, err := base64.StdEncoding.DecodeString(nd.Data) - if err != nil { - return nil, err - } - dagnode.SetData(data) - default: - return nil, ErrDataEncoding - } - - links := make([]*ipld.Link, len(nd.Links)) - for i, link := range nd.Links { - c, err := cid.Decode(link.Hash) - if err != nil { - return nil, err - } - links[i] = &ipld.Link{ - Name: link.Name, - Size: link.Size, - Cid: c, - } - } - if err := dagnode.SetLinks(links); err != nil { - return nil, err - } - - return dagnode, nil -} - -func encodeData(data []byte, encoding string) (string, error) { - switch encoding { - case "text": - return string(data), nil - case "base64": - return base64.StdEncoding.EncodeToString(data), nil - } - - return "", ErrDataEncoding } diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index 7c35151fbe2..5a82dfe0b69 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -37,128 +37,16 @@ For modern use cases, use MFS with 'files' commands: 'ipfs files --help'. }, Arguments: []cmds.Argument{}, Subcommands: map[string]*cmds.Command{ - "append-data": patchAppendDataCmd, + "append-data": RemovedObjectCmd, "add-link": patchAddLinkCmd, "rm-link": patchRmLinkCmd, - "set-data": patchSetDataCmd, + "set-data": RemovedObjectCmd, }, Options: []cmds.Option{ cmdutils.AllowBigBlockOption, }, } -var patchAppendDataCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to append data to the data segment of a DAG node.", - ShortDescription: ` -Append data to what already exists in the data segment in the given object. - -Example: - - $ echo "hello" | ipfs object patch $HASH append-data - -NOTE: This does not append data to a file - it modifies the actual raw -data within a dag-pb object. Blocks have a max size of 1MiB and objects larger than -the limit will not be respected by the network. - -DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' instead. -`, - }, - Arguments: []cmds.Argument{ - cmds.StringArg("root", true, false, "The hash of the node to modify."), - cmds.FileArg("data", true, false, "Data to append.").EnableStdin(), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - root, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - file, err := cmdenv.GetFileArg(req.Files.Entries()) - if err != nil { - return err - } - - p, err := api.Object().AppendData(req.Context, root, file) - if err != nil { - return err - } - - if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil { - return err - } - - return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()}) - }, - Type: &Object{}, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, obj *Object) error { - _, err := fmt.Fprintln(w, obj.Hash) - return err - }), - }, -} - -var patchSetDataCmd = &cmds.Command{ - Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 - Helptext: cmds.HelpText{ - Tagline: "Deprecated way to set the data field of dag-pb object.", - ShortDescription: ` -Set the data of an IPFS object from stdin or with the contents of a file. - -Example: - - $ echo "my data" | ipfs object patch $MYHASH set-data - -DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead. -`, - }, - Arguments: []cmds.Argument{ - cmds.StringArg("root", true, false, "The hash of the node to modify."), - cmds.FileArg("data", true, false, "The data to set the object to.").EnableStdin(), - }, - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env, req) - if err != nil { - return err - } - - root, err := cmdutils.PathOrCidPath(req.Arguments[0]) - if err != nil { - return err - } - - file, err := cmdenv.GetFileArg(req.Files.Entries()) - if err != nil { - return err - } - - p, err := api.Object().SetData(req.Context, root, file) - if err != nil { - return err - } - - if err := cmdutils.CheckCIDSize(req, p.RootCid(), api.Dag()); err != nil { - return err - } - - return cmds.EmitOnce(res, &Object{Hash: p.RootCid().String()}) - }, - Type: Object{}, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error { - fmt.Fprintln(w, out.Hash) - return nil - }), - }, -} - var patchRmLinkCmd = &cmds.Command{ Status: cmds.Deprecated, // https://github.com/ipfs/kubo/issues/7936 Helptext: cmds.HelpText{ diff --git a/core/coreapi/object.go b/core/coreapi/object.go index fca98bc5fa4..0f6c2747a57 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -1,22 +1,12 @@ package coreapi import ( - "bytes" "context" - "encoding/base64" - "encoding/json" - "encoding/xml" - "errors" - "fmt" - "io" 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" coreiface "github.com/ipfs/kubo/core/coreiface" caopts "github.com/ipfs/kubo/core/coreiface/options" "go.opentelemetry.io/otel/attribute" @@ -25,8 +15,6 @@ import ( "github.com/ipfs/kubo/tracing" ) -const inputLimit = 2 << 20 - type ObjectAPI CoreAPI type Link struct { @@ -39,180 +27,6 @@ type Node struct { Data string } -func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (ipld.Node, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "New") - defer span.End() - - options, err := caopts.ObjectNewOptions(opts...) - if err != nil { - return nil, err - } - - var n ipld.Node - switch options.Type { - case "empty": - n = new(dag.ProtoNode) - case "unixfs-dir": - n = ft.EmptyDirNode() - default: - return nil, fmt.Errorf("unknown node type: %s", options.Type) - } - - err = api.dag.Add(ctx, n) - if err != nil { - return nil, err - } - return n, nil -} - -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() - - options, err := caopts.ObjectPutOptions(opts...) - if err != nil { - return path.ImmutablePath{}, err - } - span.SetAttributes( - attribute.Bool("pin", options.Pin), - attribute.String("datatype", options.DataType), - attribute.String("inputenc", options.InputEnc), - ) - - data, err := io.ReadAll(io.LimitReader(src, inputLimit+10)) - if err != nil { - return path.ImmutablePath{}, err - } - - var dagnode *dag.ProtoNode - switch options.InputEnc { - case "json": - node := new(Node) - decoder := json.NewDecoder(bytes.NewReader(data)) - decoder.DisallowUnknownFields() - err = decoder.Decode(node) - if err != nil { - return path.ImmutablePath{}, err - } - - dagnode, err = deserializeNode(node, options.DataType) - if err != nil { - return path.ImmutablePath{}, err - } - - case "protobuf": - dagnode, err = dag.DecodeProtobuf(data) - - case "xml": - node := new(Node) - err = xml.Unmarshal(data, node) - if err != nil { - return path.ImmutablePath{}, err - } - - dagnode, err = deserializeNode(node, options.DataType) - if err != nil { - return path.ImmutablePath{}, err - } - - default: - return path.ImmutablePath{}, errors.New("unknown object encoding") - } - - if err != nil { - return path.ImmutablePath{}, err - } - - if options.Pin { - defer api.blockstore.PinLock(ctx).Unlock(ctx) - } - - err = api.dag.Add(ctx, dagnode) - if err != nil { - return path.ImmutablePath{}, err - } - - if options.Pin { - if err := api.pinning.PinWithMode(ctx, dagnode.Cid(), pin.Recursive, ""); err != nil { - return path.ImmutablePath{}, err - } - - err = api.pinning.Flush(ctx) - if err != nil { - return path.ImmutablePath{}, err - } - } - - return path.FromCid(dagnode.Cid()), nil -} - -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 path.Path) (io.Reader, error) { - ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Data", trace.WithAttributes(attribute.String("path", path.String()))) - defer span.End() - - nd, err := api.core().ResolveNode(ctx, path) - if err != nil { - return nil, err - } - - pbnd, ok := nd.(*dag.ProtoNode) - if !ok { - return nil, dag.ErrNotProtobuf - } - - return bytes.NewReader(pbnd.Data()), nil -} - -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() - - nd, err := api.core().ResolveNode(ctx, path) - if err != nil { - return nil, err - } - - links := nd.Links() - out := make([]*ipld.Link, len(links)) - for n, l := range links { - out[n] = (*ipld.Link)(l) - } - - return out, nil -} - -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() - - nd, err := api.core().ResolveNode(ctx, path) - if err != nil { - return nil, err - } - - stat, err := nd.Stat() - if err != nil { - return nil, err - } - - out := &coreiface.ObjectStat{ - Cid: nd.Cid(), - NumLinks: stat.NumLinks, - BlockSize: stat.BlockSize, - LinksSize: stat.LinksSize, - DataSize: stat.DataSize, - CumulativeSize: stat.CumulativeSize, - } - - return out, nil -} - 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()), @@ -294,49 +108,6 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base path.Path, link string) ( return path.FromCid(nnode.Cid()), nil } -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 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, p path.Path, r io.Reader, appendData bool) (path.ImmutablePath, error) { - nd, err := api.core().ResolveNode(ctx, p) - if err != nil { - return path.ImmutablePath{}, err - } - - pbnd, ok := nd.(*dag.ProtoNode) - if !ok { - return path.ImmutablePath{}, dag.ErrNotProtobuf - } - - data, err := io.ReadAll(r) - if err != nil { - return path.ImmutablePath{}, err - } - - if appendData { - data = append(pbnd.Data(), data...) - } - pbnd.SetData(data) - - err = api.dag.Add(ctx, pbnd) - if err != nil { - return path.ImmutablePath{}, err - } - - return path.FromCid(pbnd.Cid()), nil -} - 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()), @@ -381,37 +152,3 @@ func (api *ObjectAPI) Diff(ctx context.Context, before path.Path, after path.Pat func (api *ObjectAPI) core() coreiface.CoreAPI { return (*CoreAPI)(api) } - -func deserializeNode(nd *Node, dataFieldEncoding string) (*dag.ProtoNode, error) { - dagnode := new(dag.ProtoNode) - switch dataFieldEncoding { - case "text": - dagnode.SetData([]byte(nd.Data)) - case "base64": - data, err := base64.StdEncoding.DecodeString(nd.Data) - if err != nil { - return nil, err - } - dagnode.SetData(data) - default: - return nil, fmt.Errorf("unknown data field encoding") - } - - links := make([]*ipld.Link, len(nd.Links)) - for i, link := range nd.Links { - c, err := cid.Decode(link.Hash) - if err != nil { - return nil, err - } - links[i] = &ipld.Link{ - Name: link.Name, - Size: link.Size, - Cid: c, - } - } - if err := dagnode.SetLinks(links); err != nil { - return nil, err - } - - return dagnode, nil -} diff --git a/core/coreiface/object.go b/core/coreiface/object.go index fa378ac6c46..27bb8893583 100644 --- a/core/coreiface/object.go +++ b/core/coreiface/object.go @@ -2,36 +2,11 @@ package iface import ( "context" - "io" "github.com/ipfs/boxo/path" "github.com/ipfs/kubo/core/coreiface/options" - - "github.com/ipfs/go-cid" - ipld "github.com/ipfs/go-ipld-format" ) -// ObjectStat provides information about dag nodes -type ObjectStat struct { - // Cid is the CID of the node - Cid cid.Cid - - // NumLinks is number of links the node contains - NumLinks int - - // BlockSize is size of the raw serialized node - BlockSize int - - // LinksSize is size of the links block section - LinksSize int - - // DataSize is the size of data block section - DataSize int - - // CumulativeSize is size of the tree (BlockSize + link sizes) - CumulativeSize int -} - // ChangeType denotes type of change in ObjectChange type ChangeType int @@ -69,24 +44,6 @@ type ObjectChange struct { // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities // for manipulating MerkleDAG data structures. type ObjectAPI interface { - // New creates new, empty (by default) dag-node. - New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) - - // Put imports the data into merkledag - Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.ImmutablePath, error) - - // Get returns the node for the path - Get(context.Context, path.Path) (ipld.Node, error) - - // Data returns reader for data of the node - Data(context.Context, path.Path) (io.Reader, error) - - // Links returns lint or links the node contains - Links(context.Context, path.Path) ([]*ipld.Link, error) - - // Stat returns information about the node - Stat(context.Context, path.Path) (*ObjectStat, error) - // AddLink adds a link under the specified path. child path can point to a // subdirectory within the patent which must be present (can be overridden // with WithCreate option). @@ -95,12 +52,6 @@ type ObjectAPI interface { // RmLink removes a link from the node RmLink(ctx context.Context, base path.Path, link string) (path.ImmutablePath, error) - // AppendData appends data to the node - AppendData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error) - - // SetData sets the data contained in the node - SetData(context.Context, path.Path, io.Reader) (path.ImmutablePath, error) - // Diff returns a set of changes needed to transform the first object into the // second. Diff(context.Context, path.Path, path.Path) ([]ObjectChange, error) diff --git a/core/coreiface/options/object.go b/core/coreiface/options/object.go index b5625a1d61c..ab780ebd988 100644 --- a/core/coreiface/options/object.go +++ b/core/coreiface/options/object.go @@ -1,55 +1,13 @@ package options -type ObjectNewSettings struct { - Type string -} - -type ObjectPutSettings struct { - InputEnc string - DataType string - Pin bool -} - type ObjectAddLinkSettings struct { Create bool } type ( - ObjectNewOption func(*ObjectNewSettings) error - ObjectPutOption func(*ObjectPutSettings) error ObjectAddLinkOption func(*ObjectAddLinkSettings) error ) -func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { - options := &ObjectNewSettings{ - Type: "empty", - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - -func ObjectPutOptions(opts ...ObjectPutOption) (*ObjectPutSettings, error) { - options := &ObjectPutSettings{ - InputEnc: "json", - DataType: "text", - Pin: false, - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil -} - func ObjectAddLinkOptions(opts ...ObjectAddLinkOption) (*ObjectAddLinkSettings, error) { options := &ObjectAddLinkSettings{ Create: false, @@ -68,54 +26,6 @@ type objectOpts struct{} var Object objectOpts -// Type is an option for Object.New which allows to change the type of created -// dag node. -// -// Supported types: -// * 'empty' - Empty node -// * 'unixfs-dir' - Empty UnixFS directory -func (objectOpts) Type(t string) ObjectNewOption { - return func(settings *ObjectNewSettings) error { - settings.Type = t - return nil - } -} - -// InputEnc is an option for Object.Put which specifies the input encoding of the -// data. Default is "json". -// -// Supported encodings: -// * "protobuf" -// * "json" -func (objectOpts) InputEnc(e string) ObjectPutOption { - return func(settings *ObjectPutSettings) error { - settings.InputEnc = e - return nil - } -} - -// DataType is an option for Object.Put which specifies the encoding of data -// field when using Json or XML input encoding. -// -// Supported types: -// * "text" (default) -// * "base64" -func (objectOpts) DataType(t string) ObjectPutOption { - return func(settings *ObjectPutSettings) error { - settings.DataType = t - return nil - } -} - -// Pin is an option for Object.Put which specifies whether to pin the added -// objects, default is false -func (objectOpts) Pin(pin bool) ObjectPutOption { - return func(settings *ObjectPutSettings) error { - settings.Pin = pin - return nil - } -} - // Create is an option for Object.AddLink which specifies whether create required // directories for the child func (objectOpts) Create(create bool) ObjectAddLinkOption { diff --git a/core/coreiface/tests/object.go b/core/coreiface/tests/object.go index 9e0463ab690..239b022e14f 100644 --- a/core/coreiface/tests/object.go +++ b/core/coreiface/tests/object.go @@ -1,15 +1,15 @@ package tests import ( - "bytes" "context" - "encoding/hex" - "io" - "strings" "testing" + dag "github.com/ipfs/boxo/ipld/merkledag" + "github.com/ipfs/boxo/path" + ipld "github.com/ipfs/go-ipld-format" iface "github.com/ipfs/kubo/core/coreiface" opt "github.com/ipfs/kubo/core/coreiface/options" + "github.com/stretchr/testify/require" ) func (tp *TestSuite) TestObject(t *testing.T) { @@ -20,448 +20,125 @@ func (tp *TestSuite) TestObject(t *testing.T) { return nil }) - t.Run("TestNew", tp.TestNew) - t.Run("TestObjectPut", tp.TestObjectPut) - t.Run("TestObjectGet", tp.TestObjectGet) - t.Run("TestObjectData", tp.TestObjectData) - t.Run("TestObjectLinks", tp.TestObjectLinks) - t.Run("TestObjectStat", tp.TestObjectStat) t.Run("TestObjectAddLink", tp.TestObjectAddLink) t.Run("TestObjectAddLinkCreate", tp.TestObjectAddLinkCreate) t.Run("TestObjectRmLink", tp.TestObjectRmLink) - t.Run("TestObjectAddData", tp.TestObjectAddData) - t.Run("TestObjectSetData", tp.TestObjectSetData) t.Run("TestDiffTest", tp.TestDiffTest) } -func (tp *TestSuite) TestNew(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - emptyNode, err := api.Object().New(ctx) - if err != nil { - t.Fatal(err) - } - - dirNode, err := api.Object().New(ctx, opt.Object.Type("unixfs-dir")) - if err != nil { - t.Fatal(err) - } - - if emptyNode.String() != "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n" { - t.Errorf("Unexpected emptyNode path: %s", emptyNode.String()) - } - - if dirNode.String() != "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" { - t.Errorf("Unexpected dirNode path: %s", dirNode.String()) - } -} - -func (tp *TestSuite) TestObjectPut(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"YmFy"}`), opt.Object.DataType("base64")) // bar - if err != nil { - t.Fatal(err) - } - - pbBytes, err := hex.DecodeString("0a0362617a") - if err != nil { - t.Fatal(err) - } - - p3, err := api.Object().Put(ctx, bytes.NewReader(pbBytes), opt.Object.InputEnc("protobuf")) - if err != nil { - t.Fatal(err) - } - - if p1.String() != "/ipfs/QmQeGyS87nyijii7kFt1zbe4n2PsXTFimzsdxyE9qh9TST" { - t.Errorf("unexpected path: %s", p1.String()) - } - - if p2.String() != "/ipfs/QmNeYRbCibmaMMK6Du6ChfServcLqFvLJF76PzzF76SPrZ" { - t.Errorf("unexpected path: %s", p2.String()) - } - - if p3.String() != "/ipfs/QmZreR7M2t7bFXAdb1V5FtQhjk4t36GnrvueLJowJbQM9m" { - t.Errorf("unexpected path: %s", p3.String()) - } -} - -func (tp *TestSuite) TestObjectGet(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - nd, err := api.Object().Get(ctx, p1) - if err != nil { - t.Fatal(err) - } - - if string(nd.RawData()[len(nd.RawData())-3:]) != "foo" { - t.Fatal("got non-matching data") - } -} - -func (tp *TestSuite) TestObjectData(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - r, err := api.Object().Data(ctx, p1) - if err != nil { - t.Fatal(err) - } - - data, err := io.ReadAll(r) - if err != nil { - t.Fatal(err) - } - - if string(data) != "foo" { - t.Fatal("got non-matching data") - } -} - -func (tp *TestSuite) TestObjectLinks(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`"}]}`)) - if err != nil { - t.Fatal(err) - } - - links, err := api.Object().Links(ctx, p2) - if err != nil { - t.Fatal(err) - } - - if len(links) != 1 { - t.Errorf("unexpected number of links: %d", len(links)) - } - - if links[0].Cid.String() != p1.RootCid().String() { - t.Fatal("cids didn't batch") - } - - if links[0].Name != "bar" { - t.Fatal("unexpected link name") - } -} - -func (tp *TestSuite) TestObjectStat(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) - if err != nil { - t.Fatal(err) - } - - stat, err := api.Object().Stat(ctx, p2) - if err != nil { - t.Fatal(err) - } +func putDagPbNode(t *testing.T, ctx context.Context, api iface.CoreAPI, data string, links []*ipld.Link) path.ImmutablePath { + dagnode := new(dag.ProtoNode) - if stat.Cid.String() != p2.RootCid().String() { - t.Error("unexpected stat.Cid") + if data != "" { + dagnode.SetData([]byte(data)) } - if stat.NumLinks != 1 { - t.Errorf("unexpected stat.NumLinks") + if links != nil { + err := dagnode.SetLinks(links) + require.NoError(t, err) } - if stat.BlockSize != 51 { - t.Error("unexpected stat.BlockSize") - } - - if stat.LinksSize != 47 { - t.Errorf("unexpected stat.LinksSize: %d", stat.LinksSize) - } + err := api.Dag().Add(ctx, dagnode) + require.NoError(t, err) - if stat.DataSize != 4 { - t.Error("unexpected stat.DataSize") - } - - if stat.CumulativeSize != 54 { - t.Error("unexpected stat.DataSize") - } + return path.FromCid(dagnode.Cid()) } func (tp *TestSuite) TestObjectAddLink(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + + p1 := putDagPbNode(t, ctx, api, "foo", nil) + p2 := putDagPbNode(t, ctx, api, "bazz", []*ipld.Link{ + { + Name: "bar", + Cid: p1.RootCid(), + Size: 3, + }, + }) p3, err := api.Object().AddLink(ctx, p2, "abc", p2) - if err != nil { - t.Fatal(err) - } - - links, err := api.Object().Links(ctx, p3) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - if len(links) != 2 { - t.Errorf("unexpected number of links: %d", len(links)) - } + nd, err := api.Dag().Get(ctx, p3.RootCid()) + require.NoError(t, err) - if links[0].Name != "abc" { - t.Errorf("unexpected link 0 name: %s", links[0].Name) - } - - if links[1].Name != "bar" { - t.Errorf("unexpected link 1 name: %s", links[1].Name) - } + links := nd.Links() + require.Len(t, links, 2) + require.Equal(t, "abc", links[0].Name) + require.Equal(t, "bar", links[1].Name) } func (tp *TestSuite) TestObjectAddLinkCreate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + + p1 := putDagPbNode(t, ctx, api, "foo", nil) + p2 := putDagPbNode(t, ctx, api, "bazz", []*ipld.Link{ + { + Name: "bar", + Cid: p1.RootCid(), + Size: 3, + }, + }) _, err = api.Object().AddLink(ctx, p2, "abc/d", p2) - if err == nil { - t.Fatal("expected an error") - } - if !strings.Contains(err.Error(), "no link by that name") { - t.Fatalf("unexpected error: %s", err.Error()) - } + require.ErrorContains(t, err, "no link by that name") p3, err := api.Object().AddLink(ctx, p2, "abc/d", p2, opt.Object.Create(true)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - links, err := api.Object().Links(ctx, p3) - if err != nil { - t.Fatal(err) - } - - if len(links) != 2 { - t.Errorf("unexpected number of links: %d", len(links)) - } - - if links[0].Name != "abc" { - t.Errorf("unexpected link 0 name: %s", links[0].Name) - } + nd, err := api.Dag().Get(ctx, p3.RootCid()) + require.NoError(t, err) - if links[1].Name != "bar" { - t.Errorf("unexpected link 1 name: %s", links[1].Name) - } + links := nd.Links() + require.Len(t, links, 2) + require.Equal(t, "abc", links[0].Name) + require.Equal(t, "bar", links[1].Name) } func (tp *TestSuite) TestObjectRmLink(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bazz", "Links":[{"Name":"bar", "Hash":"`+p1.RootCid().String()+`", "Size":3}]}`)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + + p1 := putDagPbNode(t, ctx, api, "foo", nil) + p2 := putDagPbNode(t, ctx, api, "bazz", []*ipld.Link{ + { + Name: "bar", + Cid: p1.RootCid(), + Size: 3, + }, + }) p3, err := api.Object().RmLink(ctx, p2, "bar") - if err != nil { - t.Fatal(err) - } - - links, err := api.Object().Links(ctx, p3) - if err != nil { - t.Fatal(err) - } - - if len(links) != 0 { - t.Errorf("unexpected number of links: %d", len(links)) - } -} - -func (tp *TestSuite) TestObjectAddData(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } - - p2, err := api.Object().AppendData(ctx, p1, strings.NewReader("bar")) - if err != nil { - t.Fatal(err) - } - - r, err := api.Object().Data(ctx, p2) - if err != nil { - t.Fatal(err) - } - - data, err := io.ReadAll(r) - if err != nil { - t.Fatal(err) - } - - if string(data) != "foobar" { - t.Error("unexpected data") - } -} - -func (tp *TestSuite) TestObjectSetData(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - p2, err := api.Object().SetData(ctx, p1, strings.NewReader("bar")) - if err != nil { - t.Fatal(err) - } - - r, err := api.Object().Data(ctx, p2) - if err != nil { - t.Fatal(err) - } + nd, err := api.Dag().Get(ctx, p3.RootCid()) + require.NoError(t, err) - data, err := io.ReadAll(r) - if err != nil { - t.Fatal(err) - } - - if string(data) != "bar" { - t.Error("unexpected data") - } + links := nd.Links() + require.Len(t, links, 0) } func (tp *TestSuite) TestDiffTest(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() api, err := tp.makeAPI(t, ctx) - if err != nil { - t.Fatal(err) - } - - p1, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"foo"}`)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - p2, err := api.Object().Put(ctx, strings.NewReader(`{"Data":"bar"}`)) - if err != nil { - t.Fatal(err) - } + p1 := putDagPbNode(t, ctx, api, "foo", nil) + p2 := putDagPbNode(t, ctx, api, "bar", nil) changes, err := api.Object().Diff(ctx, p1, p2) - if err != nil { - t.Fatal(err) - } - - if len(changes) != 1 { - t.Fatal("unexpected changes len") - } - - if changes[0].Type != iface.DiffMod { - t.Fatal("unexpected change type") - } - - if changes[0].Before.String() != p1.String() { - t.Fatal("unexpected before path") - } - - if changes[0].After.String() != p2.String() { - t.Fatal("unexpected before path") - } + require.NoError(t, err) + require.Len(t, changes, 1) + require.Equal(t, iface.DiffMod, changes[0].Type) + require.Equal(t, p1.String(), changes[0].Before.String()) + require.Equal(t, p2.String(), changes[0].After.String()) } diff --git a/core/coreiface/tests/unixfs.go b/core/coreiface/tests/unixfs.go index 538f4d8ed7c..0dca0218ba7 100644 --- a/core/coreiface/tests/unixfs.go +++ b/core/coreiface/tests/unixfs.go @@ -630,16 +630,11 @@ func (tp *TestSuite) TestGetDir(t *testing.T) { } p := path.FromCid(edir.Cid()) - emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) - if err != nil { - t.Fatal(err) - } - - if p.String() != path.FromCid(emptyDir.Cid()).String() { - t.Fatalf("expected path %s, got: %s", emptyDir.Cid(), p.String()) + if p.String() != path.FromCid(edir.Cid()).String() { + t.Fatalf("expected path %s, got: %s", edir.Cid(), p.String()) } - r, err := api.Unixfs().Get(ctx, path.FromCid(emptyDir.Cid())) + r, err := api.Unixfs().Get(ctx, path.FromCid(edir.Cid())) if err != nil { t.Fatal(err) } @@ -779,17 +774,12 @@ func (tp *TestSuite) TestLsEmptyDir(t *testing.T) { t.Fatal(err) } - _, err = api.Unixfs().Add(ctx, files.NewSliceDirectory([]files.DirEntry{})) - if err != nil { - t.Fatal(err) - } - - emptyDir, err := api.Object().New(ctx, options.Object.Type("unixfs-dir")) + p, err := api.Unixfs().Add(ctx, files.NewSliceDirectory([]files.DirEntry{})) if err != nil { t.Fatal(err) } - links, err := api.Unixfs().Ls(ctx, path.FromCid(emptyDir.Cid())) + links, err := api.Unixfs().Ls(ctx, p) if err != nil { t.Fatal(err) } diff --git a/docs/changelogs/v0.28.md b/docs/changelogs/v0.28.md index ffc81673705..0d399c6ec13 100644 --- a/docs/changelogs/v0.28.md +++ b/docs/changelogs/v0.28.md @@ -8,6 +8,7 @@ - [๐Ÿ”ฆ Highlights](#-highlights) - [RPC client: removed deprecated DHT API](#rpc-client-removed-deprecated-dht-api) - [Gateway: `/api/v0` is removed](#gateway-apiv0-is-removed) + - [Removed deprecated Object API commands](#removed-deprecated-object-api-commands) - [๐Ÿ“ Changelog](#-changelog) - [๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Contributors](#-contributors) @@ -23,6 +24,10 @@ The legacy subset of the Kubo RPC that was available via the Gateway port and wa If you have a legacy software that relies on this behavior, and want to expose parts of `/api/v0` next to `/ipfs`, use reverse-proxy in front of Kubo to mount both Gateway and RPC on the same port. NOTE: exposing RPC to the internet comes with security risk: make sure to specify access control via [API.Authorizations](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations). +#### Removed deprecated Object API commands + +The Object API commands deprecated back in [2021](https://github.com/ipfs/kubo/issues/7936) have been removed, except for `object diff`, `object patch add-link` and `object patch rm-link`, whose alternatives have not yet been built (see issues [4801](https://github.com/ipfs/kubo/issues/4801) and [4782](https://github.com/ipfs/kubo/issues/4782)). + ### ๐Ÿ“ Changelog ### ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Contributors diff --git a/docs/implement-api-bindings.md b/docs/implement-api-bindings.md index 996a6b8ac80..3587ac21f47 100644 --- a/docs/implement-api-bindings.md +++ b/docs/implement-api-bindings.md @@ -39,10 +39,9 @@ function calls. For example: #### CLI API Transport In the commandline, IPFS uses a traditional flag and arg-based mapping, where: -- the first arguments selects the command, as in git - e.g. `ipfs object get` +- the first arguments selects the command, as in git - e.g. `ipfs dag get` - the flags specify options - e.g. `--enc=protobuf -q` -- the rest are positional arguments - e.g. - `ipfs object patch add-linkfoo ` +- the rest are positional arguments - e.g. `ipfs key rename ` - files are specified by filename, or through stdin (NOTE: When kubo runs the daemon, the CLI API is actually converted to HTTP diff --git a/test/cli/basic_commands_test.go b/test/cli/basic_commands_test.go index 69b0cc63bc8..603a03d9dea 100644 --- a/test/cli/basic_commands_test.go +++ b/test/cli/basic_commands_test.go @@ -147,7 +147,6 @@ func TestCommandDocsWidth(t *testing.T) { "ipfs swarm addrs listen": true, "ipfs dag resolve": true, "ipfs dag get": true, - "ipfs object stat": true, "ipfs pin remote add": true, "ipfs config show": true, "ipfs config edit": true, @@ -164,8 +163,6 @@ func TestCommandDocsWidth(t *testing.T) { "ipfs object diff": true, "ipfs object patch add-link": true, "ipfs name": true, - "ipfs object patch append-data": true, - "ipfs object patch set-data": true, "ipfs diag profile": true, "ipfs diag cmds": true, "ipfs swarm addrs local": true, diff --git a/test/sharness/t0051-object-data/testPut.pb b/test/sharness/t0050-block-data/testPut.pb similarity index 100% rename from test/sharness/t0051-object-data/testPut.pb rename to test/sharness/t0050-block-data/testPut.pb diff --git a/test/sharness/t0050-block.sh b/test/sharness/t0050-block.sh index 9ecf2087596..05502adaf5e 100755 --- a/test/sharness/t0050-block.sh +++ b/test/sharness/t0050-block.sh @@ -42,12 +42,12 @@ test_expect_success "'ipfs block put' output looks good" ' ' test_expect_success "can set cid codec on block put" ' - CODEC_HASH=$(ipfs block put --cid-codec=dag-pb ../t0051-object-data/testPut.pb) + CODEC_HASH=$(ipfs block put --cid-codec=dag-pb ../t0050-block-data/testPut.pb) ' test_expect_success "block get output looks right" ' ipfs block get $CODEC_HASH > pb_block_out && - test_cmp pb_block_out ../t0051-object-data/testPut.pb + test_cmp pb_block_out ../t0050-block-data/testPut.pb ' # @@ -210,33 +210,33 @@ test_expect_success "multi-block 'ipfs block rm -q' produces no output" ' # --format used 'protobuf' for 'dag-pb' which was invalid, but we keep # for backward-compatibility test_expect_success "can set deprecated --format=protobuf on block put" ' - HASH=$(ipfs block put --format=protobuf ../t0051-object-data/testPut.pb) + HASH=$(ipfs block put --format=protobuf ../t0050-block-data/testPut.pb) ' test_expect_success "created an object correctly!" ' - ipfs object get $HASH > obj_out && - echo "{\"Links\":[],\"Data\":\"test json for sharness test\"}" > obj_exp && + ipfs dag get $HASH > obj_out && + echo -n "{\"Data\":{\"/\":{\"bytes\":\"dGVzdCBqc29uIGZvciBzaGFybmVzcyB0ZXN0\"}},\"Links\":[]}" > obj_exp && test_cmp obj_out obj_exp ' test_expect_success "block get output looks right" ' ipfs block get $HASH > pb_block_out && - test_cmp pb_block_out ../t0051-object-data/testPut.pb + test_cmp pb_block_out ../t0050-block-data/testPut.pb ' test_expect_success "can set --cid-codec=dag-pb on block put" ' - HASH=$(ipfs block put --cid-codec=dag-pb ../t0051-object-data/testPut.pb) + HASH=$(ipfs block put --cid-codec=dag-pb ../t0050-block-data/testPut.pb) ' test_expect_success "created an object correctly!" ' - ipfs object get $HASH > obj_out && - echo "{\"Links\":[],\"Data\":\"test json for sharness test\"}" > obj_exp && + ipfs dag get $HASH > obj_out && + echo -n "{\"Data\":{\"/\":{\"bytes\":\"dGVzdCBqc29uIGZvciBzaGFybmVzcyB0ZXN0\"}},\"Links\":[]}" > obj_exp && test_cmp obj_out obj_exp ' test_expect_success "block get output looks right" ' ipfs block get $HASH > pb_block_out && - test_cmp pb_block_out ../t0051-object-data/testPut.pb + test_cmp pb_block_out ../t0050-block-data/testPut.pb ' test_expect_success "can set multihash type and length on block put with --format=raw (deprecated)" ' @@ -248,7 +248,7 @@ test_expect_success "output looks good" ' ' test_expect_success "can't use both legacy format and custom cid-codec at the same time" ' - test_expect_code 1 ipfs block put --format=dag-cbor --cid-codec=dag-json < ../t0051-object-data/testPut.pb 2> output && + test_expect_code 1 ipfs block put --format=dag-cbor --cid-codec=dag-json < ../t0050-block-data/testPut.pb 2> output && test_should_contain "unable to use \"format\" (deprecated) and a custom \"cid-codec\" at the same time" output ' diff --git a/test/sharness/t0051-object-data/UTF-8-test.txt b/test/sharness/t0051-object-data/UTF-8-test.txt deleted file mode 100644 index 56213a84a9843f0f8fa6f10a1a67dcdb9de982c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20350 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 is not a valid dag object fail diff --git a/test/sharness/t0051-object-data/expected_getOut b/test/sharness/t0051-object-data/expected_getOut deleted file mode 100644 index 27b23f9d35e..00000000000 --- a/test/sharness/t0051-object-data/expected_getOut +++ /dev/null @@ -1 +0,0 @@ -{"Links":[],"Data":"\b\u0002\u0012\nHello Mars\u0018\n"} diff --git a/test/sharness/t0051-object-data/mixed.json b/test/sharness/t0051-object-data/mixed.json deleted file mode 100644 index b8de2b8d886..00000000000 --- a/test/sharness/t0051-object-data/mixed.json +++ /dev/null @@ -1,5 +0,0 @@ -{"Data": "another", - "Links": [ - {"Name": "some link", "Hash": "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V", "Size": 8}, - {"Name": "inlined", "Hash": "z4CrgyEyhm4tAw1pgzQtNNuP7", "Size": 14} -]} diff --git a/test/sharness/t0051-object-data/testPut.json b/test/sharness/t0051-object-data/testPut.json deleted file mode 100644 index c97f4ec0bf9..00000000000 --- a/test/sharness/t0051-object-data/testPut.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Data": "test json for sharness test" -} diff --git a/test/sharness/t0051-object-data/testPut.xml b/test/sharness/t0051-object-data/testPut.xml deleted file mode 100644 index 5cc290b2709..00000000000 --- a/test/sharness/t0051-object-data/testPut.xml +++ /dev/null @@ -1 +0,0 @@ -Test xml for sharness test diff --git a/test/sharness/t0051-object.sh b/test/sharness/t0051-object.sh index 316c220abd5..4bac6137488 100755 --- a/test/sharness/t0051-object.sh +++ b/test/sharness/t0051-object.sh @@ -27,204 +27,21 @@ test_patch_create_path() { } test_object_cmd() { - - test_expect_success "'ipfs add testData' succeeds" ' - printf "Hello Mars" >expected_in && - ipfs add expected_in >actual_Addout - ' - - test_expect_success "'ipfs add testData' output looks good" ' - HASH="QmWkHFpYBZ9mpPRreRbMhhYWXfUhBAue3JkbbpFqwowSRb" && - echo "added $HASH expected_in" >expected_Addout && - test_cmp expected_Addout actual_Addout - ' - - test_expect_success "'ipfs object get' succeeds" ' - ipfs object get $HASH >actual_getOut - ' - - test_expect_success "'ipfs object get' output looks good" ' - test_cmp ../t0051-object-data/expected_getOut actual_getOut - ' - - test_expect_success "'ipfs object get' can specify data encoding as base64" ' - ipfs object get --data-encoding base64 $HASH > obj_out && - echo "{\"Links\":[],\"Data\":\"CAISCkhlbGxvIE1hcnMYCg==\"}" > obj_exp && - test_cmp obj_out obj_exp - ' - - test_expect_success "'ipfs object get' can specify data encoding as text" ' - echo "{\"Links\":[],\"Data\":\"Hello Mars\"}" | ipfs object put && - ipfs object get --data-encoding text QmS3hVY6eYrMQ6L22agwrx3YHBEsc3LJxVXCtyQHqRBukH > obj_out && - echo "{\"Links\":[],\"Data\":\"Hello Mars\"}" > obj_exp && - test_cmp obj_out obj_exp - ' - - test_expect_failure "'ipfs object get' requires known data encoding" ' - ipfs object get --data-encoding nonsensical-encoding $HASH - ' - - test_expect_success "'ipfs object stat' succeeds" ' - ipfs object stat $HASH >actual_stat - ' - - test_expect_success "'ipfs object get' output looks good" ' - echo "NumLinks: 0" > expected_stat && - echo "BlockSize: 18" >> expected_stat && - echo "LinksSize: 2" >> expected_stat && - echo "DataSize: 16" >> expected_stat && - echo "CumulativeSize: 18" >> expected_stat && - test_cmp expected_stat actual_stat - ' - - test_expect_success "'ipfs object put file.json' succeeds" ' - ipfs object put ../t0051-object-data/testPut.json > actual_putOut - ' - - test_expect_success "'ipfs object put file.json' output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put --quiet file.json' succeeds" ' - ipfs object put --quiet ../t0051-object-data/testPut.json > actual_putOut - ' - - test_expect_success "'ipfs object put --quiet file.json' output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "$HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put file.xml' succeeds" ' - ipfs object put ../t0051-object-data/testPut.xml --inputenc=xml > actual_putOut - ' - - test_expect_success "'ipfs object put file.xml' output looks good" ' - HASH="QmQzNKUHy4HyEUGkqKe3q3t796ffPLQXYCkHCcXUNT5JNK" && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put' from stdin succeeds" ' - cat ../t0051-object-data/testPut.xml | ipfs object put --inputenc=xml > actual_putStdinOut - ' - - test_expect_failure "'ipfs object put broken.xml' should fail" ' - test_expect_code 1 ipfs object put ../t0051-object-data/brokenPut.xml --inputenc=xml 2>actual_putBrokenErr >actual_putBroken - ' - - test_expect_failure "'ipfs object put broken.hxml' output looks good" ' - touch expected_putBroken && - printf "Error: no data or links in this node\n" > expected_putBrokenErr && - test_cmp expected_putBroken actual_putBroken && - test_cmp expected_putBrokenErr actual_putBrokenErr - ' - test_expect_success "'ipfs object get --enc=xml' succeeds" ' - ipfs object get --enc=xml $HASH >utf8_xml - ' - - test_expect_success "'ipfs object put --inputenc=xml' succeeds" ' - ipfs object put --inputenc=xml actual - ' - - test_expect_failure "'ipfs object put --inputenc=xml' output looks good" ' - echo "added $HASH\n" >expected && - test_cmp expected actual - ' - - test_expect_success "'ipfs object put file.pb' succeeds" ' - ipfs object put --inputenc=protobuf ../t0051-object-data/testPut.pb > actual_putOut - ' - - test_expect_success "'ipfs object put file.pb' output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put' from stdin succeeds" ' - cat ../t0051-object-data/testPut.json | ipfs object put > actual_putStdinOut - ' - - test_expect_success "'ipfs object put' from stdin output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putStdinOut && - test_cmp expected_putStdinOut actual_putStdinOut - ' - - test_expect_success "'ipfs object put' from stdin (pb) succeeds" ' - cat ../t0051-object-data/testPut.pb | ipfs object put --inputenc=protobuf > actual_putPbStdinOut - ' - - test_expect_success "'ipfs object put' from stdin (pb) output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putStdinOut && - test_cmp expected_putStdinOut actual_putPbStdinOut - ' - - test_expect_success "'ipfs object put broken.json' should fail" ' - test_expect_code 1 ipfs object put ../t0051-object-data/brokenPut.json 2>actual_putBrokenErr >actual_putBroken - ' - - test_expect_success "'ipfs object put broken.hjson' output looks good" ' - touch expected_putBroken && - printf "Error: json: unknown field \"this\"\n" > expected_putBrokenErr && - test_cmp expected_putBroken actual_putBroken && - test_cmp expected_putBrokenErr actual_putBrokenErr - ' - - test_expect_success "setup: add UTF-8 test file" ' - HASH="QmNY5sQeH9ttVCg24sizH71dNbcZTpGd7Yb3YwsKZ4jiFP" && - ipfs add ../t0051-object-data/UTF-8-test.txt >actual && - echo "added $HASH UTF-8-test.txt" >expected && - test_cmp expected actual - ' - - test_expect_success "'ipfs object get --enc=json' succeeds" ' - ipfs object get --enc=json $HASH >utf8_json - ' - - test_expect_success "'ipfs object put --inputenc=json' succeeds" ' - ipfs object put --inputenc=json actual - ' - - test_expect_failure "'ipfs object put --inputenc=json' output looks good" ' - echo "added $HASH" >expected && - test_cmp expected actual - ' - - test_expect_success "'ipfs object put --pin' succeeds" ' - HASH="QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V" && - echo "added $HASH" >expected && - echo "{ \"Data\": \"abc\" }" | ipfs object put --pin >actual - ' - - test_expect_success "'ipfs object put --pin' output looks good" ' - echo "added $HASH" >expected && - test_cmp expected actual - ' - - test_expect_success "after gc, objects still accessible" ' - ipfs repo gc > /dev/null && - ipfs refs -r --timeout=2s $HASH > /dev/null - ' + EMPTY_DIR=$(echo '{"Links":[]}' | ipfs dag put --store-codec dag-pb) + EMPTY_UNIXFS_DIR=$(echo '{"Data":{"/":{"bytes":"CAE"}},"Links":[]}' | ipfs dag put --store-codec dag-pb) test_expect_success "'ipfs object patch' should work (no unixfs-dir)" ' - EMPTY_DIR=$(ipfs object new) && OUTPUT=$(ipfs object patch $EMPTY_DIR add-link foo $EMPTY_DIR) && - ipfs object stat $OUTPUT + ipfs dag stat $OUTPUT ' test_expect_success "'ipfs object patch' should work" ' - EMPTY_DIR=$(ipfs object new unixfs-dir) && - OUTPUT=$(ipfs object patch $EMPTY_DIR add-link foo $EMPTY_DIR) && - ipfs object stat $OUTPUT + OUTPUT=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link foo $EMPTY_UNIXFS_DIR) && + ipfs dag stat $OUTPUT ' test_expect_success "'ipfs object patch' check output block size" ' - DIR=$(ipfs object new unixfs-dir) + DIR=$EMPTY_UNIXFS_DIR for i in {1..13} do DIR=$(ipfs object patch "$DIR" add-link "$DIR.jpg" "$DIR") @@ -241,32 +58,20 @@ test_object_cmd() { test_expect_code 0 ipfs object patch --allow-big-block=true "$DIR" add-link "$DIR.jpg" "$DIR" ' - test_expect_success "'ipfs object new foo' shouldn't crash" ' - test_expect_code 1 ipfs object new foo - ' - - test_expect_success "'ipfs object links' gives the correct results" ' - echo "$EMPTY_DIR" 4 foo > expected && - ipfs object links "$OUTPUT" > actual && - test_cmp expected actual - ' - test_expect_success "'ipfs object patch add-link' should work with paths" ' - EMPTY_DIR=$(ipfs object new unixfs-dir) && - N1=$(ipfs object patch $EMPTY_DIR add-link baz $EMPTY_DIR) && - N2=$(ipfs object patch $EMPTY_DIR add-link bar $N1) && - N3=$(ipfs object patch $EMPTY_DIR add-link foo /ipfs/$N2/bar) && - ipfs object stat /ipfs/$N3 > /dev/null && - ipfs object stat $N3/foo > /dev/null && - ipfs object stat /ipfs/$N3/foo/baz > /dev/null + N1=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link baz $EMPTY_UNIXFS_DIR) && + N2=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link bar $N1) && + N3=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link foo /ipfs/$N2/bar) && + ipfs dag stat /ipfs/$N3 > /dev/null && + ipfs dag stat $N3/foo > /dev/null && + ipfs dag stat /ipfs/$N3/foo/baz > /dev/null ' test_expect_success "'ipfs object patch add-link' allow linking IPLD objects" ' - EMPTY_DIR=$(ipfs object new unixfs-dir) && OBJ=$(echo "123" | ipfs dag put) && - N1=$(ipfs object patch $EMPTY_DIR add-link foo $OBJ) && + N1=$(ipfs object patch $EMPTY_UNIXFS_DIR add-link foo $OBJ) && - ipfs object stat /ipfs/$N1 > /dev/null && + ipfs dag stat /ipfs/$N1 > /dev/null && ipfs resolve /ipfs/$N1/foo > actual && echo /ipfs/$OBJ > expected && @@ -274,7 +79,7 @@ test_object_cmd() { ' test_expect_success "object patch creation looks right" ' - echo "QmPc73aWK9dgFBXe86P4PvQizHo9e5Qt7n7DAMXWuigFuG" > hash_exp && + echo "bafybeiakusqwohnt7bs75kx6jhmt4oi47l634bmudxfv4qxhpco6xuvgna" > hash_exp && echo $N3 > hash_actual && test_cmp hash_exp hash_actual ' @@ -282,7 +87,7 @@ test_object_cmd() { test_expect_success "multilayer ipfs patch works" ' echo "hello world" > hwfile && FILE=$(ipfs add -q hwfile) && - EMPTY=$(ipfs object new unixfs-dir) && + EMPTY=$EMPTY_UNIXFS_DIR && ONE=$(ipfs object patch $EMPTY add-link b $EMPTY) && TWO=$(ipfs object patch $EMPTY add-link a $ONE) && ipfs object patch $TWO add-link a/b/c $FILE > multi_patch @@ -293,49 +98,12 @@ test_object_cmd() { test_cmp hwfile hwfile_out ' - test_expect_success "ipfs object stat path succeeds" ' - ipfs object stat $(cat multi_patch)/a > obj_stat_out - ' - - test_expect_success "ipfs object stat output looks good" ' - echo "NumLinks: 1" > obj_stat_exp && - echo "BlockSize: 47" >> obj_stat_exp && - echo "LinksSize: 45" >> obj_stat_exp && - echo "DataSize: 2" >> obj_stat_exp && - echo "CumulativeSize: 114" >> obj_stat_exp && - - test_cmp obj_stat_exp obj_stat_out - ' - - test_expect_success "'ipfs object stat --human' succeeds" ' - ipfs object stat $(cat multi_patch)/a --human > obj_stat_human_out - ' - - test_expect_success "ipfs object stat --human output looks good" ' - echo "NumLinks: 1" > obj_stat_human_exp && - echo "BlockSize: 47" >> obj_stat_human_exp && - echo "LinksSize: 45" >> obj_stat_human_exp && - echo "DataSize: 2" >> obj_stat_human_exp && - echo "CumulativeSize: 114 B" >> obj_stat_human_exp && - - test_cmp obj_stat_human_exp obj_stat_human_out - ' - - test_expect_success "should have created dir within a dir" ' - ipfs ls $OUTPUT > patched_output - ' - - test_expect_success "output looks good" ' - echo "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn - foo/" > patched_exp && - test_cmp patched_exp patched_output - ' - test_expect_success "can remove the directory" ' ipfs object patch $OUTPUT rm-link foo > rmlink_output ' test_expect_success "output should be empty" ' - echo QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn > rmlink_exp && + echo bafybeiczsscdsbs7ffqz55asqdf3smv6klcw3gofszvwlyarci47bgf354 > rmlink_exp && test_cmp rmlink_exp rmlink_output ' @@ -344,7 +112,7 @@ test_object_cmd() { ' test_expect_success "output looks good" ' - echo "QmZD3r9cZjzU8huNY2JS9TC6n8daDfT8TmE8zBSqG31Wvq" > multi_link_rm_exp && + echo "bafybeicourxysmtbe5hacxqico4d5hyvh7gqkrwlmqa4ew7zufn3pj3juu" > multi_link_rm_exp && test_cmp multi_link_rm_exp multi_link_rm_out ' @@ -355,7 +123,7 @@ test_object_cmd() { test_patch_create_path $EMPTY a/b/b/b/b $FILE test_expect_success "can create blank object" ' - BLANK=$(ipfs object new) + BLANK=$EMPTY_DIR ' test_patch_create_path $BLANK a $FILE @@ -363,98 +131,6 @@ test_object_cmd() { test_expect_success "create bad path fails" ' test_must_fail ipfs object patch $EMPTY add-link --create / $FILE ' - - test_expect_success "patch set-data works" ' - EMPTY=$(ipfs object new) && - HASH=$(printf "foo" | ipfs object patch $EMPTY set-data) - ' - - test_expect_success "output looks good" ' - echo "{\"Links\":[],\"Data\":\"foo\"}" > exp_data_set && - ipfs object get $HASH > actual_data_set && - test_cmp exp_data_set actual_data_set - ' - - test_expect_success "patch append-data works" ' - HASH=$(printf "bar" | ipfs object patch $HASH append-data) - ' - - test_expect_success "output looks good" ' - echo "{\"Links\":[],\"Data\":\"foobar\"}" > exp_data_append && - ipfs object get $HASH > actual_data_append && - test_cmp exp_data_append actual_data_append - ' - - # - # CidBase Tests - # - - test_expect_success "'ipfs object put file.json --cid-base=base32' succeeds" ' - ipfs object put --cid-base=base32 ../t0051-object-data/testPut.json > actual_putOut - ' - - test_expect_success "'ipfs object put file.json --cid-base=base32' output looks good" ' - HASH="QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD" && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'ipfs object put file.json --cid-base=base32 --upgrade-cidv0-in-output=true' succeeds" ' - ipfs object put --cid-base=base32 --upgrade-cidv0-in-output=true ../t0051-object-data/testPut.json > actual_putOut - ' - - test_expect_success "'ipfs object put file.json --cid-base=base32 --upgrade-cidv0-in-output=true' output looks good" ' - HASH=$(ipfs cid base32 "QmUTSAdDi2xsNkDtLqjFgQDMEn5di3Ab9eqbrt4gaiNbUD") && - printf "added $HASH\n" > expected_putOut && - test_cmp expected_putOut actual_putOut - ' - - test_expect_success "'insert json dag with both CidV0 and CidV1 links'" ' - MIXED=$(ipfs object put ../t0051-object-data/mixed.json -q) && - echo $MIXED - ' - - test_expect_success "ipfs object get then put creates identical object with --cid-base=base32" ' - ipfs object get --cid-base=base32 $MIXED > mixedv2.json && - MIXED2=$(ipfs object put -q mixedv2.json) && - echo "$MIXED =? $MIXED2" && - test "$MIXED" = "$MIXED2" - ' - - HASHv0=QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V - HASHv1=bafkqadsimvwgy3zajb2w2yloeefau - - test_expect_success "ipfs object get with --cid-base=base32 uses base32 for CidV1 link only" ' - ipfs object get --cid-base=base32 $MIXED > mixed.actual && - grep -q $HASHv0 mixed.actual && - grep -q $(ipfs cid base32 $HASHv1) mixed.actual - ' - - test_expect_success "ipfs object links --cid-base=base32 --upgrade-cidv0-in-output=true converts both links" ' - ipfs object links --cid-base=base32 --upgrade-cidv0-in-output=true $MIXED | awk "{print \$1}" | sort > links.actual && - echo $(ipfs cid base32 $HASHv1) > links.expected - echo $(ipfs cid base32 $HASHv0) >> links.expected - test_cmp links.actual links.expected - ' -} - -test_object_content_type() { - - test_expect_success "'ipfs object get --encoding=protobuf' returns the correct content type" ' - curl -X POST -sI "http://$API_ADDR/api/v0/object/get?arg=$HASH&encoding=protobuf" | grep -q "^Content-Type: application/protobuf" - ' - - test_expect_success "'ipfs object get --encoding=json' returns the correct content type" ' - curl -X POST -sI "http://$API_ADDR/api/v0/object/get?arg=$HASH&encoding=json" | grep -q "^Content-Type: application/json" - ' - - test_expect_success "'ipfs object get --encoding=text' returns the correct content type" ' - curl -X POST -sI "http://$API_ADDR/api/v0/object/get?arg=$HASH&encoding=text" | grep -q "^Content-Type: text/plain" - ' - - test_expect_success "'ipfs object get --encoding=xml' returns the correct content type" ' - curl -X POST -sI "http://$API_ADDR/api/v0/object/get?arg=$HASH&encoding=xml" | grep -q "^Content-Type: application/xml" - ' } # should work offline @@ -463,7 +139,6 @@ test_object_cmd # should work online test_launch_ipfs_daemon test_object_cmd -test_object_content_type test_kill_ipfs_daemon test_done diff --git a/test/sharness/t0081-repo-pinning.sh b/test/sharness/t0081-repo-pinning.sh index 030f3fa3d06..92cb71c3858 100755 --- a/test/sharness/t0081-repo-pinning.sh +++ b/test/sharness/t0081-repo-pinning.sh @@ -114,8 +114,8 @@ test_expect_success "objects are there" ' ' # saving this output for later -test_expect_success "ipfs object links $HASH_DIR1 works" ' - ipfs object links $HASH_DIR1 > DIR1_objlink +test_expect_success "ipfs dag get $HASH_DIR1 works" ' + ipfs dag get $HASH_DIR1 | jq -r ".Links[] | .Hash | .[\"/\"]" > DIR1_objlink ' @@ -224,7 +224,7 @@ test_expect_success "some objects are still there" ' ipfs cat "$HASH_FILE1" >>actual8 && ipfs ls "$HASH_DIR4" >>actual8 && ipfs ls "$HASH_DIR2" >>actual8 && - ipfs object links "$HASH_DIR1" >>actual8 && + ipfs dag get "$HASH_DIR1" | jq -r ".Links[] | .Hash | .[\"/\"]" >>actual8 && test_cmp expected8 actual8 ' diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index 67fee89093a..6a803080e85 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -157,13 +157,13 @@ test_get_cmd() { test_get_fail() { test_expect_success "create an object that has unresolvable links" ' cat <<-\EOF >bad_object && -{ "Links": [ { "Name": "foo", "Hash": "QmZzaC6ydNXiR65W8VjGA73ET9MZ6VFAqUT1ngYMXcpihn", "Size": 1897 }, { "Name": "bar", "Hash": "Qmd4mG6pDFDmDTn6p3hX1srP8qTbkyXKj5yjpEsiHDX3u8", "Size": 56 }, { "Name": "baz", "Hash": "QmUTjwRnG28dSrFFVTYgbr6LiDLsBmRr2SaUSTGheK2YqG", "Size": 24266 } ], "Data": "\b\u0001" } +{"Data":{"/":{"bytes":"CAE"}},"Links":[{"Hash":{"/":"Qmd4mG6pDFDmDTn6p3hX1srP8qTbkyXKj5yjpEsiHDX3u8"},"Name":"bar","Tsize":56},{"Hash":{"/":"QmUTjwRnG28dSrFFVTYgbr6LiDLsBmRr2SaUSTGheK2YqG"},"Name":"baz","Tsize":24266},{"Hash":{"/":"QmZzaC6ydNXiR65W8VjGA73ET9MZ6VFAqUT1ngYMXcpihn"},"Name":"foo","Tsize":1897}]} EOF - cat bad_object | ipfs object put > put_out + cat bad_object | ipfs dag put --store-codec dag-pb > put_out ' test_expect_success "output looks good" ' - echo "added QmaGidyrnX8FMbWJoxp8HVwZ1uRKwCyxBJzABnR1S2FVUr" > put_exp && + echo "bafybeifrjjol3gixedca6etdwccnvwfvhurc4wb3i5mnk2rvwvyfcgwxd4" > put_exp && test_cmp put_exp put_out ' diff --git a/test/sharness/t0252-files-gc.sh b/test/sharness/t0252-files-gc.sh index 7267985d49a..f2eb25b4fcc 100755 --- a/test/sharness/t0252-files-gc.sh +++ b/test/sharness/t0252-files-gc.sh @@ -38,9 +38,9 @@ test_expect_success "gc okay after adding incomplete node -- prep" ' ' test_expect_success "gc okay after adding incomplete node" ' - ipfs object stat $ADIR_HASH && + ipfs dag get $ADIR_HASH && ipfs repo gc && - ipfs object stat $ADIR_HASH + ipfs dag get $ADIR_HASH ' test_expect_success "add directory with direct pin" '