Skip to content

Commit 675738c

Browse files
committed
Attempt to preserve base of Cid's provided on the command line.
License: MIT Signed-off-by: Kevin Atkinson <[email protected]>
1 parent 7548eb3 commit 675738c

File tree

8 files changed

+181
-105
lines changed

8 files changed

+181
-105
lines changed

core/apicid.go

+3-83
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,11 @@ package core
33
import (
44
"encoding/json"
55

6+
cidenc "github.com/ipfs/go-ipfs/core/cidenc"
67
cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid"
78
mbase "gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase"
8-
//path "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
99
)
1010

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-
3011
// CidJSONBase is the base to use when Encoding into JSON.
3112
//var CidJSONBase mbase.Encoder = mbase.MustNewEncoder(mbase.Base58BTC)
3213
var CidJSONBase mbase.Encoder = mbase.MustNewEncoder(mbase.Base32)
@@ -47,10 +28,10 @@ func (c APICid) Cid() (cid.Cid, error) {
4728
}
4829

4930
func (c APICid) String() string {
50-
return c.Encode(DefaultCidEncoder)
31+
return c.Encode(cidenc.Default)
5132
}
5233

53-
func (c APICid) Encode(enc CidEncoder) string {
34+
func (c APICid) Encode(enc cidenc.Interface) string {
5435
if c.str == "" {
5536
return ""
5637
}
@@ -68,64 +49,3 @@ func (c *APICid) UnmarshalJSON(b []byte) error {
6849
func (c APICid) MarshalJSON() ([]byte, error) {
6950
return json.Marshal(c.str)
7051
}
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/cidenc/encoder.go

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

core/commands/add.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ 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)
393+
_, err := HandleCidBase(nil, req)
394394
if err != nil {
395395
re.SetError(err, cmdkit.ErrNormal)
396396
return re

core/commands/ls.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ The JSON output contains type information.
172172
},
173173
Marshalers: cmds.MarshalerMap{
174174
cmds.Text: func(res cmds.Response) (io.Reader, error) {
175-
err := HandleCidBaseLegacy(res.Request())
175+
_, err := HandleCidBaseLegacy(nil, res.Request())
176176
if err != nil {
177177
return nil, err
178178
}

core/commands/pin.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ var addPinCmd = &cmds.Command{
130130
},
131131
Marshalers: cmds.MarshalerMap{
132132
cmds.Text: func(res cmds.Response) (io.Reader, error) {
133-
err := HandleCidBaseLegacy(res.Request())
133+
enc, err := HandleCidBaseWithOverrideLegacy(res.Request())
134134
if err != nil {
135135
return nil, err
136136
}
@@ -167,7 +167,7 @@ var addPinCmd = &cmds.Command{
167167

168168
buf := new(bytes.Buffer)
169169
for _, k := range added {
170-
fmt.Fprintf(buf, "pinned %s %s\n", k, pintype)
170+
fmt.Fprintf(buf, "pinned %s %s\n", k.Encode(enc), pintype)
171171
}
172172
return buf, nil
173173
},
@@ -214,7 +214,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
214214
},
215215
Marshalers: cmds.MarshalerMap{
216216
cmds.Text: func(res cmds.Response) (io.Reader, error) {
217-
err := HandleCidBaseLegacy(res.Request())
217+
enc, err := HandleCidBaseWithOverrideLegacy(res.Request())
218218
if err != nil {
219219
return nil, err
220220
}
@@ -230,7 +230,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
230230

231231
buf := new(bytes.Buffer)
232232
for _, k := range added.Pins {
233-
fmt.Fprintf(buf, "unpinned %s\n", k)
233+
fmt.Fprintf(buf, "unpinned %s\n", k.Encode(enc))
234234
}
235235
return buf, nil
236236
},
@@ -326,7 +326,7 @@ Example:
326326
Type: RefKeyList{},
327327
Marshalers: cmds.MarshalerMap{
328328
cmds.Text: func(res cmds.Response) (io.Reader, error) {
329-
err := HandleCidBaseLegacy(res.Request())
329+
_, err := HandleCidBaseLegacy(nil, res.Request())
330330
if err != nil {
331331
return nil, err
332332
}

core/commands/resolve.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
cmds "github.com/ipfs/go-ipfs/commands"
1010
"github.com/ipfs/go-ipfs/core"
11+
cidenc "github.com/ipfs/go-ipfs/core/cidenc"
1112
e "github.com/ipfs/go-ipfs/core/commands/e"
1213
ncmd "github.com/ipfs/go-ipfs/core/commands/name"
1314
ns "github.com/ipfs/go-ipfs/namesys"
@@ -84,6 +85,16 @@ Resolve the value of an IPFS DAG path:
8485
name := req.Arguments()[0]
8586
recursive, _, _ := req.Option("recursive").Bool()
8687

88+
enc := cidenc.Default // make local copy
89+
defined, err := HandleCidBaseLegacy(&enc, req)
90+
if err != nil {
91+
res.SetError(err, cmdkit.ErrNormal)
92+
return
93+
}
94+
if !defined {
95+
enc, _ = enc.FromPath(name)
96+
}
97+
8798
// the case when ipns is resolved step by step
8899
if strings.HasPrefix(name, "/ipns/") && !recursive {
89100
rc, rcok, _ := req.Option("dht-record-count").Int()
@@ -129,7 +140,7 @@ Resolve the value of an IPFS DAG path:
129140

130141
c := node.Cid()
131142

132-
res.SetOutput(&ncmd.ResolvedPath{Path: path.FromCid(c)})
143+
res.SetOutput(&ncmd.ResolvedPath{Path: path.FromString("/ipfs/" + enc.Encode(c))})
133144
},
134145
Marshalers: cmds.MarshalerMap{
135146
cmds.Text: func(res cmds.Response) (io.Reader, error) {

0 commit comments

Comments
 (0)