Skip to content

Commit

Permalink
feat(cmds): add dag diff
Browse files Browse the repository at this point in the history
  • Loading branch information
schomatis committed Apr 28, 2022
1 parent d4879a4 commit f395582
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 10 deletions.
35 changes: 35 additions & 0 deletions core/commands/dag/dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ the existing 'ipfs object' command moving forward.
"import": DagImportCmd,
"export": DagExportCmd,
"stat": DagStatCmd,
"diff": DagDiffCmd,
},
}

Expand Down Expand Up @@ -322,3 +323,37 @@ Note: This command skips duplicate blocks in reporting both size and the number
}),
},
}

type DagDiff struct {
s string
}

// DagDiffCmd is a command for comparing DAG nodes.
// FIXME: Right now only supports DAG-PB encoding (for the roadmap of this
// command see https://github.com/ipfs/go-ipfs/issues/4801).
var DagDiffCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Diffs two DAG nodes.",
ShortDescription: `
'ipfs dag diff' fetches two DAG nodes and returns their differences.
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("node_before", true, false, "First node, \"before\", in the diff."),
cmds.StringArg("node_after", true, false, "First node, \"after\", in the diff."),
},
Options: []cmds.Option{ // FIXME: Remove if unused.
},
Run: dagDiff,
Type: DagDiff{},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, d *DagDiff) error {
_, err := fmt.Fprintf(
w,
"%s\n",
d.s,
)
return err
}),
},
}
56 changes: 56 additions & 0 deletions core/commands/dag/diff.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package dagcmd

import (
"encoding/json"
cmds "github.com/ipfs/go-ipfs-cmds"
"github.com/ipfs/go-ipfs/core/commands/cmdenv"
"io/ioutil"

"github.com/wI2L/jsondiff"
)

func dagDiff(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

getArgNodeAsJson := func(argNumber int) ([]byte, error) {
r, err := getNodeWithCodec(req.Context, req.Arguments[argNumber], "dag-json", api)
if err != nil {
return nil, err
}

jsonOutput, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}

return jsonOutput, nil
}

nodeBefore, err := getArgNodeAsJson(0)
if err != nil {
return err
}
nodeAfter, err := getArgNodeAsJson(1)
if err != nil {
return err
}

patch, err := jsondiff.CompareJSONOpts(nodeBefore, nodeAfter, jsondiff.Invertible())
if err != nil {
return err
}

indented, err := json.MarshalIndent(patch, "", " ")
if err != nil {
return err
}

if err := res.Emit(DagDiff{string(indented)}); err != nil {
return err
}

return nil
}
32 changes: 22 additions & 10 deletions core/commands/dag/get.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package dagcmd

import (
"context"
"fmt"
coreiface "github.com/ipfs/interface-go-ipfs-core"
"io"

"github.com/ipfs/go-ipfs/core/commands/cmdenv"
Expand All @@ -23,24 +25,34 @@ func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e
}

codecStr, _ := req.Options["output-codec"].(string)
var codec mc.Code
if err := codec.Set(codecStr); err != nil {

r, err := getNodeWithCodec(req.Context, codecStr, req.Arguments[0], api)
if err != nil {
return err
}

rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0]))
return res.Emit(r)
}

func getNodeWithCodec(ctx context.Context, nodePath string, codecName string, api coreiface.CoreAPI) (io.Reader, error) {
var codec mc.Code
if err := codec.Set(codecName); err != nil {
return nil, err
}

rp, err := api.ResolvePath(ctx, path.New(nodePath))
if err != nil {
return err
return nil, err
}

obj, err := api.Dag().Get(req.Context, rp.Cid())
obj, err := api.Dag().Get(ctx, rp.Cid())
if err != nil {
return err
return nil, err
}

universal, ok := obj.(ipldlegacy.UniversalNode)
if !ok {
return fmt.Errorf("%T is not a valid IPLD node", obj)
return nil, fmt.Errorf("%T is not a valid IPLD node", obj)
}

finalNode := universal.(ipld.Node)
Expand All @@ -50,13 +62,13 @@ func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e

finalNode, err = traversal.Get(finalNode, remainderPath)
if err != nil {
return err
return nil, err
}
}

encoder, err := multicodec.LookupEncoder(uint64(codec))
if err != nil {
return fmt.Errorf("invalid encoding: %s - %s", codec, err)
return nil, fmt.Errorf("invalid encoding: %s - %s", codec, err)
}

r, w := io.Pipe()
Expand All @@ -67,5 +79,5 @@ func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e
}
}()

return res.Emit(r)
return r, nil
}
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A=
github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
Expand Down Expand Up @@ -1112,6 +1114,8 @@ github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1 h1:EnzzN9fPUkUck/1CuY1FlzBaI
github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI=
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk=
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24 h1:uYuGXJBAi1umT+ZS4oQJUgKtfXCAYTR+n9zw1ViT0vA=
github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
Expand Down

0 comments on commit f395582

Please sign in to comment.