forked from ipfs/kubo
/
diff.go
129 lines (111 loc) · 3.34 KB
/
diff.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package objectcmd
import (
"fmt"
"io"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
"github.com/ipfs/go-ipfs/dagutils"
cmds "gx/ipfs/QmQkW9fnCsg9SLHdViiAh6qfBppodsPZVpU92dZLqYtEfs/go-ipfs-cmds"
coreiface "gx/ipfs/QmXLwxifxwfc2bAwq6rdjbYqAsGzWsDE9RM5TWMGtykyj6/interface-go-ipfs-core"
cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
)
const (
verboseOptionName = "verbose"
)
type Changes struct {
Changes []*dagutils.Change
}
var ObjectDiffCmd = &cmds.Command{
Helptext: cmdkit.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: []cmdkit.Argument{
cmdkit.StringArg("obj_a", true, false, "Object to diff against."),
cmdkit.StringArg("obj_b", true, false, "Object to diff."),
},
Options: []cmdkit.Option{
cmdkit.BoolOption(verboseOptionName, "v", "Print extra information."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
a := req.Arguments[0]
b := req.Arguments[1]
pa, err := coreiface.ParsePath(a)
if err != nil {
return err
}
pb, err := coreiface.ParsePath(b)
if err != nil {
return err
}
changes, err := api.Object().Diff(req.Context, pa, pb)
if err != nil {
return err
}
out := make([]*dagutils.Change, len(changes))
for i, change := range changes {
out[i] = &dagutils.Change{
Type: change.Type,
Path: change.Path,
}
if change.Before != nil {
out[i].Before = change.Before.Cid()
}
if change.After != nil {
out[i].After = change.After.Cid()
}
}
return cmds.EmitOnce(res, &Changes{out})
},
Type: Changes{},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Changes) error {
verbose, _ := req.Options[verboseOptionName].(bool)
for _, change := range out.Changes {
if verbose {
switch change.Type {
case dagutils.Add:
fmt.Fprintf(w, "Added new link %q pointing to %s.\n", change.Path, change.After)
case dagutils.Mod:
fmt.Fprintf(w, "Changed %q from %s to %s.\n", change.Path, change.Before, change.After)
case dagutils.Remove:
fmt.Fprintf(w, "Removed link %q (was %s).\n", change.Path, change.Before)
}
} else {
switch change.Type {
case dagutils.Add:
fmt.Fprintf(w, "+ %s %q\n", change.After, change.Path)
case dagutils.Mod:
fmt.Fprintf(w, "~ %s %s %q\n", change.Before, change.After, change.Path)
case dagutils.Remove:
fmt.Fprintf(w, "- %s %q\n", change.Before, change.Path)
}
}
}
return nil
}),
},
}