Skip to content

Commit

Permalink
Merge pull request #21333 from hashicorp/sp-make-gen
Browse files Browse the repository at this point in the history
fix: adjust generators directives with bool flags and add conditional logic for header template
  • Loading branch information
anGie44 authored Oct 18, 2021
2 parents ac86cad + 0b90b1c commit 34d89a5
Show file tree
Hide file tree
Showing 150 changed files with 230 additions and 192 deletions.
10 changes: 5 additions & 5 deletions docs/contributing/contribution-checklists.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,17 +269,17 @@ More details about this code generation, including fixes for potential error mes
- Open the AWS Go SDK documentation for the service, e.g., for [`service/eks`](https://docs.aws.amazon.com/sdk-for-go/api/service/eks/). Note: there can be a delay between the AWS announcement and the updated AWS Go SDK documentation.
- Use the AWS Go SDK to determine which types of tagging code to generate. There are three main types of tagging code you can generate: service tags, list tags, and update tags. These are not mutually exclusive and some services use more than one.
- Determine if a service already has a `generate.go` file (e.g., `internal/service/eks/generate.go`). If none exists, follow the example of other `generate.go` files in many other services. This is a very simple file, perhaps 3-5 lines long, and must _only_ contain generate directives at the very top of the file and a package declaration (e.g., `package eks`) -- _nothing else_.
- Check for a tagging code directive: `//go:generate go run -tags generate ../../generate/tags/main.go`. If one does not exist, add it. Note that without flags, the directive itself will not do anything useful. **WARNING:** You must never have more than one `generate/tags/main.go` directive in a `generate.go` file. Even if you want to generate all three types of tag code, you will use multiple flags but only one `generate/tags/main.go` directive! Including more than one directive will cause the generator to overwrite one set of generated code with whatever is specified in the next directive.
- Check for a tagging code directive: `//go:generate go run ../../generate/tags/main.go`. If one does not exist, add it. Note that without flags, the directive itself will not do anything useful. **WARNING:** You must never have more than one `generate/tags/main.go` directive in a `generate.go` file. Even if you want to generate all three types of tag code, you will use multiple flags but only one `generate/tags/main.go` directive! Including more than one directive will cause the generator to overwrite one set of generated code with whatever is specified in the next directive.
- If the service supports service tags, determine the service's "type" of tagging implementation. Some services will use a simple map style (`map[string]*string` in Go) while others will have a separate structure (`[]service.Tag` `struct` with `Key` and `Value` fields).

- If the type is a map, add a new flag to the tagging directive (see above): `-ServiceTagsMap=yes`. If the type is `struct`, add a `-ServiceTagsSlice=yes` flag.
- If you use the `-ServiceTagsSlice=yes` flag and if the `struct` name is not exactly `Tag`, you must include the `-TagType` flag with the name of the `struct` (e.g., `-TagType=S3Tag`). If the key and value elements of the `struct` are not exactly `Key` and `Value` respectively, you must include the `-TagTypeKeyElem` and/or `-TagTypeValElem` flags with the correct names.
- If the type is a map, add a new flag to the tagging directive (see above): `-ServiceTagsMap`. If the type is `struct`, add a `-ServiceTagsSlice` flag.
- If you use the `-ServiceTagsSlice` flag and if the `struct` name is not exactly `Tag`, you must include the `-TagType` flag with the name of the `struct` (e.g., `-TagType=S3Tag`). If the key and value elements of the `struct` are not exactly `Key` and `Value` respectively, you must include the `-TagTypeKeyElem` and/or `-TagTypeValElem` flags with the correct names.
- In summary, you may need to include one or more of the following flags with `-ServiceTagsSlice` in order to properly customize the generated code: `-TagKeyType`, `TagPackage`, `TagResTypeElem`, `TagType`, `TagType2`, `TagTypeAddBoolElem`, `TagTypeAddBoolElemSnake`, `TagTypeIDElem`, `TagTypeKeyElem`, and `TagTypeValElem`.


- If the service supports listing tags (usually a `ListTags` or `ListTagsForResource` API call), follow these guidelines.

- Add a new flag to the tagging directive (see above): `-ListTags=yes`.
- Add a new flag to the tagging directive (see above): `-ListTags`.
- If the API list operation is not exactly `ListTagsForResource`, include the `-ListTagsOp` flag with the name of the operation (e.g., `-ListTagsOp=DescribeTags`).
- If the API list tags operation identifying element is not exactly `ResourceArn`, include the `-ListTagsInIDElem` flag with the name of the element (e.g., `-ListTagsInIDElem=ResourceARN`).
- If the API list tags operation identifying element needs a slice, include the `-ListTagsInIDNeedSlice` flag with a `yes` value (e.g., `-ListTagsInIDNeedSlice=yes`).
Expand All @@ -288,7 +288,7 @@ More details about this code generation, including fixes for potential error mes

- If the service API supports updating tags (usually `TagResource` and `UntagResource` API calls), follow these guidelines.

- Add a new flag to the tagging directive (see above): `-UpdateTags=yes`.
- Add a new flag to the tagging directive (see above): `-UpdateTags`.
- If the API tag operation is not exactly `TagResource`, include the `-TagOp` flag with the name of the operation (e.g., `-TagOp=AddTags`).
- If the API untag operation is not exactly `UntagResource`, include the `-UntagOp` flag with the name of the operation (e.g., `-UntagOp=RemoveTags`).
- If the API operation identifying element is not exactly `ResourceArn`, include the `-TagInIDElem` flag with the name of the element (e.g., `-TagInIDElem=ResourceARN`).
Expand Down
4 changes: 2 additions & 2 deletions internal/generate/listpages/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const (
var (
listOps = flag.String("ListOps", "", "ListOps")
paginator = flag.String("Paginator", "NextToken", "name of the pagination token field")
export = flag.String("Export", "", "whether to export the list functions")
export = flag.Bool("Export", false, "whether to export the list functions")
)

func usage() {
Expand Down Expand Up @@ -87,7 +87,7 @@ func main() {
})

for _, functionName := range functions {
g.generateFunction(functionName, *export != "")
g.generateFunction(functionName, *export)
}

src := g.format()
Expand Down
1 change: 1 addition & 0 deletions internal/generate/tagresource/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ import (
"github.com/aws/aws-sdk-go/service/{{ .AWSService }}"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
tf{{ .ServicePackage }} "github.com/hashicorp/terraform-provider-aws/internal/service/{{ .ServicePackage }}"
Expand Down
18 changes: 9 additions & 9 deletions internal/generate/tags/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ This generator (`main.go`) generates files named `tags_gen`, such as `internal/s
Control the code generated using flags of the directives that you include in a `generate.go` file for an individual service. For example, a file such as `internal/service/ecs/generate.go` may contain three directives (and a package declaration). This generator corresponds to the `../../generate/tags/main.go` directive. (The other directives are documented in their respective packages.)

```go
//go:generate go run -tags generate ../../generate/listpages/main.go -ListOps=DescribeCapacityProviders -Export=yes
//go:generate go run -tags generate ../../generate/tagresource/main.go
//go:generate go run -tags generate ../../generate/tags/main.go -GetTag=yes -ListTags=yes -ServiceTagsSlice=yes -UpdateTags=yes
//go:generate go run ../../generate/listpages/main.go -ListOps=DescribeCapacityProviders -Export
//go:generate go run ../../generate/tagresource/main.go
//go:generate go run ../../generate/tags/main.go -GetTag -ListTags -ServiceTagsSlice -UpdateTags

package ecs
```
Expand All @@ -22,11 +22,11 @@ Some flags control generation a certain section of code, such as whether the gen

| Flag | Default | Description | Example Use |
| --- | --- | --- | --- |
| `GetTag` | | Whether to generate GetTag | `-GetTag=yes` |
| `ListTags` | | Whether to generate ListTags | `-ListTags=yes` |
| `ServiceTagsMap` | | Whether to generate map service tags (use this or `ServiceTagsSlice`, not both) | `-ServiceTagsMap=yes` |
| `ServiceTagsSlice` | | Whether to generate slice service tags (use this or `ServiceTagsMap`, not both) | `-ServiceTagsSlice=yes` |
| `UpdateTags` | | Whether to generate UpdateTags | `-UpdateTags=yes` |
| `GetTag` | | Whether to generate GetTag | `-GetTag` |
| `ListTags` | | Whether to generate ListTags | `-ListTags` |
| `ServiceTagsMap` | | Whether to generate map service tags (use this or `ServiceTagsSlice`, not both) | `-ServiceTagsMap` |
| `ServiceTagsSlice` | | Whether to generate slice service tags (use this or `ServiceTagsMap`, not both) | `-ServiceTagsSlice` |
| `UpdateTags` | | Whether to generate UpdateTags | `-UpdateTags` |
| `ListTagsInFiltIDName` | | List tags input filter identifier name | `-ListTagsInFiltIDName=resource-id` |
| `ListTagsInIDElem` | `ResourceArn` | List tags input identifier element | `-ListTagsInEDElem=ResourceARN` |
| `ListTagsInIDNeedSlice` | | Whether list tags input identifier needs a slice | `-ListTagsInIDNeedSlice=yes` |
Expand All @@ -48,7 +48,7 @@ Some flags control generation a certain section of code, such as whether the gen
| `TagTypeValElem` | `Value` | Tag type value element | `-TagTypeValElem=TagValue` |
| `UntagInCustomVal` | | Untag input custom value | `-UntagInCustomVal="&cloudfront.TagKeys{Items: aws.StringSlice(removedTags.IgnoreAWS().Keys())}"` |
| `UntagInNeedTagKeyType` | | Untag input needs tag key type | `-UntagInNeedTagKeyType=yes` |
| `UntagInNeedTagType` | | Untag input needs tag type | `-UntagInNeedTagType=yes` |
| `UntagInNeedTagType` | | Untag input needs tag type | `-UntagInNeedTagType` |
| `UntagInTagsElem` | `TagKeys` | Untag input tags element | `-UntagInTagsElem=Tags` |
| `UntagOp` | `UntagResource` | Untag operation | `-UntagOp=DeleteTags` |

Expand Down
60 changes: 46 additions & 14 deletions internal/generate/tags/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ import (
const filename = `tags_gen.go`

var (
getTag = flag.String("GetTag", "", "whether to generate GetTag")
listTags = flag.String("ListTags", "", "whether to generate ListTags")
serviceTagsMap = flag.String("ServiceTagsMap", "", "whether to generate service tags for map")
serviceTagsSlice = flag.String("ServiceTagsSlice", "", "whether to generate service tags for slice")
updateTags = flag.String("UpdateTags", "", "whether to generate UpdateTags")
getTag = flag.Bool("GetTag", false, "whether to generate GetTag")
listTags = flag.Bool("ListTags", false, "whether to generate ListTags")
serviceTagsMap = flag.Bool("ServiceTagsMap", false, "whether to generate service tags for map")
serviceTagsSlice = flag.Bool("ServiceTagsSlice", false, "whether to generate service tags for slice")
untagInNeedTagType = flag.Bool("UntagInNeedTagType", false, "whether Untag input needs tag type")
updateTags = flag.Bool("UpdateTags", false, "whether to generate UpdateTags")

listTagsInFiltIDName = flag.String("ListTagsInFiltIDName", "", "listTagsInFiltIDName")
listTagsInIDElem = flag.String("ListTagsInIDElem", "ResourceArn", "listTagsInIDElem")
Expand All @@ -45,7 +46,6 @@ var (
tagTypeValElem = flag.String("TagTypeValElem", "Value", "tagTypeValElem")
untagInCustomVal = flag.String("UntagInCustomVal", "", "untagInCustomVal")
untagInNeedTagKeyType = flag.String("UntagInNeedTagKeyType", "", "untagInNeedTagKeyType")
untagInNeedTagType = flag.String("UntagInNeedTagType", "", "untagInNeedTagType")
untagInTagsElem = flag.String("UntagInTagsElem", "TagKeys", "untagInTagsElem")
untagOp = flag.String("UntagOp", "UntagResource", "untagOp")

Expand Down Expand Up @@ -91,9 +91,16 @@ type TemplateData struct {
TagTypeValElem string
UntagInCustomVal string
UntagInNeedTagKeyType string
UntagInNeedTagType string
UntagInNeedTagType bool
UntagInTagsElem string
UntagOp string

// The following are specific to writing import paths in the `headerBody`;
// to include the package, set the corresponding field's value to true
FmtPkg bool
HelperSchemaPkg bool
StrConvPkg bool
TfResourcePkg bool
}

func main() {
Expand Down Expand Up @@ -127,6 +134,11 @@ func main() {
ClientType: clientType,
ServicePackage: servicePackage,

FmtPkg: *updateTags,
HelperSchemaPkg: awsService == "autoscaling",
StrConvPkg: awsService == "autoscaling",
TfResourcePkg: *getTag,

ListTagsInFiltIDName: *listTagsInFiltIDName,
ListTagsInIDElem: *listTagsInIDElem,
ListTagsInIDNeedSlice: *listTagsInIDNeedSlice,
Expand Down Expand Up @@ -157,27 +169,32 @@ func main() {
UntagOp: *untagOp,
}

if *getTag != "" || *listTags != "" || *serviceTagsMap != "" || *serviceTagsSlice != "" || *updateTags != "" {
if *getTag || *listTags || *serviceTagsMap || *serviceTagsSlice || *updateTags {
// If you intend to only generate Tags and KeyValueTags helper methods,
// the corresponding aws-sdk-go service package does not need to be imported
if !*getTag && !*listTags && !*serviceTagsSlice && !*updateTags {
templateData.AWSService = ""
}
writeTemplate(headerBody, "header", templateData)
}

if *getTag != "" {
if *getTag {
writeTemplate(gettagBody, "gettag", templateData)
}

if *listTags != "" {
if *listTags {
writeTemplate(listtagsBody, "listtags", templateData)
}

if *serviceTagsMap != "" {
if *serviceTagsMap {
writeTemplate(servicetagsmapBody, "servicetagsmap", templateData)
}

if *serviceTagsSlice != "" {
if *serviceTagsSlice {
writeTemplate(servicetagssliceBody, "servicetagsslice", templateData)
}

if *updateTags != "" {
if *updateTags {
writeTemplate(updatetagsBody, "updatetags", templateData)
}
}
Expand Down Expand Up @@ -220,16 +237,31 @@ var headerBody = `
package {{ .ServicePackage }}
import (
{{- if .FmtPkg }}
"fmt"
{{- end }}
{{- if .StrConvPkg }}
"strconv"
{{- end }}
"github.com/aws/aws-sdk-go/aws"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
{{- if .AWSService }}
"github.com/aws/aws-sdk-go/service/{{ .AWSService }}"
{{- if ne .AWSService .TagPackage }}
"github.com/aws/aws-sdk-go/service/{{ .TagPackage }}"
{{- end }}
{{- end }}
{{- if .HelperSchemaPkg }}
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
{{- end }}
{{- if .ParentNotFoundErrCode }}
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
{{- end }}
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
{{- if .TfResourcePkg }}
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
{{- end }}
)
`
Expand Down
2 changes: 1 addition & 1 deletion internal/service/accessanalyzer/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ServiceTagsMap=yes -UpdateTags=yes
//go:generate go run ../../generate/tags/main.go -ListTags -ServiceTagsMap -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package accessanalyzer
2 changes: 1 addition & 1 deletion internal/service/acm/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ListTagsOp=ListTagsForCertificate -ListTagsInIDElem=CertificateArn -ServiceTagsSlice=yes -TagOp=AddTagsToCertificate -TagInIDElem=CertificateArn -UntagOp=RemoveTagsFromCertificate -UntagInNeedTagType=yes -UntagInTagsElem=Tags -UpdateTags=yes
//go:generate go run ../../generate/tags/main.go -ListTags -ListTagsOp=ListTagsForCertificate -ListTagsInIDElem=CertificateArn -ServiceTagsSlice -TagOp=AddTagsToCertificate -TagInIDElem=CertificateArn -UntagOp=RemoveTagsFromCertificate -UntagInNeedTagType -UntagInTagsElem=Tags -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package acm
2 changes: 1 addition & 1 deletion internal/service/acmpca/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ListTagsOp=ListTags -ListTagsInIDElem=CertificateAuthorityArn -ServiceTagsSlice=yes -TagOp=TagCertificateAuthority -TagInIDElem=CertificateAuthorityArn -UntagOp=UntagCertificateAuthority -UntagInNeedTagType=yes -UntagInTagsElem=Tags -UpdateTags=yes
//go:generate go run ../../generate/tags/main.go -ListTags -ListTagsOp=ListTags -ListTagsInIDElem=CertificateAuthorityArn -ServiceTagsSlice -TagOp=TagCertificateAuthority -TagInIDElem=CertificateAuthorityArn -UntagOp=UntagCertificateAuthority -UntagInNeedTagType -UntagInTagsElem=Tags -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package acmpca
4 changes: 2 additions & 2 deletions internal/service/amplify/generate.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:generate go run -tags generate ../../generate/listpages/main.go -ListOps=ListApps -Export=yes
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ServiceTagsMap=yes -UpdateTags=yes
//go:generate go run ../../generate/listpages/main.go -ListOps=ListApps -Export
//go:generate go run ../../generate/tags/main.go -ListTags -ServiceTagsMap -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package amplify
2 changes: 1 addition & 1 deletion internal/service/amplify/list_pages_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/service/apigateway/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate go run -tags generate ../../generate/tags/main.go -ServiceTagsMap=yes -UpdateTags=yes
//go:generate go run ../../generate/tags/main.go -ServiceTagsMap -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package apigateway
4 changes: 2 additions & 2 deletions internal/service/apigatewayv2/generate.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:generate go run -tags generate ../../generate/listpages/main.go -ListOps=GetApis,GetDomainNames -Export=yes
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ListTagsOp=GetTags -ServiceTagsMap=yes -UpdateTags=yes
//go:generate go run ../../generate/listpages/main.go -ListOps=GetApis,GetDomainNames -Export
//go:generate go run ../../generate/tags/main.go -ListTags -ListTagsOp=GetTags -ServiceTagsMap -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package apigatewayv2
2 changes: 1 addition & 1 deletion internal/service/apigatewayv2/list_pages_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/service/appconfig/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ServiceTagsMap=yes -UpdateTags=yes
//go:generate go run ../../generate/tags/main.go -ListTags -ServiceTagsMap -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package appconfig
2 changes: 1 addition & 1 deletion internal/service/appmesh/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ServiceTagsSlice=yes -TagType=TagRef -UpdateTags=yes
//go:generate go run ../../generate/tags/main.go -ListTags -ServiceTagsSlice -TagType=TagRef -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package appmesh
2 changes: 1 addition & 1 deletion internal/service/apprunner/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ServiceTagsSlice=yes -UpdateTags=yes
//go:generate go run ../../generate/tags/main.go -ListTags -ServiceTagsSlice -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package apprunner
3 changes: 2 additions & 1 deletion internal/service/appstream/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//go:generate go run -tags generate ../../generate/tags/main.go -ListTags=yes -ServiceTagsMap=yes -UpdateTags=yes
//go:generate go run ../../generate/listpages/main.go -ListOps=DescribeFleets,DescribeImageBuilders,DescribeStacks -Export
//go:generate go run ../../generate/tags/main.go -ListTags -ServiceTagsMap -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package appstream
2 changes: 1 addition & 1 deletion internal/service/appstream/list_pages_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 34d89a5

Please sign in to comment.