From ae83ce7c8d784808e59d4755e556577cc988588c Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Thu, 10 Aug 2023 21:45:24 -0700 Subject: [PATCH] fix Go struct tag parsing 304ba5de1 didn't correctly handle struct tags whose value contained a space. (My fault.) Use a proper struct tag library with a dedicated parser that handles all the edge cases. Less code, and better. --- go.mod | 1 + go.sum | 2 ++ internal/config/go_type.go | 18 ++++++++---------- .../sqlite/go/models.go | 3 +++ .../overrides_go_struct_tags/sqlite/schema.sql | 9 ++++++--- .../overrides_go_struct_tags/sqlite/sqlc.json | 4 ++++ 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index ba2ef13884..484ce95efb 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( require ( github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect + github.com/fatih/structtag v1.2.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect diff --git a/go.sum b/go.sum index 47eef02a58..5c3869e5d2 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs 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/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= diff --git a/internal/config/go_type.go b/internal/config/go_type.go index 078360e57d..14765e5f32 100644 --- a/internal/config/go_type.go +++ b/internal/config/go_type.go @@ -6,6 +6,8 @@ import ( "go/types" "regexp" "strings" + + "github.com/fatih/structtag" ) type GoType struct { @@ -171,16 +173,12 @@ type GoStructTag string // `a:"b" x:"y,z"` {"a": "b", "x": "y,z"} func (s GoStructTag) Parse() (map[string]string, error) { m := make(map[string]string) - fields := strings.Fields(string(s)) - for _, f := range fields { - k, v, ok := strings.Cut(f, ":") - if !ok { - return nil, fmt.Errorf("Failed to parse Go struct tag: no colon in field %q", f) - } - if len(v) < 2 || v[0] != '"' || v[len(v)-1] != '"' { - return nil, fmt.Errorf("Failed to parse Go struct tag: missing quotes around value in field %q", f) - } - m[k] = v[1 : len(v)-1] // trim quotes off of v + tags, err := structtag.Parse(string(s)) + if err != nil { + return nil, err + } + for _, tag := range tags.Tags() { + m[tag.Key] = tag.Value() } return m, nil } diff --git a/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/go/models.go b/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/go/models.go index 5942323c9c..bb63a04c33 100644 --- a/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/go/models.go +++ b/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/go/models.go @@ -9,14 +9,17 @@ import () type Bar struct { Other string AlsoTagged string `also:"tagged"` + Tag3 string `tag_with_space:" it's legal!"` } type Baz struct { Other string AlsoTagged string `also:"tagged"` + Tag3 string `tag_with_space:" it's legal!"` } type Foo struct { Other string Tagged string `a:"b" x:"y,z"` + Tag3 string `tag_with_space:" it's legal!"` } diff --git a/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/schema.sql b/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/schema.sql index 4d5233cc37..f908060db1 100644 --- a/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/schema.sql +++ b/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/schema.sql @@ -1,14 +1,17 @@ CREATE TABLE foo ( other text NOT NULL, - tagged text NOT NULL + tagged text NOT NULL, + tag3 text NOT NULL ); CREATE TABLE bar ( other text NOT NULL, - also_tagged text NOT NULL + also_tagged text NOT NULL, + tag3 text NOT NULL ); CREATE TABLE baz ( other text NOT NULL, - also_tagged text NOT NULL + also_tagged text NOT NULL, + tag3 text NOT NULL ); diff --git a/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/sqlc.json b/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/sqlc.json index 0be626d449..a4d54cc3df 100644 --- a/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/sqlc.json +++ b/internal/endtoend/testdata/overrides_go_struct_tags/sqlite/sqlc.json @@ -15,6 +15,10 @@ { "go_struct_tag": "also:\"tagged\"", "column": "*.also_tagged" + }, + { + "go_struct_tag": "tag_with_space:\" it's legal!\"", + "column": "*.tag3" } ] }