golang generates duplicate methods
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 267
- Avg merge
- 1d 25m
- Merged PRs (30d)
- 14
Description
### Describe the bug
We have an internal constructs library where we set internal best practices on top of the base constructs. Here is an example how we define our S3Bucket:
```typescript
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Bucket, BucketProps } from 'aws-cdk-lib/aws-s3';
import type { Construct } from 'constructs';
export class OurBucket extends Bucket {
public constructor(scope: Construct, id: string, bucketProps: BucketProps) {
super(scope, id, {
accessControl: bucketProps.accessControl ?? s3.BucketAccessControl.PRIVATE,
encryption: s3.BucketEncryption.S3_MANAGED,
versioned: true,
...bucketProps,
});
}
}
```
### Expected Behavior
We expect it to generate a go file with `OurBucket` where every method is defined once.
We either expect a struct like this:
```go
type OurBucket interface {
awss3.Bucket
}
```
or
```go
type OurBucket interface {
AutoCreatePolicy() *bool
SetAutoCreatePolicy(val *bool)
BucketArn() *string
BucketDomainName() *string
BucketDualStackDomainName() *string
BucketName() *string
BucketRegionalDomainName() *string
BucketWebsiteDomainName() *string
BucketWebsiteUrl() *string
DisallowPublicAccess() *bool
SetDisallowPublicAccess(val *bool)
EncryptionKey() awskms.IKey
Env() *awscdk.ResourceEnvironment
IsWebsite() *bool
Node() constructs.Node
NotificationsHandlerRole() awsiam.IRole
SetNotificationsHandlerRole(val awsiam.IRole)
PhysicalName() *string
Policy() awss3.BucketPolicy
SetPolicy(val awss3.BucketPolicy)
Stack() awscdk.Stack
AddEventNotification(event awss3.EventType, dest awss3.IBucketNotificationDestination, filters ...*awss3.NotificationKeyFilter)
AddInventory(inventory *awss3.Inventory)
AddLifecycleRule(rule *awss3.LifecycleRule)
AddMetric(metric *awss3.BucketMetrics)
AddObjectCreatedNotification(dest awss3.IBucketNotificationDestination, filters ...*awss3.NotificationKeyFilter)
AddObjectRemovedNotification(dest awss3.IBucketNotificationDestination, filters ...*awss3.NotificationKeyFilter)
AddToResourcePolicy(permission awsiam.PolicyStatement) *awsiam.AddToResourcePolicyResult
ApplyRemovalPolicy(policy awscdk.RemovalPolicy)
ArnForObjects(keyPattern *string) *string
EnableEventBridgeNotification()
GeneratePhysicalName() *string
GetResourceArnAttribute(arnAttr *string, arnComponents *awscdk.ArnComponents) *string
GetResourceNameAttribute(nameAttr *string) *string
GrantDelete(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
GrantPublicAccess(keyPrefix *string, allowedActions ...*string) awsiam.Grant
GrantPut(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
GrantPutAcl(identity awsiam.IGrantable, objectsKeyPattern *string) awsiam.Grant
GrantRead(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
GrantReadWrite(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
GrantWrite(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
OnCloudTrailEvent(id *string, options *awss3.OnCloudTrailBucketEventOptions) awsevents.Rule
OnCloudTrailPutObject(id *string, options *awss3.OnCloudTrailBucketEventOptions) awsevents.Rule
OnCloudTrailWriteObject(id *string, options *awss3.OnCloudTrailBucketEventOptions) awsevents.Rule
ToString() *string
UrlForObject(key *string) *string
VirtualHostedUrlForObject(key *string, options *awss3.VirtualHostedStyleUrlOptions) *string
}
### Current Behavior
Instead we get this kind of struct in go (without all the comments):
```go
type OurBucket interface {
awss3.Bucket
AutoCreatePolicy() *bool
SetAutoCreatePolicy(val *bool)
BucketArn() *string
BucketDomainName() *string
BucketDualStackDomainName() *string
BucketName() *string
BucketRegionalDomainName() *string
BucketWebsiteDomainName() *string
BucketWebsiteUrl() *string
DisallowPublicAccess() *bool
SetDisallowPublicAccess(val *bool)
EncryptionKey() awskms.IKey
Env() *awscdk.ResourceEnvironment
IsWebsite() *bool
Node() constructs.Node
NotificationsHandlerRole() awsiam.IRole
SetNotificationsHandlerRole(val awsiam.IRole)
PhysicalName() *string
Policy() awss3.BucketPolicy
SetPolicy(val awss3.BucketPolicy)
Stack() awscdk.Stack
AddEventNotification(event awss3.EventType, dest awss3.IBucketNotificationDestination, filters ...*awss3.NotificationKeyFilter)
AddInventory(inventory *awss3.Inventory)
AddLifecycleRule(rule *awss3.LifecycleRule)
AddMetric(metric *awss3.BucketMetrics)
AddObjectCreatedNotification(dest awss3.IBucketNotificationDestination, filters ...*awss3.NotificationKeyFilter)
AddObjectRemovedNotification(dest awss3.IBucketNotificationDestination, filters ...*awss3.NotificationKeyFilter)
AddToResourcePolicy(permission awsiam.PolicyStatement) *awsiam.AddToResourcePolicyResult
ApplyRemovalPolicy(policy awscdk.RemovalPolicy)
ArnForObjects(keyPattern *string) *string
EnableEventBridgeNotification()
GeneratePhysicalName() *string
GetResourceArnAttribute(arnAttr *string, arnComponents *awscdk.ArnComponents) *string
GetResourceNameAttribute(nameAttr *string) *string
GrantDelete(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
GrantPublicAccess(keyPrefix *string, allowedActions ...*string) awsiam.Grant
GrantPut(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
GrantPutAcl(identity awsiam.IGrantable, objectsKeyPattern *string) awsiam.Grant
GrantRead(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
GrantReadWrite(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
GrantWrite(identity awsiam.IGrantable, objectsKeyPattern interface{}) awsiam.Grant
OnCloudTrailEvent(id *string, options *awss3.OnCloudTrailBucketEventOptions) awsevents.Rule
OnCloudTrailPutObject(id *string, options *awss3.OnCloudTrailBucketEventOptions) awsevents.Rule
OnCloudTrailWriteObject(id *string, options *awss3.OnCloudTrailBucketEventOptions) awsevents.Rule
ToString() *string
UrlForObject(key *string) *string
VirtualHostedUrlForObject(key *string, options *awss3.VirtualHostedStyleUrlOptions) *string
}
```
and when we try to use the generated go library we get for example this error:
```
# github.com/our-org/our-cdk-construct-library-go/ourcdk/v2
vendor/github.com/our-org/our-cdk-construct-library-go/ourcdk/v2/ourcdk_OurBucket.go:18:2: duplicate method GrantWrite
vendor/github.com/our-org/our-cdk-construct-library-go/ourcdk/v2/ourcdk_OurBucket.go:223:2: other declaration of GrantWrite
```
because once all the methods are defined by importing the parent type `awss3.Bucket` and then all methods are defined a second time in the type itself.
### Reproduction Steps
This is our jsii config snippet to generate go:
```go
"jsii": {
"outdir": "dist",
"targets": {
"go": {
"moduleName": "github.com/our-org/our-cdk-construct-library-go",
"packageName": "ourcdk"
}
}
},
```
### Possible Solution
I'm not sure if this is a bug or if we do a mistake in how we use jsii. So maybe there is another way how we should code these constructs, so that they generate correct go code. But the currently produced go code doesn't seem to be the expected result.
Thanks already for looking into this and for any kind of guidance :pray:
### Additional Information/Context
_No response_
### SDK version used
1.79.0
### Environment details (OS name and version, etc.)
Linux
Contributor guide
Research direction
Start by reproducing the issue with the jsii configuration in the report and inspect the generated ourcdk_OurBucket.go file. Compare the embedded awss3.Bucket methods with the repeated declarations, then verify that the generated Go package compiles without duplicate-method errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100