Skip to content

Commit f79bb83

Browse files
committed
Add support for discovering all structs in a package automatically
1 parent 5257dcf commit f79bb83

4 files changed

Lines changed: 154 additions & 103 deletions

File tree

cli.go

Lines changed: 65 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,42 +39,81 @@ func NewCliApp() *cli.App {
3939
},
4040
},
4141
Action: func(c *cli.Context) error {
42-
// fully qualified type (my/pkg.MyType) where the record mapping is stored in tags
42+
// fully qualified type (my/pkg.MyType) or package where the record mapping is stored in tags
4343
mappingType := c.Args().Get(0)
44-
45-
i := strings.LastIndexByte(mappingType, '.')
46-
if i == -1 {
47-
return errors.Errorf("invalid mapping type: %q, expected fully qualified type with package and name (e.g. example.com/my/pkg.MyType)", mappingType)
48-
}
49-
mappingTypePackage := mappingType[0:i]
50-
mappingTypeName := mappingType[i+1:]
51-
52-
var targetTypeName string
53-
// Either an explicit target type name is given or it is derived from the name part of the mapping type
54-
if c.NArg() > 1 {
55-
targetTypeName = c.Args().Get(1)
56-
} else {
57-
targetTypeName = mappingTypeName
44+
mappingTypeName, mappingTypePackage, err := getPackageAndTypeName(mappingType)
45+
if err != nil {
46+
return err
5847
}
5948

6049
goPackage := c.String("go-package")
6150
goFile := c.String("go-file")
6251

63-
m, err := internal.BuildStructMapping(mappingTypePackage, mappingTypeName, targetTypeName)
64-
if err != nil {
65-
return errors.Wrap(err, "building struct mapping")
66-
}
52+
if mappingTypeName != "" {
53+
var targetTypeName string
54+
// Either an explicit target type name is given or it is derived from the name part of the mapping type
55+
if c.NArg() > 1 {
56+
targetTypeName = c.Args().Get(1)
57+
} else {
58+
targetTypeName = mappingTypeName
59+
}
6760

68-
var buf bytes.Buffer
69-
outputFilename, err := internal.Generate(m, goPackage, goFile, &buf)
70-
if err != nil {
71-
return errors.Wrap(err, "generating code")
72-
}
73-
if err := ioutil.WriteFile(outputFilename, buf.Bytes(), 0644); err != nil {
74-
return errors.Wrap(err, "writing output file")
61+
m, err := internal.BuildStructMapping(mappingTypePackage, mappingTypeName, targetTypeName)
62+
if err != nil {
63+
return errors.Wrap(err, "building struct mapping")
64+
}
65+
66+
var buf bytes.Buffer
67+
outputFilename, err := internal.Generate(m, goPackage, goFile, &buf)
68+
if err != nil {
69+
return errors.Wrap(err, "generating code")
70+
}
71+
if err := ioutil.WriteFile(outputFilename, buf.Bytes(), 0644); err != nil {
72+
return errors.Wrap(err, "writing output file")
73+
}
74+
} else {
75+
mappings, err := internal.DiscoverStructMappings(mappingTypePackage)
76+
if err != nil {
77+
return errors.Wrap(err, "discovering struct mappings")
78+
}
79+
80+
for _, m := range mappings {
81+
var buf bytes.Buffer
82+
outputFilename, err := internal.Generate(m, goPackage, goFile, &buf)
83+
if err != nil {
84+
return errors.Wrap(err, "generating code")
85+
}
86+
if err := ioutil.WriteFile(outputFilename, buf.Bytes(), 0644); err != nil {
87+
return errors.Wrap(err, "writing output file")
88+
}
89+
}
7590
}
7691

7792
return nil
7893
},
7994
}
8095
}
96+
97+
func getPackageAndTypeName(mappingType string) (string, string, error) {
98+
i := strings.LastIndexByte(mappingType, '/')
99+
if i == -1 {
100+
return "", "", errors.Errorf("invalid mapping type: %q, expected fully qualified type with package and name (e.g. example.com/my/pkg.MyType)", mappingType)
101+
}
102+
lastPackageAndTypeName := mappingType[i+1:]
103+
104+
mappingTypeName := ""
105+
mappingTypePackage := mappingType
106+
107+
// Check if last package part has a ".", if so, a type name is specified
108+
j := strings.LastIndexByte(lastPackageAndTypeName, '.')
109+
if j != -1 {
110+
// Split mappingType by last "." to get the package and the type name
111+
k := strings.LastIndexByte(mappingType, '.')
112+
mappingTypePackage = mappingType[:k]
113+
mappingTypeName = mappingType[k+1:]
114+
115+
return mappingTypeName, mappingTypePackage, nil
116+
}
117+
118+
return "", mappingType, nil
119+
}

go.mod

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
module github.com/networkteam/construct
22

3-
go 1.15
3+
go 1.18
44

55
require (
6-
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
7-
github.com/dave/jennifer v1.5.0
6+
github.com/dave/jennifer v1.5.1
87
github.com/fatih/structtag v1.2.0
98
github.com/friendsofgo/errors v0.9.2
10-
github.com/gofrs/uuid v4.2.0+incompatible
9+
github.com/gofrs/uuid v4.3.0+incompatible
1110
github.com/networkteam/go-immutable v0.1.4-0.20211222090629-91036a8e4d09
1211
github.com/stretchr/testify v1.7.0
13-
github.com/urfave/cli/v2 v2.3.0
14-
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
15-
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
16-
golang.org/x/tools v0.1.8
12+
github.com/urfave/cli/v2 v2.17.1
13+
golang.org/x/tools v0.1.12
14+
)
15+
16+
require (
17+
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
18+
github.com/davecgh/go-spew v1.1.0 // indirect
19+
github.com/pmezard/go-difflib v1.0.0 // indirect
20+
github.com/russross/blackfriday/v2 v2.1.0 // indirect
21+
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
22+
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
23+
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
24+
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
25+
gopkg.in/yaml.v3 v3.0.1 // indirect
1726
)

go.sum

Lines changed: 20 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,39 @@
1-
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2-
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
3-
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
4-
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
5-
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
6-
github.com/dave/astrid v0.0.0-20170323122508-8c2895878b14/go.mod h1:Sth2QfxfATb/nW4EsrSi2KyJmbcniZ8TgTaji17D6ms=
7-
github.com/dave/brenda v1.1.0/go.mod h1:4wCUr6gSlu5/1Tk7akE5X7UorwiQ8Rij0SKH3/BGMOM=
8-
github.com/dave/courtney v0.3.0/go.mod h1:BAv3hA06AYfNUjfjQr+5gc6vxeBVOupLqrColj+QSD8=
9-
github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ=
10-
github.com/dave/jennifer v1.4.1 h1:XyqG6cn5RQsTj3qlWQTKlRGAyrTcsk1kUmWdZBzRjDw=
11-
github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA=
12-
github.com/dave/jennifer v1.5.0 h1:HmgPN93bVDpkQyYbqhCHj5QlgvUkvEOzMyEvKLgCRrg=
13-
github.com/dave/jennifer v1.5.0/go.mod h1:4MnyiFIlZS3l5tSDn8VnzE6ffAhYBMB2SZntBsZGUok=
14-
github.com/dave/kerr v0.0.0-20170318121727-bc25dd6abe8e/go.mod h1:qZqlPyPvfsDJt+3wHJ1EvSXDuVjFTK0j2p/ca+gtsb8=
15-
github.com/dave/patsy v0.0.0-20210517141501-957256f50cba/go.mod h1:qfR88CgEGLoiqDaE+xxDCi5QA5v4vUoW0UCX2Nd5Tlc=
16-
github.com/dave/rebecca v0.9.1/go.mod h1:N6XYdMD/OKw3lkF3ywh8Z6wPGuwNFDNtWYEMFWEmXBA=
1+
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
2+
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
3+
github.com/dave/jennifer v1.5.1 h1:AI8gaM02nCYRw6/WTH0W+S6UNck9YqPZ05xoIxQtuoE=
4+
github.com/dave/jennifer v1.5.1/go.mod h1:AxTG893FiZKqxy3FP1kL80VMshSMuz2G+EgvszgGRnk=
175
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
186
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
197
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
208
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
219
github.com/friendsofgo/errors v0.9.2 h1:X6NYxef4efCBdwI7BgS820zFaN7Cphrmb+Pljdzjtgk=
2210
github.com/friendsofgo/errors v0.9.2/go.mod h1:yCvFW5AkDIL9qn7suHVLiI/gH228n7PC4Pn44IGoTOI=
23-
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
24-
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
25-
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
26-
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
11+
github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc=
12+
github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
2713
github.com/networkteam/go-immutable v0.1.4-0.20211222090629-91036a8e4d09 h1:zR2V1JjLklsk3zLp5eU1+XI05qc0FEB/kA2/+TnQavo=
2814
github.com/networkteam/go-immutable v0.1.4-0.20211222090629-91036a8e4d09/go.mod h1:2RHFJZ2nhkS3Z1UtpvkW/G6im/g3Lrpwon+M6TtAfzk=
29-
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
3015
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3116
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
32-
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
33-
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
3417
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
3518
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
36-
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
37-
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
3819
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
3920
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
4021
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
41-
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
42-
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
43-
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
44-
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
45-
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
46-
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
47-
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
48-
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
49-
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
50-
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
51-
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
52-
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
53-
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
54-
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
55-
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
56-
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
57-
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
58-
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
59-
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
60-
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
61-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
62-
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
63-
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
64-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
65-
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
66-
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
67-
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
68-
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
69-
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
70-
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
71-
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
72-
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
73-
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
74-
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
75-
golang.org/x/tools v0.0.0-20200930163820-66e72d03b26e h1:aVrms4psYTL0CrQ8G2hpFT2vKevUsWT88U0iV2+Tg8A=
76-
golang.org/x/tools v0.0.0-20200930163820-66e72d03b26e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
77-
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
78-
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
22+
github.com/urfave/cli/v2 v2.17.1 h1:UzjDEw2dJQUE3iRaiNQ1VrVFbyAtKGH3VdkMoHA58V0=
23+
github.com/urfave/cli/v2 v2.17.1/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
24+
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
25+
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
26+
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
27+
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
28+
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
29+
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
30+
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
31+
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
7932
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
80-
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
81-
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
82-
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
33+
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
34+
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
8335
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
8436
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
85-
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
86-
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
87-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
8837
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
38+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
39+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/struct_mapping.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,49 @@ func BuildStructMapping(mappingTypePackage string, mappingTypeName string, targe
7474
return nil, errors.Errorf("type %v is a %T, not a struct", obj, obj.Type().Underlying())
7575
}
7676

77+
return buildStructMapping(targetTypeName, mappingTypePackage, mappingTypeName, structType)
78+
}
79+
80+
// DiscoverStructMappings discovers all struct mappings in a given package
81+
func DiscoverStructMappings(mappingTypePackage string) (mappings []*StructMapping, err error) {
82+
cfg := &packages.Config{Mode: packages.NeedTypes | packages.NeedSyntax | packages.NeedImports}
83+
pkgs, err := packages.Load(cfg, mappingTypePackage)
84+
if err != nil {
85+
return nil, errors.Wrap(err, "loading package for type info")
86+
}
87+
88+
if len(pkgs) != 1 {
89+
return nil, errors.Errorf("expected single package after load, got %d", len(pkgs))
90+
}
91+
pkg := pkgs[0]
92+
93+
names := pkg.Types.Scope().Names()
94+
95+
for _, name := range names {
96+
obj := pkg.Types.Scope().Lookup(name)
97+
if _, ok := obj.(*types.TypeName); !ok {
98+
continue
99+
}
100+
structType, ok := obj.Type().Underlying().(*types.Struct)
101+
if !ok {
102+
continue
103+
}
104+
105+
m, err := buildStructMapping(name, mappingTypePackage, name, structType)
106+
if err != nil {
107+
return nil, errors.Wrapf(err, "building struct mapping for %s", name)
108+
}
109+
110+
// Only include mappings with read or write columns defined
111+
if m.hasColDef() {
112+
mappings = append(mappings, m)
113+
}
114+
}
115+
116+
return mappings, nil
117+
}
118+
119+
func buildStructMapping(targetTypeName, mappingTypePackage, mappingTypeName string, structType *types.Struct) (*StructMapping, error) {
77120
var m StructMapping
78121

79122
m.TargetName = targetTypeName
@@ -115,3 +158,12 @@ func BuildStructMapping(mappingTypePackage string, mappingTypeName string, targe
115158

116159
return &m, nil
117160
}
161+
162+
func (m *StructMapping) hasColDef() bool {
163+
for _, fm := range m.FieldMappings {
164+
if fm.ReadColDef != nil || fm.WriteColDef != nil {
165+
return true
166+
}
167+
}
168+
return false
169+
}

0 commit comments

Comments
 (0)