From c8fcbfb0dfa79e1d56e29068320d6090be1ce1da Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Wed, 27 Oct 2021 09:24:50 -0700 Subject: [PATCH 1/2] Migrate from Travis CI to GitHub Actions Signed-off-by: Kazuyoshi Kato --- .gitattributes | 2 ++ .github/workflows/ci.yaml | 46 +++++++++++++++++++++++++++++++++++++++ .travis.yml | 31 -------------------------- 3 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/ci.yaml delete mode 100644 .travis.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d020be8 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.go text eol=lf + diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..7d0b2c9 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,46 @@ +name: Go + +on: [push, pull_request] + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ ubuntu-latest, macos-latest, windows-latest ] + fail-fast: false + + steps: + - uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.17.1 + + - name: Setup gotestsum + uses: autero1/action-gotestsum@v1.0.0 + with: + gotestsum_version: 1.7.0 + + - name: Test + run: gotestsum --format short-verbose -- -race -timeout=20m -coverprofile=coverage_txt -covermode=atomic ./... + + - uses: codecov/codecov-action@v2 + with: + files: coverage_txt + + lint: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ ubuntu-latest, macos-latest, windows-latest ] + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - uses: golangci/golangci-lint-action@v2 + with: + args: --timeout=5m diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index eaee5b6..0000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.x -arch: -- amd64 -jobs: - include: - # only run fast tests on ppc64le - - go: 1.x - arch: ppc64le - script: - - gotestsum -f short-verbose -- ./... - - # include linting job, but only for latest go version and amd64 arch - - go: 1.x - arch: amd64 - install: - go get github.com/golangci/golangci-lint/cmd/golangci-lint - script: - - golangci-lint run --new-from-rev master - -install: -- GO111MODULE=off go get -u gotest.tools/gotestsum -language: go -notifications: - slack: - secure: zE5AtIYTpYfQPnTzP+EaQPN7JKtfFAGv6PrJqoIZLOXa8B6zGb6+J1JRNNxWi7faWbyJOxa4FSSsuPsKZMycUK6wlLFIdhDxwqeo7Ew8r6rdZKdfUHQggfNS9wO79ARoNYUDHtmnaBUS+eWSM1YqSc4i99QxyyfuURLOeAaA/q14YbdlTlaw3lrZ0qT92ot1FnVGNOx064zuHtFeUf+jAVRMZ6Q3rvqllwIlPszE6rmHGXBt2VoJxRaBetdwd7FgkcYw9FPXKHhadwC7/75ZAdmxIukhxNMw4Tr5NuPcqNcnbYLenDP7B3lssGVIrP4BRSqekS1d/tqvdvnnFWHMwrNCkSnSc065G5+qWTlXKAemIclgiXXqE2furBNLm05MDdG8fn5epS0UNarkjD+zX336RiqwBlOX4KbF+vPyqcO98CsN0lnd+H6loc9reiTHs37orFFpQ+309av9be2GGsHUsRB9ssIyrewmhAccOmkRtr2dVTZJNFQwa5Kph5TNJuTjnZEwG/xUkEX2YSfwShOsb062JWiflV6PJdnl80pc9Tn7D5sO5Bf9DbijGRJwwP+YiiJtwtr+vsvS+n4sM0b5eqm4UoRo+JJO8ffoJtHS7ItuyRbVQCwEPJ4221WLcf5PquEEDdAPwR+K4Gj8qTXqTDdxOiES1xFUKVgmzhI= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... From c984fbd4f4a1841fcba20526a1b860fae65ac5f2 Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Wed, 27 Oct 2021 09:50:05 -0700 Subject: [PATCH 2/2] Fix or workarond lint issues This change mostly fixes golangci-lint's reported issues, except for - Renaming ObjectId, since it will break existing code - MapStructureHookFunc, since I'd like to separate larger refactoring from this commit. Signed-off-by: Kazuyoshi Kato --- bson.go | 4 ++-- default_test.go | 8 +++++++ duration_test.go | 4 ++++ format.go | 59 ++++++++++++++++++++++++++---------------------- ulid.go | 8 +++++-- ulid_test.go | 2 +- 6 files changed, 53 insertions(+), 32 deletions(-) diff --git a/bson.go b/bson.go index 727647b..8740b15 100644 --- a/bson.go +++ b/bson.go @@ -39,10 +39,10 @@ func IsBSONObjectID(str string) bool { // ObjectId represents a BSON object ID (alias to go.mongodb.org/mongo-driver/bson/primitive.ObjectID) // // swagger:strfmt bsonobjectid -type ObjectId bsonprim.ObjectID +type ObjectId bsonprim.ObjectID //nolint:revive // NewObjectId creates a ObjectId from a Hex String -func NewObjectId(hex string) ObjectId { +func NewObjectId(hex string) ObjectId { //nolint:revive oid, err := bsonprim.ObjectIDFromHex(hex) if err != nil { panic(err) diff --git a/default_test.go b/default_test.go index 6b46fde..b1875c0 100644 --- a/default_test.go +++ b/default_test.go @@ -345,6 +345,8 @@ type testableFormat interface { } func testStringFormat(t *testing.T, what testableFormat, format, with string, validSamples, invalidSamples []string) { + t.Helper() + // text encoding interface b := []byte(with) err := what.UnmarshalText(b) @@ -422,6 +424,8 @@ func testStringFormat(t *testing.T, what testableFormat, format, with string, va } func resetValue(t *testing.T, format string, what encoding.TextUnmarshaler) { + t.Helper() + err := what.UnmarshalText([]byte("reset value")) assert.NoError(t, err) val := reflect.Indirect(reflect.ValueOf(what)) @@ -430,6 +434,8 @@ func resetValue(t *testing.T, format string, what encoding.TextUnmarshaler) { } func testValid(t *testing.T, name, value string) { + t.Helper() + ok := Default.Validates(name, value) if !ok { t.Errorf("expected %q of type %s to be valid", value, name) @@ -437,6 +443,8 @@ func testValid(t *testing.T, name, value string) { } func testInvalid(t *testing.T, name, value string) { + t.Helper() + ok := Default.Validates(name, value) if ok { t.Errorf("expected %q of type %s to be invalid", value, name) diff --git a/duration_test.go b/duration_test.go index dc0631a..7180cbd 100644 --- a/duration_test.go +++ b/duration_test.go @@ -75,6 +75,8 @@ func TestDuration(t *testing.T) { } func testDurationParser(t *testing.T, toParse string, expected time.Duration) { + t.Helper() + r, e := ParseDuration(toParse) assert.NoError(t, e) assert.Equal(t, expected, r) @@ -91,6 +93,8 @@ func TestIsDuration_Failed(t *testing.T) { } func testDurationSQLScanner(t *testing.T, dur time.Duration) { + t.Helper() + values := []interface{}{int64(dur), float64(dur)} for _, value := range values { var result Duration diff --git a/format.go b/format.go index 13a1626..602e478 100644 --- a/format.go +++ b/format.go @@ -93,75 +93,80 @@ func NewSeededFormats(seeds []knownFormat, normalizer NameNormalizer) Registry { } // MapStructureHookFunc is a decode hook function for mapstructure -func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc { - return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) { +func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc { //nolint:gocyclo,cyclop + return func(from reflect.Type, to reflect.Type, obj interface{}) (interface{}, error) { if from.Kind() != reflect.String { - return data, nil + return obj, nil } + data, ok := obj.(string) + if !ok { + return nil, fmt.Errorf("failed to cast %+v to string", obj) + } + for _, v := range f.data { tpe, _ := f.GetType(v.Name) if to == tpe { switch v.Name { case "date": - d, err := time.Parse(RFC3339FullDate, data.(string)) + d, err := time.Parse(RFC3339FullDate, data) if err != nil { return nil, err } return Date(d), nil case "datetime": - input := data.(string) + input := data if len(input) == 0 { return nil, fmt.Errorf("empty string is an invalid datetime format") } return ParseDateTime(input) case "duration": - dur, err := ParseDuration(data.(string)) + dur, err := ParseDuration(data) if err != nil { return nil, err } return Duration(dur), nil case "uri": - return URI(data.(string)), nil + return URI(data), nil case "email": - return Email(data.(string)), nil + return Email(data), nil case "uuid": - return UUID(data.(string)), nil + return UUID(data), nil case "uuid3": - return UUID3(data.(string)), nil + return UUID3(data), nil case "uuid4": - return UUID4(data.(string)), nil + return UUID4(data), nil case "uuid5": - return UUID5(data.(string)), nil + return UUID5(data), nil case "hostname": - return Hostname(data.(string)), nil + return Hostname(data), nil case "ipv4": - return IPv4(data.(string)), nil + return IPv4(data), nil case "ipv6": - return IPv6(data.(string)), nil + return IPv6(data), nil case "cidr": - return CIDR(data.(string)), nil + return CIDR(data), nil case "mac": - return MAC(data.(string)), nil + return MAC(data), nil case "isbn": - return ISBN(data.(string)), nil + return ISBN(data), nil case "isbn10": - return ISBN10(data.(string)), nil + return ISBN10(data), nil case "isbn13": - return ISBN13(data.(string)), nil + return ISBN13(data), nil case "creditcard": - return CreditCard(data.(string)), nil + return CreditCard(data), nil case "ssn": - return SSN(data.(string)), nil + return SSN(data), nil case "hexcolor": - return HexColor(data.(string)), nil + return HexColor(data), nil case "rgbcolor": - return RGBColor(data.(string)), nil + return RGBColor(data), nil case "byte": - return Base64(data.(string)), nil + return Base64(data), nil case "password": - return Password(data.(string)), nil + return Password(data), nil case "ulid": - ulid, err := ParseULID(data.(string)) + ulid, err := ParseULID(data) if err != nil { return nil, err } diff --git a/ulid.go b/ulid.go index 6ea2e35..4bd2ccd 100644 --- a/ulid.go +++ b/ulid.go @@ -32,7 +32,7 @@ var ( } ULIDScanDefaultFunc = func(raw interface{}) (ULID, error) { - var u ULID = NewULIDZero() + u := NewULIDZero() switch x := raw.(type) { case nil: // zerp ulid @@ -90,7 +90,11 @@ func NewULIDZero() ULID { // NewULID generates new unique ULID value and a error if any func NewULID() (u ULID, err error) { - entropy := ulidEntropyPool.Get().(io.Reader) + obj := ulidEntropyPool.Get() + entropy, ok := obj.(io.Reader) + if !ok { + return u, fmt.Errorf("failed to cast %+v to io.Reader", obj) + } id, err := ulid.New(ulid.Now(), entropy) if err != nil { diff --git a/ulid_test.go b/ulid_test.go index 71eda74..afa46b5 100644 --- a/ulid_test.go +++ b/ulid_test.go @@ -195,7 +195,7 @@ func TestFormatULID_Scan(t *testing.T) { assert.NoError(t, err) ULIDScanOverrideFunc = func(raw interface{}) (ULID, error) { - var u ULID = NewULIDZero() + u := NewULIDZero() switch x := raw.(type) { case [16]byte: return u, u.ULID.UnmarshalBinary(x[:])