main.go 2.62 KB
Newer Older
1 2 3 4 5
package main

import (
	"fmt"
	"os"
Kevin Atkinson's avatar
Kevin Atkinson committed
6
	"strings"
7 8 9

	c "github.com/ipfs/go-cid"

Kevin Atkinson's avatar
Kevin Atkinson committed
10
	mb "github.com/multiformats/go-multibase"
11 12
)

Kevin Atkinson's avatar
Kevin Atkinson committed
13
func usage() {
14
	fmt.Fprintf(os.Stderr, "usage: %s [-b multibase-code] [-v cid-version] <fmt-str> <cid> ...\n\n", os.Args[0])
15
	fmt.Fprintf(os.Stderr, "<fmt-str> is either 'prefix' or a printf style format string:\n%s", c.FormatRef)
16
	os.Exit(2)
Kevin Atkinson's avatar
Kevin Atkinson committed
17 18
}

19 20
func main() {
	if len(os.Args) < 2 {
Kevin Atkinson's avatar
Kevin Atkinson committed
21 22 23
		usage()
	}
	newBase := mb.Encoding(-1)
24
	var verConv func(cid *c.Cid) (*c.Cid, error)
Kevin Atkinson's avatar
Kevin Atkinson committed
25
	args := os.Args[1:]
26 27 28 29 30 31 32
outer:
	for {
		switch args[0] {
		case "-b":
			if len(args) < 2 {
				usage()
			}
33 34 35
			encoder, err := mb.EncoderByName(args[1])
			if err != nil {
				fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error())
36
				os.Exit(2)
37
			}
38
			newBase = encoder.Encoding()
39 40 41 42 43 44 45 46 47 48 49 50
			args = args[2:]
		case "-v":
			if len(args) < 2 {
				usage()
			}
			switch args[1] {
			case "0":
				verConv = toCidV0
			case "1":
				verConv = toCidV1
			default:
				fmt.Fprintf(os.Stderr, "Error: Invalid cid version: %s\n", args[1])
51
				os.Exit(2)
52 53 54 55
			}
			args = args[2:]
		default:
			break outer
Kevin Atkinson's avatar
Kevin Atkinson committed
56 57 58 59
		}
	}
	if len(args) < 2 {
		usage()
60
	}
Kevin Atkinson's avatar
Kevin Atkinson committed
61 62
	fmtStr := args[0]
	switch fmtStr {
63
	case "prefix":
Kevin Atkinson's avatar
Kevin Atkinson committed
64 65 66 67
		fmtStr = "%P"
	default:
		if strings.IndexByte(fmtStr, '%') == -1 {
			fmt.Fprintf(os.Stderr, "Error: Invalid format string: %s\n", fmtStr)
68
			os.Exit(2)
Kevin Atkinson's avatar
Kevin Atkinson committed
69 70 71
		}
	}
	for _, cidStr := range args[1:] {
72
		cid, err := c.Decode(cidStr)
73
		if err != nil {
Kevin Atkinson's avatar
Kevin Atkinson committed
74
			fmt.Fprintf(os.Stdout, "!INVALID_CID!\n")
75
			errorMsg("%s: %v", cidStr, err)
Kevin Atkinson's avatar
Kevin Atkinson committed
76 77 78
			// Don't abort on a bad cid
			continue
		}
79 80 81
		base := newBase
		if newBase == -1 {
			base, _ = c.ExtractEncoding(cidStr)
82 83 84 85
		}
		if verConv != nil {
			cid, err = verConv(cid)
			if err != nil {
86 87
				fmt.Fprintf(os.Stdout, "!ERROR!\n")
				errorMsg("%s: %v", cidStr, err)
88 89 90 91
				// Don't abort on a bad conversion
				continue
			}
		}
92
		str, err := c.Format(fmtStr, base, cid)
Kevin Atkinson's avatar
Kevin Atkinson committed
93
		switch err.(type) {
94
		case c.FormatStringError:
Kevin Atkinson's avatar
Kevin Atkinson committed
95
			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
96
			os.Exit(2)
Kevin Atkinson's avatar
Kevin Atkinson committed
97 98 99 100 101 102 103
		default:
			fmt.Fprintf(os.Stdout, "!ERROR!\n")
			errorMsg("%s: %v", cidStr, err)
			// Don't abort on cid specific errors
			continue
		case nil:
			// no error
104
		}
Kevin Atkinson's avatar
Kevin Atkinson committed
105
		fmt.Fprintf(os.Stdout, "%s\n", str)
106
	}
107 108 109 110 111 112 113 114 115 116
	os.Exit(exitCode)
}

var exitCode = 0

func errorMsg(fmtStr string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, "Error: ")
	fmt.Fprintf(os.Stderr, fmtStr, a...)
	fmt.Fprintf(os.Stderr, "\n")
	exitCode = 1
117 118
}

119 120 121 122 123 124 125 126 127 128
func toCidV0(cid *c.Cid) (*c.Cid, error) {
	if cid.Type() != c.DagProtobuf {
		return nil, fmt.Errorf("can't convert non-protobuf nodes to cidv0")
	}
	return c.NewCidV0(cid.Hash()), nil
}

func toCidV1(cid *c.Cid) (*c.Cid, error) {
	return c.NewCidV1(cid.Type(), cid.Hash()), nil
}