diff --git a/.circleci/config.yml b/.circleci/config.yml index 92c1a4ca..a710b906 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,27 +2,21 @@ version: 2 jobs: build: docker: - - image: circleci/golang:1.10.3 - environment: - GOBIN: /tmp/workspace/bin - - working_directory: /go/src/github.com/tendermint/go-amino + - image: circleci/golang:1.12.0 steps: - - run: mkdir -p /tmp/workspace/bin - - run: mkdir -p /tmp/workspace/profiles - checkout - restore_cache: keys: - - v1-dep-{{ .Branch }} + - go-mod-v1-{{ checksum "go.sum" }} - run: name: test command: | export PATH="$GOBIN:$PATH" go env go version - make get_tools && make get_vendor_deps && make test + make get_tools && make && make test - save_cache: - key: v1-dep-{{ .Branch }} + key: go-mod-v1-{{ checksum "go.sum" }} paths: - - /go/pkg + - "/go/pkg/mod" diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..80bf5625 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,65 @@ +run: + deadline: 1m + +linters: + enable-all: true + disable: + - gocyclo + - golint + - gosimple + - goimports + - unused + - govet + - deadcode + - structcheck + - maligned + - errcheck + - staticcheck + - dupl + - ineffassign + - interfacer + - unconvert + - goconst + - unparam + - nakedret + - lll + - gochecknoglobals + - gocritic + - gochecknoinits + - scopelint + - stylecheck + +# linters-settings: +# govet: +# check-shadowing: true +# golint: +# min-confidence: 0 +# gocyclo: +# min-complexity: 10 +# maligned: +# suggest-new: true +# dupl: +# threshold: 100 +# goconst: +# min-len: 2 +# min-occurrences: 2 +# depguard: +# list-type: blacklist +# packages: +# # logging is allowed only by logutils.Log, logrus +# # is allowed to use only in logutils package +# - github.com/sirupsen/logrus +# misspell: +# locale: US +# lll: +# line-length: 140 +# goimports: +# local-prefixes: github.com/golangci/golangci-lint +# gocritic: +# enabled-tags: +# - performance +# - style +# - experimental +# disabled-checks: +# - wrapperFunc +# - commentFormatting # https://github.com/go-critic/go-critic/issues/755 diff --git a/Gopkg.lock b/Gopkg.lock index 4589d933..ef498e39 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -2,46 +2,65 @@ [[projects]] + digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" name = "github.com/davecgh/go-spew" packages = ["spew"] - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" + pruneopts = "UT" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" [[projects]] + digest = "1:239c4c7fd2159585454003d9be7207167970194216193a8a210b8d29576f19c9" name = "github.com/golang/protobuf" packages = [ "proto", - "proto/proto3_proto", - "proto/test_proto", - "ptypes/any" + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp", ] - revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" - version = "v1.1.0" + pruneopts = "UT" + revision = "c823c79ea1570fb5ff454033735a8e68575d1d0f" + version = "v1.3.0" [[projects]] branch = "master" + digest = "1:3ee90c0d94da31b442dde97c99635aaafec68d0b8a3c12ee2075c6bdabeec6bb" name = "github.com/google/gofuzz" packages = ["."] + pruneopts = "UT" revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1" [[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" name = "github.com/pmezard/go-difflib" packages = ["difflib"] + pruneopts = "UT" revision = "792786c7400a136282c1664665ae0a8db921c6c2" version = "v1.0.0" [[projects]] + digest = "1:5da8ce674952566deae4dbc23d07c85caafc6cfa815b0b3e03e41979cedb8750" name = "github.com/stretchr/testify" packages = [ "assert", - "require" + "require", ] - revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" - version = "v1.2.2" + pruneopts = "UT" + revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053" + version = "v1.3.0" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "8ca44333ad8ca8f143fc1513ae309425e548d9deb7c567eb18d197a4fef9a250" + input-imports = [ + "github.com/davecgh/go-spew/spew", + "github.com/golang/protobuf/proto", + "github.com/golang/protobuf/ptypes", + "github.com/golang/protobuf/ptypes/timestamp", + "github.com/google/gofuzz", + "github.com/stretchr/testify/assert", + "github.com/stretchr/testify/require", + ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index cc862455..7d98ffaf 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -27,7 +27,7 @@ [[constraint]] name = "github.com/davecgh/go-spew" - version = "1.1.0" + version = "1.1.1" [[constraint]] branch = "master" @@ -35,7 +35,7 @@ [[constraint]] name = "github.com/stretchr/testify" - version = "1.2.1" + version = "1.3.0" [prune] go-tests = true diff --git a/Makefile b/Makefile index c322d019..04ecb907 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,8 @@ GOTOOLS = \ - github.com/golang/dep/cmd/dep \ - gopkg.in/alecthomas/gometalinter.v2 -GOTOOLS_CHECK = dep gometalinter.v2 + github.com/golangci/golangci-lint/cmd/golangci-lint +GOTOOLS_CHECK = golangci-lint -all: check_tools get_vendor_deps test metalinter +all: check_tools test ######################################## ### Build @@ -25,17 +24,11 @@ check_tools: get_tools: @echo "--> Installing tools" - go get -u -v $(GOTOOLS) - @gometalinter.v2 --install + go get -v $(GOTOOLS) update_tools: @echo "--> Updating tools" - @go get -u $(GOTOOLS) - -get_vendor_deps: - @rm -rf vendor/ - @echo "--> Running dep ensure" - @dep ensure + @go get -u -v $(GOTOOLS) ######################################## @@ -66,46 +59,12 @@ gofuzz_json: fmt: @go fmt ./... -metalinter: - @echo "==> Running linter" - gometalinter.v2 --vendor --deadline=600s --disable-all \ - --enable=deadcode \ - --enable=goconst \ - --enable=goimports \ - --enable=gosimple \ - --enable=ineffassign \ - --enable=megacheck \ - --enable=misspell \ - --enable=staticcheck \ - --enable=safesql \ - --enable=structcheck \ - --enable=unconvert \ - --enable=unused \ - --enable=varcheck \ - --enable=vetshadow \ - ./... - - #--enable=maligned \ - #--enable=gas \ - #--enable=aligncheck \ - #--enable=dupl \ - #--enable=errcheck \ - #--enable=gocyclo \ - #--enable=golint \ <== comments on anything exported - #--enable=gotype \ - #--enable=interfacer \ - #--enable=unparam \ - #--enable=vet \ - -metalinter_all: - protoc $(INCLUDE) --lint_out=. types/*.proto - gometalinter.v2 --vendor --deadline=600s --enable-all --disable=lll ./... - - -test_golang1.10rc: - docker run -it -v "$(CURDIR):/go/src/github.com/tendermint/go-amino" -w "/go/src/github.com/tendermint/go-amino" golang:1.10-rc /bin/bash -ci "make get_tools all" +# look into .golangci.yml for enabling / disabling linters +lint: + @echo "--> Running linter" + @golangci-lint run # To avoid unintended conflicts with file names, always add to .PHONY # unless there is a reason not to. # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: build install check_tools get_tools update_tools get_vendor_deps test fmt metalinter metalinter_all +.PHONY: build install check_tools get_tools fmt lint test diff --git a/binary_test.go b/binary_test.go index 077b96e6..2dfee79f 100644 --- a/binary_test.go +++ b/binary_test.go @@ -204,7 +204,7 @@ func TestStructPointerSlice1(t *testing.T) { var f3 = Foo{ A: "k", B: 2, - C: []*Foo{&Foo{}, &Foo{}, &Foo{}}, + C: []*Foo{{}, {}, {}}, D: "j", } bz2, err := cdc.MarshalBinaryLengthPrefixed(f3) @@ -232,7 +232,7 @@ func TestStructPointerSlice2(t *testing.T) { bz, err := cdc.MarshalBinaryLengthPrefixed(f) assert.Error(t, err, "nil elements of a slice/array not supported when empty_elements field tag set.") - f.C = []*Foo{&Foo{}, &Foo{}, &Foo{}} + f.C = []*Foo{{}, {}, {}} bz, err = cdc.MarshalBinaryLengthPrefixed(f) assert.NoError(t, err) diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..299e8eec --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module github.com/tendermint/go-amino + +go 1.12 + +require ( + github.com/davecgh/go-spew v1.1.1 + github.com/golang/protobuf v1.3.0 + github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf + github.com/stretchr/testify v1.3.0 + golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..93686c0d --- /dev/null +++ b/go.sum @@ -0,0 +1,18 @@ +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/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= diff --git a/json_test.go b/json_test.go index 90bc11f3..e4cdae28 100644 --- a/json_test.go +++ b/json_test.go @@ -173,32 +173,33 @@ type innerFP struct { func TestUnmarshalMap(t *testing.T) { binBytes := []byte(`dontcare`) - jsonBytes := []byte(`{"2": 2}`) obj := new(map[string]int) cdc := amino.NewCodec() // Binary doesn't support decoding to a map... + // TODO: move out binary tests from json_test.go ... assert.Panics(t, func() { - err := cdc.UnmarshalBinaryLengthPrefixed(binBytes, &obj) + err := cdc.UnmarshalBinaryBare(binBytes, &obj) assert.Fail(t, "should have paniced but got err: %v", err) }) assert.Panics(t, func() { - err := cdc.UnmarshalBinaryLengthPrefixed(binBytes, obj) + err := cdc.UnmarshalBinaryBare(binBytes, obj) assert.Fail(t, "should have paniced but got err: %v", err) }) // ... nor encoding it. assert.Panics(t, func() { - bz, err := cdc.MarshalBinaryLengthPrefixed(obj) + bz, err := cdc.MarshalBinaryBare(obj) assert.Fail(t, "should have paniced but got bz: %X err: %v", bz, err) }) - // JSON doesn't support decoding to a map... - assert.Panics(t, func() { - err := cdc.UnmarshalJSON(jsonBytes, &obj) - assert.Fail(t, "should have paniced but got err: %v", err) - }) - assert.Panics(t, func() { - err := cdc.UnmarshalJSON(jsonBytes, obj) - assert.Fail(t, "should have paniced but got err: %v", err) - }) + + invalidJSONMapBytes := []byte(`{"some_key": 2}`) + // we expect quoted values for javascript / JSON numbers: + err := cdc.UnmarshalJSON(invalidJSONMapBytes, &obj) + assert.Error(t, err) + + validJSONMapBytes := []byte(`{"some_key": "2"}`) + err = cdc.UnmarshalJSON(validJSONMapBytes, obj) + assert.NoError(t, err) + // ... nor encoding it. assert.Panics(t, func() { bz, err := cdc.MarshalJSON(obj) @@ -212,12 +213,18 @@ func TestUnmarshalFunc(t *testing.T) { obj := func() {} cdc := amino.NewCodec() // Binary doesn't support decoding to a func... + + err := cdc.UnmarshalBinaryLengthPrefixed(binBytes, &obj) + // on length prefixed we return an error: + assert.Error(t, err) + assert.Panics(t, func() { - err := cdc.UnmarshalBinaryLengthPrefixed(binBytes, &obj) + err := cdc.UnmarshalBinaryBare(binBytes, &obj) + // panics with "unknown field type Func" assert.Fail(t, "should have paniced but got err: %v", err) }) assert.Panics(t, func() { - err := cdc.UnmarshalBinaryLengthPrefixed(binBytes, obj) + err := cdc.UnmarshalBinaryBare(binBytes, obj) assert.Fail(t, "should have paniced but got err: %v", err) }) // ... nor encoding it. @@ -230,10 +237,11 @@ func TestUnmarshalFunc(t *testing.T) { err := cdc.UnmarshalJSON(jsonBytes, &obj) assert.Fail(t, "should have paniced but got err: %v", err) }) - assert.Panics(t, func() { - err := cdc.UnmarshalJSON(jsonBytes, obj) - assert.Fail(t, "should have paniced but got err: %v", err) - }) + + err = cdc.UnmarshalJSON(jsonBytes, obj) + // UnmarshalJSON expects a pointer + assert.Error(t, err) + // ... nor encoding it. assert.Panics(t, func() { bz, err := cdc.MarshalJSON(obj) @@ -560,7 +568,7 @@ func TestMarshalJSONMap(t *testing.T) { Map2nil: (map[string]SimpleStruct)(nil), Map2empty: map[string]SimpleStruct{}, - Map3: map[string]*SimpleStruct{"foo": &SimpleStruct{Foo: 1, Bar: []byte("bar")}}, + Map3: map[string]*SimpleStruct{"foo": {Foo: 1, Bar: []byte("bar")}}, Map3nil: (map[string]*SimpleStruct)(nil), Map3empty: map[string]*SimpleStruct{}, @@ -581,7 +589,7 @@ func TestMarshalJSONMap(t *testing.T) { Map2nil: map[string]SimpleStruct{}, Map2empty: map[string]SimpleStruct{}, - Map3: map[string]*SimpleStruct{"foo": &SimpleStruct{Foo: 1, Bar: []byte("bar")}}, + Map3: map[string]*SimpleStruct{"foo": {Foo: 1, Bar: []byte("bar")}}, Map3nil: map[string]*SimpleStruct{}, Map3empty: map[string]*SimpleStruct{}, diff --git a/reflect.go b/reflect.go index bbf35ed6..97cfeac0 100644 --- a/reflect.go +++ b/reflect.go @@ -132,7 +132,7 @@ func defaultValue(rt reflect.Type) (rv reflect.Value) { switch rt.Kind() { case reflect.Ptr: // Dereference all the way and see if it's a time type. - rt_:= rt.Elem() + rt_ := rt.Elem() for rt_.Kind() == reflect.Ptr { rt_ = rt_.Elem() } diff --git a/tests/fuzz/binary/init-corpus/main.go b/tests/fuzz/binary/init-corpus/main.go index 95dc4d29..1fba7268 100644 --- a/tests/fuzz/binary/init-corpus/main.go +++ b/tests/fuzz/binary/init-corpus/main.go @@ -58,7 +58,7 @@ func main() { UvarintAr: [4]uint64{0x99808080FFFFFF77, 0xFF0202FFFFFFFF77, 0xAE21FF0051F23F77, 0x1045880011AABBCC}, UintAr: [4]uint{0x80808080, 0x110202FF, 0xAE21FF00, 0x10458800}, StringAr: [4]string{"Tendermint", "Fuzzing", "Blue", "410DDC670CF9BFD7"}, - TimeAr: [4]time.Time{time.Time{}, time.Time{}.Add(1000 * hour * 24), time.Time{}.Add(20 * time.Minute)}, + TimeAr: [4]time.Time{{}, time.Time{}.Add(1000 * hour * 24), time.Time{}.Add(20 * time.Minute)}, } ss := tests.SlicesStruct{ @@ -67,7 +67,7 @@ func main() { Int32Sl: []int32{0x6FFFFFFF, 0x5FFFFFFF, 0x7FFFFFFF, 0x7F000000}, Int64Sl: []int64{0x6FFFFFFFFFFFF, 0x5FFFFFFFFFFFF, 0x7FFFFFFFFFFFF, 0x80808000FFFFF}, VarintSl: []int64{0x5FFFFFFFFFFFF, 0x7FFFFFFFFFFFF, 0x6FFFFFFFFFFFF, 0x80808000FFFFF}, - IntSl: []int{0x6FFFFFFF, 0x7FFFFFFF, math.MaxInt32, 0x5FFFFFFF}, + IntSl: []int{0x6FFFFFFF, 0x7FFFFFFF, math.MaxInt32, 0x5FFFFFFF}, ByteSl: []byte{0xAD, 0xBE, 0xDE, 0xEF}, Uint8Sl: []uint8{0xFF, 0x00, 0x88, 0xFF}, Uint16Sl: []uint16{0xFFFF, 0xFFFF, 0xFF00, 0x8800},