mirror of
https://github.com/ipfs/kubo.git
synced 2025-08-14 19:11:02 +08:00

Also change existing 'Node' type to 'ProtoNode' and use that most everywhere for now. As we move forward with the integration we will try and use the Node interface in more places that we're currently using ProtoNode. License: MIT Signed-off-by: Jeromy <why@ipfs.io>
140 lines
3.5 KiB
Go
140 lines
3.5 KiB
Go
package objectcmd
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
|
|
cmds "github.com/ipfs/go-ipfs/commands"
|
|
core "github.com/ipfs/go-ipfs/core"
|
|
dag "github.com/ipfs/go-ipfs/merkledag"
|
|
dagutils "github.com/ipfs/go-ipfs/merkledag/utils"
|
|
path "github.com/ipfs/go-ipfs/path"
|
|
)
|
|
|
|
type Changes struct {
|
|
Changes []*dagutils.Change
|
|
}
|
|
|
|
var ObjectDiffCmd = &cmds.Command{
|
|
Helptext: cmds.HelpText{
|
|
Tagline: "Display the diff between two ipfs objects.",
|
|
ShortDescription: `
|
|
'ipfs object diff' is a command used to show the differences between
|
|
two ipfs objects.`,
|
|
LongDescription: `
|
|
'ipfs object diff' is a command used to show the differences between
|
|
two ipfs objects.
|
|
|
|
Example:
|
|
|
|
> ls foo
|
|
bar baz/ giraffe
|
|
> ipfs add -r foo
|
|
...
|
|
Added QmegHcnrPgMwC7tBiMxChD54fgQMBUecNw9nE9UUU4x1bz foo
|
|
> OBJ_A=QmegHcnrPgMwC7tBiMxChD54fgQMBUecNw9nE9UUU4x1bz
|
|
> echo "different content" > foo/bar
|
|
> ipfs add -r foo
|
|
...
|
|
Added QmcmRptkSPWhptCttgHg27QNDmnV33wAJyUkCnAvqD3eCD foo
|
|
> OBJ_B=QmcmRptkSPWhptCttgHg27QNDmnV33wAJyUkCnAvqD3eCD
|
|
> ipfs object diff -v $OBJ_A $OBJ_B
|
|
Changed "bar" from QmNgd5cz2jNftnAHBhcRUGdtiaMzb5Rhjqd4etondHHST8 to QmRfFVsjSXkhFxrfWnLpMae2M4GBVsry6VAuYYcji5MiZb.
|
|
`,
|
|
},
|
|
Arguments: []cmds.Argument{
|
|
cmds.StringArg("obj_a", true, false, "Object to diff against."),
|
|
cmds.StringArg("obj_b", true, false, "Object to diff."),
|
|
},
|
|
Options: []cmds.Option{
|
|
cmds.BoolOption("verbose", "v", "Print extra information."),
|
|
},
|
|
Run: func(req cmds.Request, res cmds.Response) {
|
|
node, err := req.InvocContext().GetNode()
|
|
if err != nil {
|
|
res.SetError(err, cmds.ErrNormal)
|
|
return
|
|
}
|
|
|
|
a := req.Arguments()[0]
|
|
b := req.Arguments()[1]
|
|
|
|
pa, err := path.ParsePath(a)
|
|
if err != nil {
|
|
res.SetError(err, cmds.ErrNormal)
|
|
return
|
|
}
|
|
|
|
pb, err := path.ParsePath(b)
|
|
if err != nil {
|
|
res.SetError(err, cmds.ErrNormal)
|
|
return
|
|
}
|
|
|
|
ctx := req.Context()
|
|
|
|
obj_a, err := core.Resolve(ctx, node, pa)
|
|
if err != nil {
|
|
res.SetError(err, cmds.ErrNormal)
|
|
return
|
|
}
|
|
|
|
obj_b, err := core.Resolve(ctx, node, pb)
|
|
if err != nil {
|
|
res.SetError(err, cmds.ErrNormal)
|
|
return
|
|
}
|
|
|
|
pbobj_a, ok := obj_a.(*dag.ProtoNode)
|
|
if !ok {
|
|
res.SetError(dag.ErrNotProtobuf, cmds.ErrNormal)
|
|
return
|
|
}
|
|
|
|
pbobj_b, ok := obj_b.(*dag.ProtoNode)
|
|
if !ok {
|
|
res.SetError(dag.ErrNotProtobuf, cmds.ErrNormal)
|
|
return
|
|
}
|
|
|
|
changes, err := dagutils.Diff(ctx, node.DAG, pbobj_a, pbobj_b)
|
|
if err != nil {
|
|
res.SetError(err, cmds.ErrNormal)
|
|
return
|
|
}
|
|
|
|
res.SetOutput(&Changes{changes})
|
|
},
|
|
Type: Changes{},
|
|
Marshalers: cmds.MarshalerMap{
|
|
cmds.Text: func(res cmds.Response) (io.Reader, error) {
|
|
verbose, _, _ := res.Request().Option("v").Bool()
|
|
changes := res.Output().(*Changes)
|
|
buf := new(bytes.Buffer)
|
|
for _, change := range changes.Changes {
|
|
if verbose {
|
|
switch change.Type {
|
|
case dagutils.Add:
|
|
fmt.Fprintf(buf, "Added new link %q pointing to %s.\n", change.Path, change.After)
|
|
case dagutils.Mod:
|
|
fmt.Fprintf(buf, "Changed %q from %s to %s.\n", change.Path, change.Before, change.After)
|
|
case dagutils.Remove:
|
|
fmt.Fprintf(buf, "Removed link %q (was %s).\n", change.Path, change.Before)
|
|
}
|
|
} else {
|
|
switch change.Type {
|
|
case dagutils.Add:
|
|
fmt.Fprintf(buf, "+ %s %q\n", change.After, change.Path)
|
|
case dagutils.Mod:
|
|
fmt.Fprintf(buf, "~ %s %s %q\n", change.Before, change.After, change.Path)
|
|
case dagutils.Remove:
|
|
fmt.Fprintf(buf, "- %s %q\n", change.Before, change.Path)
|
|
}
|
|
}
|
|
}
|
|
return buf, nil
|
|
},
|
|
},
|
|
}
|