From 40885a0cafac10cacb795088a9b3a37f97fb19c2 Mon Sep 17 00:00:00 2001 From: Tomas Kocman Date: Mon, 27 Mar 2023 13:50:30 +0200 Subject: [PATCH 1/5] feat: add support for string IDs --- CHANGELOG.md | 2 ++ cmd/tea/gen_id.go | 84 ++++++++++++++++++++++++++++++++++++++++------- go.mod | 2 ++ go.sum | 2 ++ 4 files changed, 79 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0808482..b6c4b26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ How to release a new version: - Manually release new version. ## [Unreleased] +### Added +- Support for string IDs. ## [0.3.1] - 2023-02-07 ### Added diff --git a/cmd/tea/gen_id.go b/cmd/tea/gen_id.go index 26b2a86..5902b80 100644 --- a/cmd/tea/gen_id.go +++ b/cmd/tea/gen_id.go @@ -13,6 +13,7 @@ import ( cmderrors "go.strv.io/tea/pkg/errors" + mapset "github.com/deckarep/golang-set/v2" "github.com/spf13/cobra" ) @@ -62,6 +63,17 @@ type GenIDOptions struct { OutputFilePath string } +const stringTemplate = `{{ range .ids }} +func (i *{{ . }}) UnmarshalText(data []byte) error { + *i = {{ . }}(data) + return nil +} + +func (i {{ . }}) MarshalText() ([]byte, error) { + return []byte(i), nil +} +{{ end }}` + const uint64Template = ` func unmarshalUint64(i *uint64, idTypeName string, data []byte) error { l := len(data) @@ -160,6 +172,10 @@ func (i IDs) generate() ([]byte, error) { if genData, err = i.generateUUID(); err != nil { return nil, fmt.Errorf("generating uuid.UUID ids: %w", err) } + case "string": + if genData, err = i.generateStringID(); err != nil { + return nil, fmt.Errorf("generating string ids: %w", err) + } } if _, err = output.Write(genData); err != nil { @@ -214,28 +230,74 @@ func (i IDs) generateUUID() ([]byte, error) { return generatedOutput.Bytes(), nil } -func (i IDs) generateHeader() []byte { - var d []byte - d = append(d, "package id\n\n"...) - d = append(d, "import (\n"...) - d = append(d, "\t\"fmt\"\n"...) +func (i IDs) generateStringID() ([]byte, error) { + ids, ok := i["string"] + if !ok { + return nil, nil + } + + generatedOutput := &bytes.Buffer{} + data := map[string][]string{ + "ids": ids, + } + t, err := template.New("string").Parse(stringTemplate) + if err != nil { + return nil, err + } + if err = t.Execute(generatedOutput, data); err != nil { + return nil, err + } + + return generatedOutput.Bytes(), nil +} + +func (i IDs) generateHeader() []byte { + // In case of a new type, add import dependencies to standardImports and externalImports. + standardImports := mapset.NewSet[string]() + externalImports := mapset.NewSet[string]() if _, ok := i["uint64"]; ok { - d = append(d, "\t\"strconv\"\n"...) + standardImports.Append("fmt", "strconv") } if _, ok := i["uuid.UUID"]; ok { - d = append(d, "\n"...) - d = append(d, "\t\"github.com/google/uuid\"\n"...) + standardImports.Add("fmt") + externalImports.Add("github.com/google/uuid") + } + + var ( + d []byte + standardImportsLen = len(standardImports.ToSlice()) + externalImportsLen = len(externalImports.ToSlice()) + ) + + d = append(d, "package id\n"...) + if standardImportsLen == 0 && externalImportsLen == 0 { + return d + } + + d = append(d, "\nimport (\n"...) + for _, v := range standardImports.ToSlice() { + d = append(d, fmt.Sprintf("\t\"%s\"\n", v)...) + } + + if externalImportsLen == 0 { + return append(d, ")\n"...) + } + + d = append(d, "\n"...) + for _, v := range externalImports.ToSlice() { + d = append(d, fmt.Sprintf("\t\"%s\"\n", v)...) } return append(d, ")\n"...) } func supportedType(typ string) bool { - if typ != "uint64" && typ != "uuid.UUID" { - return false + switch typ { + case "uint64", "uuid.UUID", "string": + return true } - return true + return false } func extractIDs(filename string) (IDs, error) { diff --git a/go.mod b/go.mod index 8834b2f..631ce8e 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,8 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) +require github.com/deckarep/golang-set/v2 v2.3.0 // indirect + require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect diff --git a/go.sum b/go.sum index ee8fe32..4eb200a 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 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/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= +github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= From b01d13ccd07ae7d0d0a37ac8257b78445252b945 Mon Sep 17 00:00:00 2001 From: Tomas Kocman Date: Mon, 27 Mar 2023 14:05:23 +0200 Subject: [PATCH 2/5] refactor: removed useless marshalling/unmarshalling of custom IDs --- CHANGELOG.md | 3 +++ cmd/tea/gen_id.go | 20 -------------------- go.mod | 2 +- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6c4b26..c030eea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ How to release a new version: ### Added - Support for string IDs. +### Removed +- Useless marshalling/unmarshalling of custom IDs. + ## [0.3.1] - 2023-02-07 ### Added - Repo init command. diff --git a/cmd/tea/gen_id.go b/cmd/tea/gen_id.go index 5902b80..0672263 100644 --- a/cmd/tea/gen_id.go +++ b/cmd/tea/gen_id.go @@ -76,10 +76,6 @@ func (i {{ . }}) MarshalText() ([]byte, error) { const uint64Template = ` func unmarshalUint64(i *uint64, idTypeName string, data []byte) error { - l := len(data) - if l > 2 && data[0] == '"' && data[l-1] == '"' { - data = data[1 : l-1] - } uintNum, err := strconv.ParseUint(string(data), 10, 64) if err != nil { return fmt.Errorf("parsing %q id value: %w", idTypeName, err) @@ -92,17 +88,9 @@ func (i {{ . }}) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("%d", i)), nil } -func (i {{ . }}) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf("\"%d\"", i)), nil -} - func (i *{{ . }}) UnmarshalText(data []byte) error { return unmarshalUint64((*uint64)(i), "{{ . }}", data) } - -func (i *{{ . }}) UnmarshalJSON(data []byte) error { - return unmarshalUint64((*uint64)(i), "{{ . }}", data) -} {{ end }}` const uuidTemplate = ` @@ -136,18 +124,10 @@ func (i {{ . }}) MarshalText() ([]byte, error) { return []byte(uuid.UUID(i).String()), nil } -func (i {{ . }}) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf("\"%s\"", uuid.UUID(i).String())), nil -} - func (i *{{ . }}) UnmarshalText(data []byte) error { return unmarshalUUID((*uuid.UUID)(i), "{{ . }}", data) } -func (i *{{ . }}) UnmarshalJSON(data []byte) error { - return unmarshalUUID((*uuid.UUID)(i), "{{ . }}", data) -} - func (i *{{ . }}) Scan(data any) error { return scanUUID((*uuid.UUID)(i), "{{ . }}", data) } diff --git a/go.mod b/go.mod index 631ce8e..bbd677d 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) -require github.com/deckarep/golang-set/v2 v2.3.0 // indirect +require github.com/deckarep/golang-set/v2 v2.3.0 require ( github.com/Masterminds/goutils v1.1.1 // indirect From 2f12c5495bb395cc8253be23329564d35f012aa4 Mon Sep 17 00:00:00 2001 From: Tomas Kocman Date: Mon, 27 Mar 2023 14:09:12 +0200 Subject: [PATCH 3/5] chore: update Go version to 1.20 --- CHANGELOG.md | 8 +++++++- README.md | 7 ++++--- go.mod | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c030eea..95a8e22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,17 @@ How to release a new version: - Manually release new version. ## [Unreleased] + +## [0.4.0] - 2023-03-27 ### Added - Support for string IDs. ### Removed - Useless marshalling/unmarshalling of custom IDs. +### Changed +- Updated Go version to 1.20. + ## [0.3.1] - 2023-02-07 ### Added - Repo init command. @@ -41,7 +46,8 @@ How to release a new version: ### Added - Added Changelog. -[Unreleased]: https://github.com/strvcom/strv-backend-go-tea/compare/v0.3.1...HEAD +[Unreleased]: https://github.com/strvcom/strv-backend-go-tea/compare/v0.4.0...HEAD +[0.4.0]: https://github.com/strvcom/strv-backend-go-tea/compare/v0.3.1...v0.4.0 [0.3.1]: https://github.com/strvcom/strv-backend-go-tea/compare/v0.3.0...v0.3.1 [0.3.0]: https://github.com/strvcom/strv-backend-go-tea/compare/v0.2.2...v0.3.0 [0.2.2]: https://github.com/strvcom/strv-backend-go-tea/compare/v0.2.1...v0.2.2 diff --git a/README.md b/README.md index 505ea8e..26dee72 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,12 @@ import ( //go:generate tea gen id -i ./id.go -o ./id_gen.go type ( - User uint64 - RefreshToken uuid.UUID + User uint64 + RefreshToken uuid.UUID + DeviceIdentifier string ) ``` -After triggering `go generate ./...` within an app, methods `MarshalText`, `MarshalJSON`, `UnmarshalText` and `UnmarshalJSON` are generated. +After triggering `go generate ./...` within an app, methods `MarshalText` and `UnmarshalText` along with other useful functions are generated. ### openapi This command provides a set of tools to manage OpenAPI specifications. diff --git a/go.mod b/go.mod index bbd677d..bfb4c93 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module go.strv.io/tea -go 1.19 +go 1.20 require ( github.com/Masterminds/sprig/v3 v3.2.2 From 54ac41e29bacc6339a5a11a53a43abdb4d8fbc9b Mon Sep 17 00:00:00 2001 From: Tomas Kocman Date: Mon, 27 Mar 2023 14:28:04 +0200 Subject: [PATCH 4/5] ci: update github actions/workflows --- .github/actions/setup-go/action.yml | 10 +--------- .github/workflows/lint.yaml | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml index e01ef74..406a99e 100644 --- a/.github/actions/setup-go/action.yml +++ b/.github/actions/setup-go/action.yml @@ -2,11 +2,6 @@ name: Setup Go description: | Setup Go -inputs: - go-version: - description: Used Go version - default: '1.19' - runs: using: "composite" steps: @@ -18,7 +13,4 @@ runs: - id: go-setup uses: actions/setup-go@v3 with: - go-version: ${{ env.GO_VERSION }} - - run: | - go mod download - shell: bash + go-version-file: 'go.mod' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 815fd76..ac5752e 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -23,4 +23,4 @@ jobs: - name: Run golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.50.1 + version: v1.52.2 From b946ebd288cc85fa7bf9057e5bd722c006e86b44 Mon Sep 17 00:00:00 2001 From: Tomas Kocman Date: Mon, 27 Mar 2023 17:22:16 +0200 Subject: [PATCH 5/5] refactor: imports should be sorted --- cmd/tea/gen_id.go | 30 ++++++++++++++++++++---------- go.mod | 2 -- go.sum | 2 -- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/cmd/tea/gen_id.go b/cmd/tea/gen_id.go index 0672263..99e3d81 100644 --- a/cmd/tea/gen_id.go +++ b/cmd/tea/gen_id.go @@ -8,12 +8,12 @@ import ( "go/parser" "go/token" "os" + "sort" "strings" "text/template" cmderrors "go.strv.io/tea/pkg/errors" - mapset "github.com/deckarep/golang-set/v2" "github.com/spf13/cobra" ) @@ -234,20 +234,21 @@ func (i IDs) generateStringID() ([]byte, error) { func (i IDs) generateHeader() []byte { // In case of a new type, add import dependencies to standardImports and externalImports. - standardImports := mapset.NewSet[string]() - externalImports := mapset.NewSet[string]() + standardImports := make(map[string]struct{}) + externalImports := make(map[string]struct{}) if _, ok := i["uint64"]; ok { - standardImports.Append("fmt", "strconv") + standardImports["fmt"] = struct{}{} + standardImports["strconv"] = struct{}{} } if _, ok := i["uuid.UUID"]; ok { - standardImports.Add("fmt") - externalImports.Add("github.com/google/uuid") + standardImports["fmt"] = struct{}{} + externalImports["github.com/google/uuid"] = struct{}{} } var ( d []byte - standardImportsLen = len(standardImports.ToSlice()) - externalImportsLen = len(externalImports.ToSlice()) + standardImportsLen = len(standardImports) + externalImportsLen = len(externalImports) ) d = append(d, "package id\n"...) @@ -256,7 +257,7 @@ func (i IDs) generateHeader() []byte { } d = append(d, "\nimport (\n"...) - for _, v := range standardImports.ToSlice() { + for _, v := range sortedMapKeys(standardImports) { d = append(d, fmt.Sprintf("\t\"%s\"\n", v)...) } @@ -265,13 +266,22 @@ func (i IDs) generateHeader() []byte { } d = append(d, "\n"...) - for _, v := range externalImports.ToSlice() { + for _, v := range sortedMapKeys(externalImports) { d = append(d, fmt.Sprintf("\t\"%s\"\n", v)...) } return append(d, ")\n"...) } +func sortedMapKeys[V any](m map[string]V) []string { + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + func supportedType(typ string) bool { switch typ { case "uint64", "uuid.UUID", "string": diff --git a/go.mod b/go.mod index bfb4c93..9fd0e4a 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,6 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) -require github.com/deckarep/golang-set/v2 v2.3.0 - require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect diff --git a/go.sum b/go.sum index 4eb200a..ee8fe32 100644 --- a/go.sum +++ b/go.sum @@ -63,8 +63,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 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/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= -github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=