Skip to content

Commit 7548eb3

Browse files
committed
Add --cid-base & --upgrade-cidv0 global opt. and enable them on select cmds
License: MIT Signed-off-by: Kevin Atkinson <[email protected]>
1 parent cbc6e69 commit 7548eb3

File tree

8 files changed

+232
-30
lines changed

8 files changed

+232
-30
lines changed

core/apicid.go

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package core
2+
3+
import (
4+
"encoding/json"
5+
6+
cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid"
7+
mbase "gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase"
8+
//path "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
9+
)
10+
11+
// CidEncoder is a type used to encode or recode Cid as the user
12+
// specifies
13+
type CidEncoder interface {
14+
Encode(c cid.Cid) string
15+
Recode(v string) (string, error)
16+
}
17+
18+
// BasicCidEncoder is a basic CidEncoder that will encode Cid's using
19+
// a specifed base, optionally upgrading a Cid if is Version 0
20+
type BasicCidEncoder struct {
21+
Base mbase.Encoder
22+
Upgrade bool
23+
}
24+
25+
var DefaultCidEncoder = BasicCidEncoder{
26+
Base: mbase.MustNewEncoder(mbase.Base58BTC),
27+
Upgrade: false,
28+
}
29+
30+
// CidJSONBase is the base to use when Encoding into JSON.
31+
//var CidJSONBase mbase.Encoder = mbase.MustNewEncoder(mbase.Base58BTC)
32+
var CidJSONBase mbase.Encoder = mbase.MustNewEncoder(mbase.Base32)
33+
34+
// APICid is a type to respesnt CID in the API
35+
type APICid struct {
36+
str string // always in CidJSONBase
37+
}
38+
39+
// FromCid created an APICid from a Cid
40+
func FromCid(c cid.Cid) APICid {
41+
return APICid{c.Encode(CidJSONBase)}
42+
}
43+
44+
// Cid converts an APICid to a CID
45+
func (c APICid) Cid() (cid.Cid, error) {
46+
return cid.Decode(c.str)
47+
}
48+
49+
func (c APICid) String() string {
50+
return c.Encode(DefaultCidEncoder)
51+
}
52+
53+
func (c APICid) Encode(enc CidEncoder) string {
54+
if c.str == "" {
55+
return ""
56+
}
57+
str, err := enc.Recode(c.str)
58+
if err != nil {
59+
return c.str
60+
}
61+
return str
62+
}
63+
64+
func (c *APICid) UnmarshalJSON(b []byte) error {
65+
return json.Unmarshal(b, &c.str)
66+
}
67+
68+
func (c APICid) MarshalJSON() ([]byte, error) {
69+
return json.Marshal(c.str)
70+
}
71+
72+
func (enc BasicCidEncoder) Encode(c cid.Cid) string {
73+
if c.Version() == 0 {
74+
c = cid.NewCidV1(c.Type(), c.Hash())
75+
}
76+
return c.Encode(enc.Base)
77+
}
78+
79+
func (enc BasicCidEncoder) Recode(v string) (string, error) {
80+
skip, err := enc.NoopRecode(v)
81+
if skip || err != nil {
82+
return v, err
83+
}
84+
85+
c, err := cid.Decode(v)
86+
if err != nil {
87+
return v, err
88+
}
89+
90+
return enc.Encode(c), nil
91+
}
92+
93+
func (enc BasicCidEncoder) NoopRecode(v string) (bool, error) {
94+
if len(v) < 2 {
95+
return false, cid.ErrCidTooShort
96+
}
97+
ver := cidVer(v)
98+
skip := ver == 0 && !enc.Upgrade || ver == 1 && v[0] == byte(enc.Base.Encoding())
99+
return skip, nil
100+
}
101+
102+
func cidVer(v string) int {
103+
if len(v) == 46 && v[:2] == "Qm" {
104+
return 0
105+
} else {
106+
return 1
107+
}
108+
}
109+
110+
// func (enc *CidEncoder) Scan(cids ...string) {
111+
// if enc.Override == nil {
112+
// enc.Override = map[cid.Cid]string{}
113+
// }
114+
// for _, p := range cids {
115+
// //segs := path.FromString(p).Segments()
116+
// //v := segs[0]
117+
// //if v == "ipfs" && len(segs) > 0 {
118+
// // v = segs[1]
119+
// //}
120+
// v := p
121+
// skip, err := enc.noopRecode(v)
122+
// if skip || err != nil {
123+
// continue
124+
// }
125+
// c, err := cid.Decode(v)
126+
// if err != nil {
127+
// continue
128+
// }
129+
// enc.Override[c] = v
130+
// }
131+
// }

core/commands/add.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,12 @@ You can now check what blocks have been created by:
390390
log.Warning("cannot determine size of input file")
391391
}
392392

393+
err := HandleCidBase(req)
394+
if err != nil {
395+
re.SetError(err, cmdkit.ErrNormal)
396+
return re
397+
}
398+
393399
progressBar := func(wait chan struct{}) {
394400
defer close(wait)
395401

@@ -425,8 +431,9 @@ You can now check what blocks have been created by:
425431
break LOOP
426432
}
427433
output := out.(*coreunix.AddedObject)
428-
if len(output.Hash) > 0 {
429-
lastHash = output.Hash
434+
hash := output.Hash.String()
435+
if len(hash) > 0 {
436+
lastHash = hash
430437
if quieter {
431438
continue
432439
}
@@ -436,9 +443,9 @@ You can now check what blocks have been created by:
436443
fmt.Fprintf(os.Stderr, "\033[2K\r")
437444
}
438445
if quiet {
439-
fmt.Fprintf(os.Stdout, "%s\n", output.Hash)
446+
fmt.Fprintf(os.Stdout, "%s\n", hash)
440447
} else {
441-
fmt.Fprintf(os.Stdout, "added %s %s\n", output.Hash, output.Name)
448+
fmt.Fprintf(os.Stdout, "added %s %s\n", hash, output.Name)
442449
}
443450

444451
} else {

core/commands/ls.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ import (
2424
)
2525

2626
type LsLink struct {
27-
Name, Hash string
28-
Size uint64
29-
Type unixfspb.Data_DataType
27+
Name string
28+
Hash core.APICid
29+
Size uint64
30+
Type unixfspb.Data_DataType
3031
}
3132

3233
type LsObject struct {
@@ -160,7 +161,7 @@ The JSON output contains type information.
160161
}
161162
output[i].Links[j] = LsLink{
162163
Name: link.Name,
163-
Hash: link.Cid.String(),
164+
Hash: core.FromCid(link.Cid),
164165
Size: link.Size,
165166
Type: t,
166167
}
@@ -171,6 +172,10 @@ The JSON output contains type information.
171172
},
172173
Marshalers: cmds.MarshalerMap{
173174
cmds.Text: func(res cmds.Response) (io.Reader, error) {
175+
err := HandleCidBaseLegacy(res.Request())
176+
if err != nil {
177+
return nil, err
178+
}
174179

175180
v, err := unwrapOutput(res.Output())
176181
if err != nil {

core/commands/pin.go

+27-11
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ var PinCmd = &cmds.Command{
3939
}
4040

4141
type PinOutput struct {
42-
Pins []string
42+
Pins []core.APICid
4343
}
4444

4545
type AddPinOutput struct {
46-
Pins []string
46+
Pins []core.APICid
4747
Progress int `json:",omitempty"`
4848
}
4949

@@ -84,7 +84,7 @@ var addPinCmd = &cmds.Command{
8484
res.SetError(err, cmdkit.ErrNormal)
8585
return
8686
}
87-
res.SetOutput(&AddPinOutput{Pins: cidsToStrings(added)})
87+
res.SetOutput(&AddPinOutput{Pins: toAPICids(added)})
8888
return
8989
}
9090

@@ -117,7 +117,7 @@ var addPinCmd = &cmds.Command{
117117
if pv := v.Value(); pv != 0 {
118118
out <- &AddPinOutput{Progress: v.Value()}
119119
}
120-
out <- &AddPinOutput{Pins: cidsToStrings(val.pins)}
120+
out <- &AddPinOutput{Pins: toAPICids(val.pins)}
121121
return
122122
case <-ticker.C:
123123
out <- &AddPinOutput{Progress: v.Value()}
@@ -130,12 +130,16 @@ var addPinCmd = &cmds.Command{
130130
},
131131
Marshalers: cmds.MarshalerMap{
132132
cmds.Text: func(res cmds.Response) (io.Reader, error) {
133+
err := HandleCidBaseLegacy(res.Request())
134+
if err != nil {
135+
return nil, err
136+
}
133137
v, err := unwrapOutput(res.Output())
134138
if err != nil {
135139
return nil, err
136140
}
137141

138-
var added []string
142+
var added []core.APICid
139143

140144
switch out := v.(type) {
141145
case *AddPinOutput:
@@ -206,10 +210,14 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
206210
return
207211
}
208212

209-
res.SetOutput(&PinOutput{cidsToStrings(removed)})
213+
res.SetOutput(&PinOutput{toAPICids(removed)})
210214
},
211215
Marshalers: cmds.MarshalerMap{
212216
cmds.Text: func(res cmds.Response) (io.Reader, error) {
217+
err := HandleCidBaseLegacy(res.Request())
218+
if err != nil {
219+
return nil, err
220+
}
213221
v, err := unwrapOutput(res.Output())
214222
if err != nil {
215223
return nil, err
@@ -318,6 +326,10 @@ Example:
318326
Type: RefKeyList{},
319327
Marshalers: cmds.MarshalerMap{
320328
cmds.Text: func(res cmds.Response) (io.Reader, error) {
329+
err := HandleCidBaseLegacy(res.Request())
330+
if err != nil {
331+
return nil, err
332+
}
321333
v, err := unwrapOutput(res.Output())
322334
if err != nil {
323335
return nil, err
@@ -345,6 +357,10 @@ Example:
345357
},
346358
}
347359

360+
type UpdatePinOutput struct {
361+
Pins []string // really paths
362+
}
363+
348364
var updatePinCmd = &cmds.Command{
349365
Helptext: cmdkit.HelpText{
350366
Tagline: "Update a recursive pin",
@@ -362,7 +378,7 @@ new pin and removing the old one.
362378
Options: []cmdkit.Option{
363379
cmdkit.BoolOption("unpin", "Remove the old pin.").WithDefault(true),
364380
},
365-
Type: PinOutput{},
381+
Type: UpdatePinOutput{},
366382
Run: func(req cmds.Request, res cmds.Response) {
367383
n, err := req.InvocContext().GetNode()
368384
if err != nil {
@@ -417,7 +433,7 @@ new pin and removing the old one.
417433
return
418434
}
419435

420-
res.SetOutput(&PinOutput{Pins: []string{from.String(), to.String()}})
436+
res.SetOutput(&UpdatePinOutput{Pins: []string{from.String(), to.String()}})
421437
},
422438
Marshalers: cmds.MarshalerMap{
423439
cmds.Text: func(res cmds.Response) (io.Reader, error) {
@@ -680,10 +696,10 @@ func (r PinVerifyRes) Format(out io.Writer) {
680696
}
681697
}
682698

683-
func cidsToStrings(cs []cid.Cid) []string {
684-
out := make([]string, 0, len(cs))
699+
func toAPICids(cs []cid.Cid) []core.APICid {
700+
out := make([]core.APICid, 0, len(cs))
685701
for _, c := range cs {
686-
out = append(out, c.String())
702+
out = append(out, core.FromCid(c))
687703
}
688704
return out
689705
}

core/commands/root.go

+39-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
oldcmds "github.com/ipfs/go-ipfs/commands"
99
lgc "github.com/ipfs/go-ipfs/commands/legacy"
10+
core "github.com/ipfs/go-ipfs/core"
1011
dag "github.com/ipfs/go-ipfs/core/commands/dag"
1112
e "github.com/ipfs/go-ipfs/core/commands/e"
1213
name "github.com/ipfs/go-ipfs/core/commands/name"
@@ -16,14 +17,17 @@ import (
1617
"gx/ipfs/QmPTfgFTo9PFr1PvPKyKoeMgBvYPh6cX3aDP7DHKVbnCbi/go-ipfs-cmds"
1718
logging "gx/ipfs/QmRREK2CAZ5Re2Bd9zZFG6FeYDppUWt5cMgsoUEp3ktgSr/go-log"
1819
"gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit"
20+
mbase "gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase"
1921
)
2022

2123
var log = logging.Logger("core/commands")
2224

2325
var ErrNotOnline = errors.New("this command must be run in online mode. Try running 'ipfs daemon' first")
2426

2527
const (
26-
ApiOption = "api"
28+
ApiOption = "api"
29+
CidBaseOption = "cid-base"
30+
UpgradeCidV0Option = "upgrade-cidv0"
2731
)
2832

2933
var Root = &cmds.Command{
@@ -95,6 +99,8 @@ The CLI will exit with one of the following values:
9599
cmdkit.BoolOption("h", "Show a short version of the command help text."),
96100
cmdkit.BoolOption("local", "L", "Run the command locally, instead of using the daemon."),
97101
cmdkit.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"),
102+
cmdkit.StringOption(CidBaseOption, "mbase", "Multi-base to use to encode version 1 CIDs in output."),
103+
cmdkit.BoolOption(UpgradeCidV0Option, "Upgrade CID version 0 to version 1 in output."),
98104

99105
// global options, added to every command
100106
cmds.OptionEncodingType,
@@ -222,3 +228,35 @@ func MessageTextMarshaler(res oldcmds.Response) (io.Reader, error) {
222228

223229
return strings.NewReader(out.Message), nil
224230
}
231+
232+
func handleCidBase(base string, upgrade bool, upgradeDefined bool) error {
233+
enc := core.DefaultCidEncoder
234+
235+
if base != "" {
236+
var err error
237+
enc.Base, err = mbase.EncoderByName(base)
238+
if err != nil {
239+
return err
240+
}
241+
}
242+
243+
enc.Upgrade = upgrade
244+
if base != "" && !upgradeDefined {
245+
enc.Upgrade = true
246+
}
247+
248+
core.DefaultCidEncoder = enc
249+
return nil
250+
}
251+
252+
func HandleCidBase(req *cmds.Request) error {
253+
base, _ := req.Options[CidBaseOption].(string)
254+
upgrade, defined := req.Options[UpgradeCidV0Option].(bool)
255+
return handleCidBase(base, upgrade, defined)
256+
}
257+
258+
func HandleCidBaseLegacy(req oldcmds.Request) error {
259+
base, _, _ := req.Option(CidBaseOption).String()
260+
upgrade, defined, _ := req.Option(UpgradeCidV0Option).Bool()
261+
return handleCidBase(base, upgrade, defined)
262+
}

0 commit comments

Comments
 (0)