From 03231a899378cc5ac504b226fb46588fba2c4370 Mon Sep 17 00:00:00 2001 From: Tiago Angelo Date: Mon, 19 Jun 2023 17:22:35 -0300 Subject: [PATCH 1/3] Upgraded dependencies to their latest versions --- go.mod | 10 +++++----- go.sum | 25 ++++++++++--------------- main.go | 7 ++++--- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 8cb4777..d8909b4 100644 --- a/go.mod +++ b/go.mod @@ -8,14 +8,14 @@ require ( github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/gookit/color v1.5.3 github.com/ku/go-change-case v0.0.1 - github.com/lmittmann/tint v0.3.2 + github.com/lmittmann/tint v0.3.4 github.com/pkg/errors v0.9.1 github.com/samber/lo v1.38.1 github.com/spf13/cobra v1.7.0 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.4 github.com/wk8/go-ordered-map/v2 v2.1.7 - golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 - golang.org/x/mod v0.10.0 + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 + golang.org/x/mod v0.11.0 ) require ( @@ -27,6 +27,6 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/sys v0.8.0 // indirect + golang.org/x/sys v0.9.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 50d951e..e357c1a 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,8 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/ku/go-change-case v0.0.1 h1:Dym6yulm/ma+XRgH1SG2CIOLk2biWpSFf6mMPtg3ic8= github.com/ku/go-change-case v0.0.1/go.mod h1:7rNOPNKPrCdjm8+iDIKgs87tZuyPJkhnStQZIOT3Pss= -github.com/lmittmann/tint v0.3.2 h1:PU2S17rAGhz5mo5shxnybv6Vwz7E08/RlOeWrwabuyg= -github.com/lmittmann/tint v0.3.2/go.mod h1:w5kXnXdS9aMMlo2eFRTyEPrSRywqAi44wbSUxIBfd38= +github.com/lmittmann/tint v0.3.4 h1:QOr2U9GKQfNsNhKPhL7PexQm0mqkRmvuy1UrZb6AidM= +github.com/lmittmann/tint v0.3.4/go.mod h1:vYasuAV5qbz2TYeUK+sj8iURGIl9T/WOlh4qzYGP16I= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -37,26 +37,21 @@ github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRM github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/wk8/go-ordered-map/v2 v2.1.7 h1:aUZ1xBMdbvY8wnNt77qqo4nyT3y0pX4Usat48Vm+hik= github.com/wk8/go-ordered-map/v2 v2.1.7/go.mod h1:9Xvgm2mV2kSq2SAm0Y608tBmu8akTzI7c2bz7/G7ZN4= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= -golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 75076c9..a69bb82 100644 --- a/main.go +++ b/main.go @@ -12,13 +12,14 @@ import ( "github.com/lmittmann/tint" "github.com/pkg/errors" "github.com/spf13/cobra" + "golang.org/x/exp/slog" + "github.com/totvs-cloud/pflagstruct/internal/code" scanfld "github.com/totvs-cloud/pflagstruct/internal/scan/fld" scanpkg "github.com/totvs-cloud/pflagstruct/internal/scan/pkg" scanproj "github.com/totvs-cloud/pflagstruct/internal/scan/proj" scanst "github.com/totvs-cloud/pflagstruct/internal/scan/st" "github.com/totvs-cloud/pflagstruct/internal/syntree" - "golang.org/x/exp/slog" ) var ( @@ -107,13 +108,13 @@ func fatal(err error) { } func main() { - options := tint.Options{TimeFormat: time.Kitchen} + options := &tint.Options{TimeFormat: time.Kitchen} if debug { options.AddSource = true options.Level = slog.LevelDebug } - slog.SetDefault(slog.New(options.NewHandler(os.Stderr))) + slog.SetDefault(slog.New(tint.NewHandler(os.Stderr, options))) cmd, err := NewCommand() if err != nil { From e2356fb1aae446d980fa3ed73338cb0986a75411 Mon Sep 17 00:00:00 2001 From: Tiago Angelo Date: Tue, 20 Jun 2023 13:56:18 -0300 Subject: [PATCH 2/3] Indicate whether the field is a pointer to an array type --- internal/code/generator.go | 2 + internal/code/methods.go | 21 ++++++-- internal/scan/fld/finder.go | 105 +++++++++++++++++++----------------- projscan/field.go | 13 ++--- 4 files changed, 82 insertions(+), 59 deletions(-) diff --git a/internal/code/generator.go b/internal/code/generator.go index 63c1ea4..632ed64 100644 --- a/internal/code/generator.go +++ b/internal/code/generator.go @@ -5,6 +5,7 @@ import ( "path" changecase "github.com/ku/go-change-case" + "github.com/totvs-cloud/pflagstruct/internal/dir" "github.com/totvs-cloud/pflagstruct/projscan" ) @@ -71,6 +72,7 @@ func (g *Generator) Generate(directory string, structName string, destination st Prefix: prefix, Struct: field.StructRef, Pointer: field.Pointer, + ArrayPointer: field.ArrayPointer, }) case FieldKindStringMap: getterMethods = append(getterMethods, &MapGetterMethod{ diff --git a/internal/code/methods.go b/internal/code/methods.go index d50575d..1e9beb1 100644 --- a/internal/code/methods.go +++ b/internal/code/methods.go @@ -107,6 +107,7 @@ type TagsGetterMethod struct { Prefix string Struct *projscan.Struct Pointer bool + ArrayPointer bool } func (t *TagsGetterMethod) MethodName() string { @@ -149,10 +150,6 @@ func (t *TagsGetterMethod) Flag() string { func (t *TagsGetterMethod) Statement() *jen.Statement { receiver := jen.Id("cf").Op("*").Id(t.FlagsBuilderName) - returns := []jen.Code{ - jen.Index().Op("*").Qual(t.Struct.Package.Path, t.Struct.Name), - jen.Error(), - } calls := []jen.Code{ jen.List(jen.Id("tagStrList"), jen.Id("err")).Op(":=").Id("cf").Dot("flags").Dot("GetStringSlice").Call(jen.Lit(t.Flag())), @@ -167,7 +164,21 @@ func (t *TagsGetterMethod) Statement() *jen.Statement { t.ResultAssignment().Values(jen.Id("Name").Op(":").Id("parts").Index(jen.Lit(0)), jen.Id("Value").Op(":").Id("parts").Index(jen.Lit(1))))), } - calls = append(calls, jen.Return().List(jen.Id("resultingTags"), jen.Nil())) + var returns []jen.Code + if !t.ArrayPointer { + returns = []jen.Code{ + jen.Index().Op("*").Qual(t.Struct.Package.Path, t.Struct.Name), + jen.Error(), + } + + calls = append(calls, jen.Return().List(jen.Id("resultingTags"), jen.Nil())) + } else { + returns = []jen.Code{ + jen.Op("*").Index().Op("*").Qual(t.Struct.Package.Path, t.Struct.Name), + jen.Error(), + } + calls = append(calls, jen.Return().List(jen.Op("&").Id("resultingTags"), jen.Nil())) + } return jen.Func().Params(receiver).Id(t.MethodName()).Params().Params(returns...).Block(calls...) } diff --git a/internal/scan/fld/finder.go b/internal/scan/fld/finder.go index a3a6ab5..08e921b 100644 --- a/internal/scan/fld/finder.go +++ b/internal/scan/fld/finder.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/pkg/errors" + "github.com/totvs-cloud/pflagstruct/internal/syntree" "github.com/totvs-cloud/pflagstruct/projscan" ) @@ -62,33 +63,36 @@ func (f *Finder) buildField(expr ast.Expr, st *projscan.Struct, proj *projscan.P case *ast.StarExpr: // it means that the field type is a pointer return f.buildField(x.X, st, proj, &projscan.Field{ - Name: field.Name, - Type: field.Type, - Doc: field.Doc, - StructRef: field.StructRef, - Pointer: true, - Array: field.Array, + Name: field.Name, + Type: field.Type, + Doc: field.Doc, + StructRef: field.StructRef, + Pointer: true, + Array: field.Array, + ArrayPointer: field.ArrayPointer, }) case *ast.ArrayType: // it means that the field type is an array return f.buildField(x.Elt, st, proj, &projscan.Field{ - Name: field.Name, - Type: field.Type, - Doc: field.Doc, - StructRef: field.StructRef, - Pointer: field.Pointer, - Array: true, + Name: field.Name, + Type: field.Type, + Doc: field.Doc, + StructRef: field.StructRef, + Pointer: false, + Array: true, + ArrayPointer: field.Pointer, }) case *ast.Ident: // it means that the field type is either a built-in type or a struct from the same package if projscan.FieldType(x.Name).IsValid() { return &projscan.Field{ - Name: field.Name, - Type: projscan.FieldType(x.Name), - Doc: field.Doc, - StructRef: field.StructRef, - Pointer: field.Pointer, - Array: field.Array, + Name: field.Name, + Type: projscan.FieldType(x.Name), + Doc: field.Doc, + StructRef: field.StructRef, + Pointer: field.Pointer, + Array: field.Array, + ArrayPointer: field.ArrayPointer, }, nil } @@ -98,12 +102,13 @@ func (f *Finder) buildField(expr ast.Expr, st *projscan.Struct, proj *projscan.P } return &projscan.Field{ - Name: field.Name, - Type: projscan.FieldType(x.Name), - Doc: field.Doc, - StructRef: structRef, - Pointer: field.Pointer, - Array: field.Array, + Name: field.Name, + Type: projscan.FieldType(x.Name), + Doc: field.Doc, + StructRef: structRef, + Pointer: field.Pointer, + Array: field.Array, + ArrayPointer: field.ArrayPointer, }, nil case *ast.SelectorExpr: // it means that the field type is a struct from another package @@ -124,47 +129,51 @@ func (f *Finder) buildField(expr ast.Expr, st *projscan.Struct, proj *projscan.P } return &projscan.Field{ - Name: field.Name, - Type: projscan.FieldType(fmt.Sprintf("%s.%s", pkg.Name, x.Sel.Name)), - Doc: field.Doc, - StructRef: structRef, - Pointer: field.Pointer, - Array: field.Array, + Name: field.Name, + Type: projscan.FieldType(fmt.Sprintf("%s.%s", pkg.Name, x.Sel.Name)), + Doc: field.Doc, + StructRef: structRef, + Pointer: field.Pointer, + Array: field.Array, + ArrayPointer: field.ArrayPointer, }, nil } case *ast.MapType: // it means that the field type is a map key, err := f.buildField(x.Key, st, proj, &projscan.Field{ - Name: field.Name, - Type: "", - Doc: field.Doc, - StructRef: nil, - Pointer: false, - Array: false, + Name: field.Name, + Type: "", + Doc: field.Doc, + StructRef: nil, + Pointer: false, + Array: false, + ArrayPointer: false, }) if err != nil { return nil, err } value, err := f.buildField(x.Value, st, proj, &projscan.Field{ - Name: field.Name, - Type: "", - Doc: field.Doc, - StructRef: nil, - Pointer: false, - Array: false, + Name: field.Name, + Type: "", + Doc: field.Doc, + StructRef: nil, + Pointer: false, + Array: false, + ArrayPointer: false, }) if err != nil { return nil, err } return &projscan.Field{ - Name: field.Name, - Type: projscan.FieldType(fmt.Sprintf("map[%s]%s", key.Type, value.Type)), - Doc: field.Doc, - StructRef: field.StructRef, - Pointer: field.Pointer, - Array: field.Array, + Name: field.Name, + Type: projscan.FieldType(fmt.Sprintf("map[%s]%s", key.Type, value.Type)), + Doc: field.Doc, + StructRef: field.StructRef, + Pointer: field.Pointer, + Array: field.Array, + ArrayPointer: field.ArrayPointer, }, nil } diff --git a/projscan/field.go b/projscan/field.go index 3673a3c..80f7d44 100644 --- a/projscan/field.go +++ b/projscan/field.go @@ -8,12 +8,13 @@ import ( // Field represents a field of a struct. type Field struct { - Name string // Name of the field - Type FieldType // Type of the field - Doc string // Documentation for the field - StructRef *Struct // Reference to the struct that contains this field - Pointer bool // Indicates whether the field is a pointer type or not - Array bool // Indicates whether the field is an array type or not + Name string // Name of the field + Type FieldType // Type of the field + Doc string // Documentation for the field + StructRef *Struct // Reference to the struct that contains this field + Pointer bool // Indicates whether the field is a pointer type or not + Array bool // Indicates whether the field is an array type or not + ArrayPointer bool // Indicates whether the field is a pointer to an array type or not } // FieldType defines the available field types in Go From bec32e592ba06931611f87a6af58d516f6d1ab2c Mon Sep 17 00:00:00 2001 From: Tiago Angelo Date: Tue, 20 Jun 2023 13:58:52 -0300 Subject: [PATCH 3/3] Appends '&' to generated code for pointer references --- internal/code/calls.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/internal/code/calls.go b/internal/code/calls.go index 88d28a8..2c33fd7 100644 --- a/internal/code/calls.go +++ b/internal/code/calls.go @@ -157,16 +157,25 @@ func (g *PointerGetterCall) Statement() *jen.Statement { switch KindOf(g.Field) { case FieldKindNative: + var assigment1, assigment2 *jen.Statement + if !g.Field.Pointer { + assigment1 = jen.Id(fieldName).Op(":").Id(flagValue) + assigment2 = jen.Id(structName).Dot(fieldName).Op("=").Id(flagValue) + } else { + assigment1 = jen.Id(fieldName).Op(":").Op("&").Id(flagValue) + assigment2 = jen.Id(structName).Dot(fieldName).Op("=").Op("&").Id(flagValue) + } + return jen.If(jen.List(jen.Id(flagValue), jen.Err()).Op(":="). Id("cf").Dot("flags").Dot(g.CobraMethod()).Call(jen.Lit(g.Flag())), jen.Err().Op("!=").Nil()). Block( jen.Return().List(returnId, jen.Qual("fmt", "Errorf").Call(jen.Lit("error retrieving \""+g.Flag()+"\" from command flags: %w"), jen.Err())), ).Else().If(g.CompareToDefaultValue(jen.Id(flagValue).Op("!=")).Op("&&").Id(structName).Op("==").Nil()). Block( - jen.Id(structName).Op("=").Op("&").Qual(g.Struct.Package.Path, g.Struct.Name).Values(jen.Id(fieldName).Op(":").Id(flagValue)), + jen.Id(structName).Op("=").Op("&").Qual(g.Struct.Package.Path, g.Struct.Name).Values(assigment1), ).Else().If(g.CompareToDefaultValue(jen.Id(flagValue).Op("!="))). Block( - jen.Id(structName).Dot(fieldName).Op("=").Id(flagValue), + assigment2, ) case FieldKindStruct, FieldKindTCloudTag, FieldKindStringMap: if g.Field.Pointer {