Skip to content

Commit 71f36ca

Browse files
committed
Add global --cid-base option and enable it for ipfs add and tar commands.
This also adds a global --output-cidv1 option. License: MIT Signed-off-by: Kevin Atkinson <[email protected]>
1 parent 4f73615 commit 71f36ca

File tree

10 files changed

+163
-26
lines changed

10 files changed

+163
-26
lines changed

core/commands/add.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ You can now check what blocks have been created by:
225225
outChan := make(chan interface{})
226226
req := res.Request()
227227

228+
err := cmdenv.ProcCidBaseClientSide(req)
229+
if err != nil {
230+
return err
231+
}
232+
228233
sizeFile, ok := req.Files.(files.SizeFile)
229234
if ok {
230235
// Could be slow.
@@ -279,8 +284,9 @@ You can now check what blocks have been created by:
279284
break LOOP
280285
}
281286
output := out.(*coreiface.AddEvent)
282-
if len(output.Hash) > 0 {
283-
lastHash = output.Hash
287+
hash := output.Hash.String()
288+
if len(hash) > 0 {
289+
lastHash = hash
284290
if quieter {
285291
continue
286292
}
@@ -290,9 +296,9 @@ You can now check what blocks have been created by:
290296
fmt.Fprintf(os.Stderr, "\033[2K\r")
291297
}
292298
if quiet {
293-
fmt.Fprintf(os.Stdout, "%s\n", output.Hash)
299+
fmt.Fprintf(os.Stdout, "%s\n", hash)
294300
} else {
295-
fmt.Fprintf(os.Stdout, "added %s %s\n", output.Hash, output.Name)
301+
fmt.Fprintf(os.Stdout, "added %s %s\n", hash, output.Name)
296302
}
297303

298304
} else {

core/commands/cmdenv/cidbase.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package cmdenv
2+
3+
import (
4+
cidenc "gx/ipfs/QmWf8NwKFLbTBvAvZst3bYF7WEEetzxWyMhvQ885cj9MM8/go-cidutil/cidenc"
5+
cmds "gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
6+
cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
7+
mbase "gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase"
8+
)
9+
10+
var OptionCidBase = cmdkit.StringOption("cid-base", "Multi-base encoding used for version 1 CIDs in output.")
11+
var OptionOutputCidV1 = cmdkit.BoolOption("output-cidv1", "Upgrade CID version 0 to version 1 in output.")
12+
13+
// ProcCidBase processes the `cid-base` and `output-cidv1` options and
14+
// returns a encoder to use based on those parameters.
15+
func ProcCidBase(req *cmds.Request) (cidenc.Encoder, error) {
16+
base, _ := req.Options["cid-base"].(string)
17+
upgrade, upgradeDefined := req.Options["output-cidv1"].(bool)
18+
19+
var e cidenc.Encoder = cidenc.Default
20+
21+
if base != "" {
22+
var err error
23+
e.Base, err = mbase.EncoderByName(base)
24+
if err != nil {
25+
return e, err
26+
}
27+
if !upgradeDefined {
28+
e.Upgrade = true
29+
}
30+
}
31+
32+
if upgradeDefined {
33+
e.Upgrade = upgrade
34+
}
35+
36+
return e, nil
37+
}
38+
39+
// ProcCidBaseClientSide processes the `cid-base` and `output-cidv1`
40+
// options and sets the default encoder based on those options
41+
func ProcCidBaseClientSide(req *cmds.Request) error {
42+
enc, err := ProcCidBase(req)
43+
if err != nil {
44+
return err
45+
}
46+
cidenc.Default = enc
47+
return nil
48+
}

core/commands/root.go

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55

66
lgc "github.com/ipfs/go-ipfs/commands/legacy"
7+
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
78
dag "github.com/ipfs/go-ipfs/core/commands/dag"
89
name "github.com/ipfs/go-ipfs/core/commands/name"
910
ocmd "github.com/ipfs/go-ipfs/core/commands/object"
@@ -97,6 +98,9 @@ The CLI will exit with one of the following values:
9798
cmdkit.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"),
9899

99100
// global options, added to every command
101+
cmdenv.OptionCidBase,
102+
cmdenv.OptionOutputCidV1,
103+
100104
cmds.OptionEncodingType,
101105
cmds.OptionStreamChannels,
102106
cmds.OptionTimeout,

core/commands/tar.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
tar "github.com/ipfs/go-ipfs/tar"
1111

1212
"gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path"
13+
apicid "gx/ipfs/QmWf8NwKFLbTBvAvZst3bYF7WEEetzxWyMhvQ885cj9MM8/go-cidutil/apicid"
1314
cmds "gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
1415
dag "gx/ipfs/QmaDBne4KeY3UepeqSVKYpSmQGa3q9zP6x3LfVF2UjF3Hc/go-merkledag"
1516
cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
@@ -59,12 +60,17 @@ represent it.
5960
fi.FileName()
6061
return cmds.EmitOnce(res, &coreiface.AddEvent{
6162
Name: fi.FileName(),
62-
Hash: c.String(),
63+
Hash: apicid.FromCid(c),
6364
})
6465
},
6566
Type: coreiface.AddEvent{},
6667
Encoders: cmds.EncoderMap{
6768
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *coreiface.AddEvent) error {
69+
err := cmdenv.ProcCidBaseClientSide(req)
70+
if err != nil {
71+
return err
72+
}
73+
6874
fmt.Fprintln(w, out.Hash)
6975
return nil
7076
}),

core/coreapi/interface/unixfs.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@ import (
66

77
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
88

9+
apicid "gx/ipfs/QmWf8NwKFLbTBvAvZst3bYF7WEEetzxWyMhvQ885cj9MM8/go-cidutil/apicid"
910
files "gx/ipfs/QmZMWMvWMVKCbHetJ4RgndbuEF1io2UpUxwQwtNjtYPzSC/go-ipfs-files"
1011
ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
1112
)
1213

1314
// TODO: ideas on making this more coreapi-ish without breaking the http API?
1415
type AddEvent struct {
1516
Name string
16-
Hash string `json:",omitempty"`
17-
Bytes int64 `json:",omitempty"`
18-
Size string `json:",omitempty"`
17+
Hash apicid.Hash `json:",omitempty"`
18+
Bytes int64 `json:",omitempty"`
19+
Size string `json:",omitempty"`
1920
}
2021

2122
type UnixfsFile interface {

core/coreapi/unixfs_test.go

+19-9
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ import (
2424
"github.com/ipfs/go-ipfs/repo"
2525

2626
ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto"
27+
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
2728
cbor "gx/ipfs/QmRoARq3nkUb13HSKZGepCZSWe5GrVPwx7xURJGZ7KWv9V/go-ipld-cbor"
2829
pstore "gx/ipfs/QmUymf8fJtideyv3z727BcZUifGBjMZMpCJqu3Gxk5aRUk/go-libp2p-peerstore"
30+
apicid "gx/ipfs/QmWf8NwKFLbTBvAvZst3bYF7WEEetzxWyMhvQ885cj9MM8/go-cidutil/apicid"
2931
unixfs "gx/ipfs/QmXLCwhHh7bxRsBnCKNE9BAN87V44aSxXLquZYTtjr6fZ3/go-unixfs"
3032
mocknet "gx/ipfs/QmXnpYYg2onGLXVxM4Q5PEFcx29k8zeJQkPeLAk9h9naxg/go-libp2p/p2p/net/mock"
3133
files "gx/ipfs/QmZMWMvWMVKCbHetJ4RgndbuEF1io2UpUxwQwtNjtYPzSC/go-ipfs-files"
@@ -165,6 +167,14 @@ func wrapped(f files.File) files.File {
165167
})
166168
}
167169

170+
func apiCid(hash string) apicid.Hash {
171+
c, err := cid.Decode(hash)
172+
if err != nil {
173+
panic(err)
174+
}
175+
return apicid.FromCid(c)
176+
}
177+
168178
func TestAdd(t *testing.T) {
169179
ctx := context.Background()
170180
_, api, err := makeAPI(ctx)
@@ -384,7 +394,7 @@ func TestAdd(t *testing.T) {
384394
data: strFile(helloStr),
385395
path: "/ipfs/zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd",
386396
events: []coreiface.AddEvent{
387-
{Name: "zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", Hash: "zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", Size: strconv.Itoa(len(helloStr))},
397+
{Name: "zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd", Hash: apiCid("zb2rhdhmJjJZs9qkhQCpCQ7VREFkqWw3h1r8utjVvQugwHPFd"), Size: strconv.Itoa(len(helloStr))},
388398
},
389399
opts: []options.UnixfsAddOption{options.Unixfs.RawLeaves(true)},
390400
},
@@ -393,8 +403,8 @@ func TestAdd(t *testing.T) {
393403
data: twoLevelDir(),
394404
path: "/ipfs/QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr",
395405
events: []coreiface.AddEvent{
396-
{Name: "t/abc", Hash: "QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt", Size: "62"},
397-
{Name: "t", Hash: "QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr", Size: "229"},
406+
{Name: "t/abc", Hash: apiCid("QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt"), Size: "62"},
407+
{Name: "t", Hash: apiCid("QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr"), Size: "229"},
398408
},
399409
recursive: true,
400410
opts: []options.UnixfsAddOption{options.Unixfs.Silent(true)},
@@ -404,11 +414,11 @@ func TestAdd(t *testing.T) {
404414
data: twoLevelDir(),
405415
path: "/ipfs/QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr",
406416
events: []coreiface.AddEvent{
407-
{Name: "t/abc/def", Hash: "QmNyJpQkU1cEkBwMDhDNFstr42q55mqG5GE5Mgwug4xyGk", Size: "13"},
408-
{Name: "t/bar", Hash: "QmS21GuXiRMvJKHos4ZkEmQDmRBqRaF5tQS2CQCu2ne9sY", Size: "14"},
409-
{Name: "t/foo", Hash: "QmfAjGiVpTN56TXi6SBQtstit5BEw3sijKj1Qkxn6EXKzJ", Size: "14"},
410-
{Name: "t/abc", Hash: "QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt", Size: "62"},
411-
{Name: "t", Hash: "QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr", Size: "229"},
417+
{Name: "t/abc/def", Hash: apiCid("QmNyJpQkU1cEkBwMDhDNFstr42q55mqG5GE5Mgwug4xyGk"), Size: "13"},
418+
{Name: "t/bar", Hash: apiCid("QmS21GuXiRMvJKHos4ZkEmQDmRBqRaF5tQS2CQCu2ne9sY"), Size: "14"},
419+
{Name: "t/foo", Hash: apiCid("QmfAjGiVpTN56TXi6SBQtstit5BEw3sijKj1Qkxn6EXKzJ"), Size: "14"},
420+
{Name: "t/abc", Hash: apiCid("QmU7nuGs2djqK99UNsNgEPGh6GV4662p6WtsgccBNGTDxt"), Size: "62"},
421+
{Name: "t", Hash: apiCid("QmVG2ZYCkV1S4TK8URA3a4RupBF17A8yAr4FqsRDXVJASr"), Size: "229"},
412422
},
413423
recursive: true,
414424
},
@@ -424,7 +434,7 @@ func TestAdd(t *testing.T) {
424434
{Name: "", Bytes: 524288},
425435
{Name: "", Bytes: 786432},
426436
{Name: "", Bytes: 1000000},
427-
{Name: "QmXXNNbwe4zzpdMg62ZXvnX1oU7MwSrQ3vAEtuwFKCm1oD", Hash: "QmXXNNbwe4zzpdMg62ZXvnX1oU7MwSrQ3vAEtuwFKCm1oD", Size: "1000256"},
437+
{Name: "QmXXNNbwe4zzpdMg62ZXvnX1oU7MwSrQ3vAEtuwFKCm1oD", Hash: apiCid("QmXXNNbwe4zzpdMg62ZXvnX1oU7MwSrQ3vAEtuwFKCm1oD"), Size: "1000256"},
428438
},
429439
recursive: true,
430440
opts: []options.UnixfsAddOption{options.Unixfs.Progress(true)},

core/coreunix/add.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
posinfo "gx/ipfs/QmR6YMs8EkXQLXNwQKxLnQp2VBZSepoEJ8KCZAyanJHhJu/go-ipfs-posinfo"
1919
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
2020
bstore "gx/ipfs/QmSNLNnL3kq3A1NGdQA9AtgxM9CWKiiSEup3W435jCkRQS/go-ipfs-blockstore"
21+
apicid "gx/ipfs/QmWf8NwKFLbTBvAvZst3bYF7WEEetzxWyMhvQ885cj9MM8/go-cidutil/apicid"
2122
unixfs "gx/ipfs/QmXLCwhHh7bxRsBnCKNE9BAN87V44aSxXLquZYTtjr6fZ3/go-unixfs"
2223
balanced "gx/ipfs/QmXLCwhHh7bxRsBnCKNE9BAN87V44aSxXLquZYTtjr6fZ3/go-unixfs/importer/balanced"
2324
ihelper "gx/ipfs/QmXLCwhHh7bxRsBnCKNE9BAN87V44aSxXLquZYTtjr6fZ3/go-unixfs/importer/helpers"
@@ -37,12 +38,13 @@ const progressReaderIncrement = 1024 * 256
3738
var liveCacheSize = uint64(256 << 10)
3839

3940
type Link struct {
40-
Name, Hash string
41-
Size uint64
41+
Name string
42+
Hash apicid.Hash
43+
Size uint64
4244
}
4345

4446
type Object struct {
45-
Hash string
47+
Hash apicid.Hash
4648
Links []Link
4749
Size string
4850
}
@@ -599,7 +601,7 @@ func getOutput(dagnode ipld.Node) (*Object, error) {
599601
}
600602

601603
output := &Object{
602-
Hash: c.String(),
604+
Hash: apicid.FromCid(c),
603605
Size: strconv.FormatUint(s, 10),
604606
Links: make([]Link, len(dagnode.Links())),
605607
}

core/coreunix/add_test.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,11 @@ func TestAddGCLive(t *testing.T) {
9494

9595
}()
9696

97-
addedHashes := make(map[string]struct{})
97+
addedHashes := make(map[cid.Cid]struct{})
9898
select {
9999
case o := <-out:
100-
addedHashes[o.(*coreiface.AddEvent).Hash] = struct{}{}
100+
c, _ := o.(*coreiface.AddEvent).Hash.Cid()
101+
addedHashes[c] = struct{}{}
101102
case <-addDone:
102103
t.Fatal("add shouldnt complete yet")
103104
}
@@ -125,23 +126,24 @@ func TestAddGCLive(t *testing.T) {
125126

126127
// receive next object from adder
127128
o := <-out
128-
addedHashes[o.(*coreiface.AddEvent).Hash] = struct{}{}
129+
c, _ := o.(*coreiface.AddEvent).Hash.Cid()
130+
addedHashes[c] = struct{}{}
129131

130132
<-gcstarted
131133

132134
for r := range gcout {
133135
if r.Error != nil {
134136
t.Fatal(err)
135137
}
136-
if _, ok := addedHashes[r.KeyRemoved.String()]; ok {
138+
if _, ok := addedHashes[r.KeyRemoved]; ok {
137139
t.Fatal("gc'ed a hash we just added")
138140
}
139141
}
140142

141143
var last cid.Cid
142144
for a := range out {
143145
// wait for it to finish
144-
c, err := cid.Decode(a.(*coreiface.AddEvent).Hash)
146+
c, err := a.(*coreiface.AddEvent).Hash.Cid()
145147
if err != nil {
146148
t.Fatal(err)
147149
}

test/sharness/t0040-add-and-cat.sh

+49
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,36 @@ test_add_cat_file() {
272272
echo "added QmZQWnfcqJ6hNkkPvrY9Q5X39GP3jUnUbAV4AbmbbR3Cb1 test_current_dir" > expected
273273
test_cmp expected actual
274274
'
275+
276+
# --cid-base=base32
277+
278+
test_expect_success "ipfs add --cid-base=base32 succeeds" '
279+
echo "Hello Worlds!" >mountdir/hello.txt &&
280+
ipfs add --cid-base=base32 mountdir/hello.txt >actual
281+
'
282+
283+
test_expect_success "ipfs add output looks good" '
284+
HASH="bafybeidpq7lcjx4w5c6yr4vuthzvlav54hgxsremwk73to5ferdc2rxhai" &&
285+
echo "added $HASH hello.txt" >expected &&
286+
test_cmp expected actual
287+
'
288+
289+
test_expect_success "ipfs add --cid-base=base32 --only-hash succeeds" '
290+
ipfs add --cid-base=base32 --only-hash mountdir/hello.txt > oh_actual
291+
'
292+
293+
test_expect_success "ipfs add --only-hash output looks good" '
294+
test_cmp expected oh_actual
295+
'
296+
297+
test_expect_success "ipfs cat succeeds" '
298+
ipfs cat "$HASH" >actual
299+
'
300+
301+
test_expect_success "ipfs cat output looks good" '
302+
echo "Hello Worlds!" >expected &&
303+
test_cmp expected actual
304+
'
275305
}
276306

277307
test_add_cat_5MB() {
@@ -312,6 +342,25 @@ test_add_cat_5MB() {
312342
test_expect_success FUSE "cat ipfs/bigfile looks good" '
313343
test_cmp mountdir/bigfile actual
314344
'
345+
346+
test_expect_success "get base32 version of CID" '
347+
ipfs cid base32 $EXP_HASH > base32_cid &&
348+
BASE32_HASH=`cat base32_cid`
349+
'
350+
351+
test_expect_success "ipfs add --cid-base=base32 bigfile' succeeds" '
352+
ipfs add $ADD_FLAGS --cid-base=base32 mountdir/bigfile >actual ||
353+
test_fsh cat daemon_err
354+
'
355+
356+
test_expect_success "'ipfs add bigfile --cid-base=base32' output looks good" '
357+
echo "added $BASE32_HASH bigfile" >expected &&
358+
test_cmp expected actual
359+
'
360+
361+
test_expect_success "'ipfs cat $BASE32_HASH' succeeds" '
362+
ipfs cat "$BASE32_HASH" >actual
363+
'
315364
}
316365

317366
test_add_cat_raw() {

test/sharness/t0210-tar.sh

+9
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,13 @@ test_expect_success "files look right" '
4646
[ -x foo/script ]
4747
'
4848

49+
test_expect_success "'ipfs tar add --cid-base=base32' succeeds" '
50+
ipfs tar add --cid-base=base32 files.tar > actual
51+
'
52+
53+
test_expect_success "'ipfs tar add --cid-base=base32' has correct hash" '
54+
ipfs cid base32 $TAR_HASH > expected &&
55+
test_cmp expected actual
56+
'
57+
4958
test_done

0 commit comments

Comments
 (0)