diff --git a/core/commands/cid.go b/core/commands/cid.go index f65aaef31..30304f737 100644 --- a/core/commands/cid.go +++ b/core/commands/cid.go @@ -31,6 +31,7 @@ var CidCmd = &cmds.Command{ const ( cidFormatOptionName = "f" cidVerisonOptionName = "v" + cidCodecOptionName = "codec" cidMultibaseOptionName = "b" ) @@ -49,11 +50,13 @@ The optional format string is a printf style format string: Options: []cmds.Option{ cmds.StringOption(cidFormatOptionName, "Printf style format string.").WithDefault("%s"), cmds.StringOption(cidVerisonOptionName, "CID version to convert to."), + cmds.StringOption(cidCodecOptionName, "CID codec to convert to."), cmds.StringOption(cidMultibaseOptionName, "Multibase to display CID in."), }, Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error { fmtStr, _ := req.Options[cidFormatOptionName].(string) verStr, _ := req.Options[cidVerisonOptionName].(string) + codecStr, _ := req.Options[cidCodecOptionName].(string) baseStr, _ := req.Options[cidMultibaseOptionName].(string) opts := cidFormatOpts{} @@ -63,10 +66,21 @@ The optional format string is a printf style format string: } opts.fmtStr = fmtStr + if codecStr != "" { + codec, ok := cid.Codecs[codecStr] + if !ok { + return fmt.Errorf("unknown IPLD codec: %s", codecStr) + } + opts.newCodec = codec + } // otherwise, leave it as 0 (not a valid IPLD codec) + switch verStr { case "": // noop case "0": + if opts.newCodec != 0 && opts.newCodec != cid.DagProtobuf { + return fmt.Errorf("cannot convert to CIDv0 with any codec other than DagPB") + } opts.verConv = toCidV0 case "1": opts.verConv = toCidV1 @@ -125,9 +139,10 @@ var base32Cmd = &cmds.Command{ } type cidFormatOpts struct { - fmtStr string - newBase mbase.Encoding - verConv func(cid cid.Cid) (cid.Cid, error) + fmtStr string + newBase mbase.Encoding + verConv func(cid cid.Cid) (cid.Cid, error) + newCodec uint64 } type argumentIterator struct { @@ -170,6 +185,10 @@ func emitCids(req *cmds.Request, resp cmds.ResponseEmitter, opts cidFormatOpts) continue } + if opts.newCodec != 0 && opts.newCodec != c.Type() { + c = cid.NewCidV1(opts.newCodec, c.Hash()) + } + if opts.verConv != nil { c, err = opts.verConv(c) if err != nil { diff --git a/test/sharness/t0290-cid.sh b/test/sharness/t0290-cid.sh index b7f6e8e53..0659df2a2 100755 --- a/test/sharness/t0290-cid.sh +++ b/test/sharness/t0290-cid.sh @@ -10,6 +10,10 @@ CIDv0="QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv" CIDv1="zdj7WZAAFKPvYPPzyJLso2hhxo8a7ZACFQ4DvvfrNXTHidofr" CIDb32="bafybeibxm2nsadl3fnxv2sxcxmxaco2jl53wpeorjdzidjwf5aqdg7wa6u" +CIDbase="QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6" +CIDb32pb="bafybeievd6mwe6vcwnkwo3eizs3h7w3a34opszbyfxziqdxguhjw7imdve" +CIDb32raw="bafkreievd6mwe6vcwnkwo3eizs3h7w3a34opszbyfxziqdxguhjw7imdve" + test_expect_success "cid base32 works" ' echo $CIDb32 > expected && ipfs cid base32 $CIDv0 > actual1 && @@ -234,4 +238,17 @@ test_expect_success "cid hashes --numeric" ' test_cmp hashes_expect actual ' +test_expect_success "cid format -c raw" ' + echo $CIDb32raw > expected && + ipfs cid format --codec raw -b base32 $CIDb32pb > actual && + test_cmp actual expected +' + +test_expect_success "cid format -c protobuf -v 0" ' + echo $CIDbase > expected && + ipfs cid format --codec protobuf -v 0 $CIDb32raw > actual && + test_cmp actual expected +' + + test_done