Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ipfs/go-ipfs-cmds
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.3.0
Choose a base ref
...
head repository: ipfs/go-ipfs-cmds
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.6.0
Choose a head ref
  • 14 commits
  • 9 files changed
  • 2 contributors

Commits on Sep 7, 2020

  1. fix: allow requests from electron renderer (#201)

    * fix: allow requests from electron renderer
    
    The Electron Renderer process runs in an embedded  browser window so
    has access to browser-native `fetch`.  If this is used by
    `ipfs-http-client` to make requests against the HTTP API, the
    `User-Agent` header is set to a value that looks similar to a browser
    but no `Origin` or `Referer` headers are sent.
    
    The change here is to relax the user agent check to allow through
    requests from clients with `'Electron'` in their user agents.
    achingbrain authored Sep 7, 2020
    Copy the full SHA
    bb36028 View commit details

Commits on Nov 25, 2020

  1. Copy the full SHA
    4373bad View commit details

Commits on Dec 1, 2020

  1. Copy the full SHA
    6d7b776 View commit details
  2. refactor: cleanup code

    aschmahmann committed Dec 1, 2020
    Copy the full SHA
    11d59a2 View commit details

Commits on Dec 2, 2020

  1. Copy the full SHA
    91330cf View commit details
  2. chore: go mod tidy

    aschmahmann committed Dec 2, 2020
    Copy the full SHA
    d57bbdf View commit details
  3. Merge pull request #203 from ipfs/feat/stringsOption

    feat: support strings option over HTTP API
    aschmahmann authored Dec 2, 2020
    Copy the full SHA
    edc78ef View commit details

Commits on Jan 15, 2021

  1. feat: StringsOption.Parse(string) now returns a slice containing the …

    …original string. Added DelimitedStringsOption which allows passing delimited options on the CLI, such as --option=opt1,opt2 when the delimiter is a comma, instead of requiring the longer form --option=op1 --option=opt2
    aschmahmann committed Jan 15, 2021
    Copy the full SHA
    382fd11 View commit details
  2. Copy the full SHA
    cde56b1 View commit details
  3. Copy the full SHA
    d48b43d View commit details
  4. Copy the full SHA
    16d8195 View commit details
  5. testing: add tests for constructing Options with defaults and parsing…

    … those Options using the CLI parsing tools
    aschmahmann committed Jan 15, 2021
    Copy the full SHA
    e2c3e22 View commit details

Commits on Jan 26, 2021

  1. Copy the full SHA
    c6690cc View commit details

Commits on Jan 27, 2021

  1. Merge pull request #204 from ipfs/feat/stringsDelim

    Added DelimitedStringsOption for enabling delimited strings on the CLI
    aschmahmann authored Jan 27, 2021
    Copy the full SHA
    4ade007 View commit details
Showing with 302 additions and 67 deletions.
  1. +1 −1 cli/parse.go
  2. +170 −20 cli/parse_test.go
  3. +9 −14 go.sum
  4. +12 −2 http/client.go
  5. +7 −0 http/config.go
  6. +9 −0 http/errors_test.go
  7. +25 −24 http/parse.go
  8. +57 −1 option.go
  9. +12 −5 request.go
2 changes: 1 addition & 1 deletion cli/parse.go
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ func setOpts(kv kv, kvType reflect.Kind, opts cmds.OptMap) error {

if kvType == cmds.Strings {
res, _ := opts[kv.Key].([]string)
opts[kv.Key] = append(res, kv.Value.(string))
opts[kv.Key] = append(res, kv.Value.([]string)...)
} else if _, exists := opts[kv.Key]; !exists {
opts[kv.Key] = kv.Value
} else {
190 changes: 170 additions & 20 deletions cli/parse_test.go
Original file line number Diff line number Diff line change
@@ -77,13 +77,32 @@ func TestSameWords(t *testing.T) {
test(f, f, true)
}

func testOptionHelper(t *testing.T, cmd *cmds.Command, args string, expectedOpts kvs, expectedWords words, expectErr bool) {
req := &cmds.Request{}
err := parse(req, strings.Split(args, " "), cmd)
if err == nil {
err = req.FillDefaults()
}
if expectErr {
if err == nil {
t.Errorf("Command line '%v' parsing should have failed", args)
}
} else if err != nil {
t.Errorf("Command line '%v' failed to parse: %v", args, err)
} else if !sameWords(req.Arguments, expectedWords) || !sameKVs(kvs(req.Options), expectedOpts) {
t.Errorf("Command line '%v':\n parsed as %v %v\n instead of %v %v",
args, req.Options, req.Arguments, expectedOpts, expectedWords)
}
}

func TestOptionParsing(t *testing.T) {
cmd := &cmds.Command{
Options: []cmds.Option{
cmds.StringOption("string", "s", "a string"),
cmds.StringOption("flag", "alias", "multiple long"),
cmds.BoolOption("bool", "b", "a bool"),
cmds.StringsOption("strings", "r", "strings array"),
cmds.DelimitedStringsOption(",", "delimstrings", "d", "comma delimited string array"),
},
Subcommands: map[string]*cmds.Command{
"test": &cmds.Command{},
@@ -95,30 +114,12 @@ func TestOptionParsing(t *testing.T) {
},
}

testHelper := func(args string, expectedOpts kvs, expectedWords words, expectErr bool) {
req := &cmds.Request{}
err := parse(req, strings.Split(args, " "), cmd)
if err == nil {
err = req.FillDefaults()
}
if expectErr {
if err == nil {
t.Errorf("Command line '%v' parsing should have failed", args)
}
} else if err != nil {
t.Errorf("Command line '%v' failed to parse: %v", args, err)
} else if !sameWords(req.Arguments, expectedWords) || !sameKVs(kvs(req.Options), expectedOpts) {
t.Errorf("Command line '%v':\n parsed as %v %v\n instead of %v %v",
args, req.Options, req.Arguments, expectedOpts, expectedWords)
}
}

testFail := func(args string) {
testHelper(args, kvs{}, words{}, true)
testOptionHelper(t, cmd, args, kvs{}, words{}, true)
}

test := func(args string, expectedOpts kvs, expectedWords words) {
testHelper(args, expectedOpts, expectedWords, false)
testOptionHelper(t, cmd, args, expectedOpts, expectedWords, false)
}

test("test -", kvs{}, words{"-"})
@@ -154,6 +155,13 @@ func TestOptionParsing(t *testing.T) {
test("-b --string foo test bar", kvs{"bool": true, "string": "foo"}, words{"bar"})
test("-b=false --string bar", kvs{"bool": false, "string": "bar"}, words{})
test("--strings a --strings b", kvs{"strings": []string{"a", "b"}}, words{})

test("--delimstrings a,b", kvs{"delimstrings": []string{"a", "b"}}, words{})
test("--delimstrings=a,b", kvs{"delimstrings": []string{"a", "b"}}, words{})
test("-d a,b", kvs{"delimstrings": []string{"a", "b"}}, words{})
test("-d=a,b", kvs{"delimstrings": []string{"a", "b"}}, words{})
test("-d=a,b -d c --delimstrings d", kvs{"delimstrings": []string{"a", "b", "c", "d"}}, words{})

testFail("foo test")
test("defaults", kvs{"opt": "def"}, words{})
test("defaults -o foo", kvs{"opt": "foo"}, words{})
@@ -170,6 +178,148 @@ func TestOptionParsing(t *testing.T) {
testFail("-zz--- --")
}

func TestDefaultOptionParsing(t *testing.T) {
testPanic := func(f func()) {
fnFinished := false
defer func() {
if r := recover(); fnFinished == true {
panic(r)
}
}()
f()
fnFinished = true
t.Error("expected panic")
}

testPanic(func() { cmds.StringOption("string", "s", "a string").WithDefault(0) })
testPanic(func() { cmds.StringOption("string", "s", "a string").WithDefault(false) })
testPanic(func() { cmds.StringOption("string", "s", "a string").WithDefault(nil) })
testPanic(func() { cmds.StringOption("string", "s", "a string").WithDefault([]string{"foo"}) })
testPanic(func() { cmds.StringsOption("strings", "a", "a string array").WithDefault(0) })
testPanic(func() { cmds.StringsOption("strings", "a", "a string array").WithDefault(false) })
testPanic(func() { cmds.StringsOption("strings", "a", "a string array").WithDefault(nil) })
testPanic(func() { cmds.StringsOption("strings", "a", "a string array").WithDefault("foo") })
testPanic(func() { cmds.StringsOption("strings", "a", "a string array").WithDefault([]bool{false}) })
testPanic(func() { cmds.DelimitedStringsOption(",", "dstrings", "d", "delimited string array").WithDefault(0) })
testPanic(func() { cmds.DelimitedStringsOption(",", "dstrs", "d", "delimited string array").WithDefault(false) })
testPanic(func() { cmds.DelimitedStringsOption(",", "dstrings", "d", "delimited string array").WithDefault(nil) })
testPanic(func() { cmds.DelimitedStringsOption(",", "dstrs", "d", "delimited string array").WithDefault("foo") })
testPanic(func() { cmds.DelimitedStringsOption(",", "dstrs", "d", "delimited string array").WithDefault([]int{0}) })

testPanic(func() { cmds.BoolOption("bool", "b", "a bool").WithDefault(0) })
testPanic(func() { cmds.BoolOption("bool", "b", "a bool").WithDefault(1) })
testPanic(func() { cmds.BoolOption("bool", "b", "a bool").WithDefault(nil) })
testPanic(func() { cmds.BoolOption("bool", "b", "a bool").WithDefault([]bool{false}) })
testPanic(func() { cmds.BoolOption("bool", "b", "a bool").WithDefault([]string{"foo"}) })

testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault(int(0)) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault(int32(0)) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault(int64(0)) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault(uint64(0)) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault(uint32(0)) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault(float32(0)) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault(float64(0)) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault(nil) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault([]uint{0}) })
testPanic(func() { cmds.UintOption("uint", "u", "a uint").WithDefault([]string{"foo"}) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(int(0)) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(int32(0)) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(int64(0)) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(uint(0)) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(uint32(0)) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(float32(0)) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(float64(0)) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(nil) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault([]uint64{0}) })
testPanic(func() { cmds.Uint64Option("uint64", "v", "a uint64").WithDefault([]string{"foo"}) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault(int32(0)) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault(int64(0)) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault(uint(0)) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault(uint32(0)) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault(uint64(0)) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault(float32(0)) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault(float64(0)) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault(nil) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault([]int{0}) })
testPanic(func() { cmds.IntOption("int", "i", "an int").WithDefault([]string{"foo"}) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault(int(0)) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault(int32(0)) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault(uint(0)) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault(uint32(0)) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault(uint64(0)) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault(float32(0)) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault(float64(0)) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault(nil) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault([]int64{0}) })
testPanic(func() { cmds.Int64Option("int64", "j", "an int64").WithDefault([]string{"foo"}) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault(int(0)) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault(int32(0)) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault(int64(0)) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault(uint(0)) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault(uint32(0)) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault(uint64(0)) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault(float32(0)) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault(nil) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault([]int{0}) })
testPanic(func() { cmds.FloatOption("float", "f", "a float64").WithDefault([]string{"foo"}) })

cmd := &cmds.Command{
Subcommands: map[string]*cmds.Command{
"defaults": &cmds.Command{
Options: []cmds.Option{
cmds.StringOption("string", "s", "a string").WithDefault("foo"),
cmds.StringsOption("strings1", "a", "a string array").WithDefault([]string{"foo"}),
cmds.StringsOption("strings2", "b", "a string array").WithDefault([]string{"foo", "bar"}),
cmds.DelimitedStringsOption(",", "dstrings1", "c", "a delimited string array").WithDefault([]string{"foo"}),
cmds.DelimitedStringsOption(",", "dstrings2", "d", "a delimited string array").WithDefault([]string{"foo", "bar"}),

cmds.BoolOption("boolT", "t", "a bool").WithDefault(true),
cmds.BoolOption("boolF", "a bool").WithDefault(false),

cmds.UintOption("uint", "u", "a uint").WithDefault(uint(1)),
cmds.Uint64Option("uint64", "v", "a uint64").WithDefault(uint64(1)),
cmds.IntOption("int", "i", "an int").WithDefault(int(1)),
cmds.Int64Option("int64", "j", "an int64").WithDefault(int64(1)),
cmds.FloatOption("float", "f", "a float64").WithDefault(float64(1)),
},
},
},
}

test := func(args string, expectedOpts kvs, expectedWords words) {
testOptionHelper(t, cmd, args, expectedOpts, expectedWords, false)
}

test("defaults", kvs{
"string": "foo",
"strings1": []string{"foo"},
"strings2": []string{"foo", "bar"},
"dstrings1": []string{"foo"},
"dstrings2": []string{"foo", "bar"},
"boolT": true,
"boolF": false,
"uint": uint(1),
"uint64": uint64(1),
"int": int(1),
"int64": int64(1),
"float": float64(1),
}, words{})
test("defaults --string baz --strings1=baz -b baz -b=foo -c=foo -d=foo,baz,bing -d=zip,zap -d=zorp -t=false --boolF -u=0 -v=10 -i=-5 -j=10 -f=-3.14", kvs{
"string": "baz",
"strings1": []string{"baz"},
"strings2": []string{"baz", "foo"},
"dstrings1": []string{"foo"},
"dstrings2": []string{"foo", "baz", "bing", "zip", "zap", "zorp"},
"boolT": false,
"boolF": true,
"uint": uint(0),
"uint64": uint64(10),
"int": int(-5),
"int64": int64(10),
"float": float64(-3.14),
}, words{})
}

func TestArgumentParsing(t *testing.T) {
rootCmd := &cmds.Command{
Subcommands: map[string]*cmds.Command{
23 changes: 9 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMGXfDk=
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg=
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/ipfs/go-ipfs-files v0.0.8 h1:8o0oFJkJ8UkO/ABl8T6ac6tKF3+NIpj67aAB6ZpusRg=
github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs=
github.com/ipfs/go-log v1.0.3 h1:Gg7SUYSZ7BrqaKMwM+hRgcAkKv4QLfzP4XPQt5Sx/OI=
github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A=
github.com/ipfs/go-log v1.0.4 h1:6nLQdX4W8P9yZZFH7mO+X/PzjN8Laozm/lMJ6esdgzY=
github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs=
github.com/ipfs/go-log/v2 v2.0.3 h1:Q2gXcBoCALyLN/pUQlz1qgu0x3uFV6FzP9oXhpfyJpc=
github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
github.com/ipfs/go-log/v2 v2.0.5 h1:fL4YI+1g5V/b1Yxr1qAiXTMg1H8z9vx/VmJxBuQMHvU=
github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
@@ -42,23 +39,19 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s=
github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo=
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d h1:2+ZP7EfsZV7Vvmx3TIqSlSzATMkTAKqM14YGFPoSKjI=
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -72,17 +65,19 @@ golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
Loading