diff --git a/go.mod b/go.mod index a7df8be..c4a49b1 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,12 @@ module github.com/cloudquery/codegen -go 1.20 +go 1.21.1 require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/appconfiguration/armappconfiguration/v2 v2.0.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armmanagedapplications v1.1.1 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/solutions/armmanagedapplications v1.1.1 + github.com/cloudquery/plugin-sdk/v4 v4.12.0 github.com/google/go-cmp v0.5.9 github.com/invopop/jsonschema v0.11.0 github.com/jpillora/longestcommon v0.0.0-20161227235612-adb9d91ee629 @@ -17,6 +18,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect golang.org/x/net v0.15.0 // indirect diff --git a/go.sum b/go.sum index 08b31c4..5e1a9dd 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,7 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.2 h1:t5+QXLCK9SVi0PPdaY0PrFvYUo24KwA0QwxnaHRSVd4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.2/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.2 h1:uqM+VoHjVH6zdlkLF2b6O0ZANcHoj3rO0PoQ3jglUJA= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.2/go.mod h1:twTKAa1E6hLmSDjLhaCkbTMQKc7p/rNLU40rLxGEOCI= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/appconfiguration/armappconfiguration/v2 v2.0.0 h1:PWMXyUvMZxxu+7nMMEQUvhkChyyL5QHZS09l0pFFNy0= @@ -10,37 +11,57 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armmanagedapplic github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/solutions/armmanagedapplications v1.1.1 h1:hioFVSo4plF3RHTlGiTW9NSwdS8lN34yRT1QDpTgDsw= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/solutions/armmanagedapplications v1.1.1/go.mod h1:AA8RASHl5shSrLLA0/IpBbLNsoSJkjIm68X9EGDQRgo= github.com/AzureAD/microsoft-authentication-library-for-go v0.9.0 h1:UE9n9rkJF62ArLb1F3DEjRt8O3jLwMWdSoypKV4f3MU= +github.com/AzureAD/microsoft-authentication-library-for-go v0.9.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/cloudquery/plugin-sdk/v4 v4.12.0 h1:vNPptFUZYLAaG/9ktm7bnRBrR72+rN28rpPC62TSuXA= +github.com/cloudquery/plugin-sdk/v4 v4.12.0/go.mod h1:gvX/+uoZSxH+hJ/4qqE56jm6tJhJyQ+4RVroKACtkp4= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/invopop/jsonschema v0.11.0 h1:tdAVvos5ttrsYLyEuVymkVVK31EFpwnTu5hWiyYLGWA= github.com/invopop/jsonschema v0.11.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/longestcommon v0.0.0-20161227235612-adb9d91ee629 h1:1dSBUfGlorLAua2CRx0zFN7kQsTpE2DQSmr7rrTNgY8= github.com/jpillora/longestcommon v0.0.0-20161227235612-adb9d91ee629/go.mod h1:mb5nS4uRANwOJSZj8rlCWAfAcGi72GGMIXx+xGOjA7M= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +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.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -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/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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/interfaces/generate.go b/interfaces/generate.go index ba5ca37..4f3d9b9 100644 --- a/interfaces/generate.go +++ b/interfaces/generate.go @@ -12,8 +12,8 @@ import ( "strings" "text/template" + "github.com/cloudquery/plugin-sdk/v4/caser" "github.com/jpillora/longestcommon" - "golang.org/x/exp/maps" ) @@ -28,6 +28,10 @@ type Options struct { // ExtraImports can add extra imports for a method ExtraImports func(reflect.Method) []string + + // SinglePackage allows to generate all passed clients into a single package. + // The clients will get their package name as prefix to the interface name (e.g., s3.Client -> S3Client) + SinglePackage string } func (o *Options) SetDefaults() { @@ -53,6 +57,12 @@ func WithExtraImports(f func(reflect.Method) []string) Option { } } +func WithSinglePackage(name string) Option { + return func(o *Options) { + o.SinglePackage = name + } +} + func getPackageNames(clientInfos []clientInfo) []string { versionPattern := regexp.MustCompile(`/v\d+$`) allImports := make([]string, len(clientInfos)) @@ -77,7 +87,7 @@ func getPackageNames(clientInfos []clientInfo) []string { return packageNames } -func getTemplateDataFromClientInfos(clientInfos []clientInfo) []serviceTemplateData { +func getTemplateDataFromClientInfos(clientInfos []clientInfo, options *Options) []serviceTemplateData { packageNames := getPackageNames(clientInfos) services := make([]serviceTemplateData, 0) serviceMap := make(map[string][]clientInfo) @@ -92,13 +102,18 @@ func getTemplateDataFromClientInfos(clientInfos []clientInfo) []serviceTemplateD for _, extraImport := range clientInfo.ExtraImports { imports[extraImport] = true } - clientsTemplateData = append(clientsTemplateData, clientTemplateData{Name: clientInfo.ClientName, Signatures: clientInfo.Signatures}) + clientsTemplateData = append(clientsTemplateData, clientInfo.templateData(len(options.SinglePackage) > 0)) } - services = append(services, serviceTemplateData{ + svc := serviceTemplateData{ PackageName: packageName, + FileName: packageName, Imports: maps.Keys(imports), Clients: clientsTemplateData, - }) + } + if len(options.SinglePackage) > 0 { + svc.PackageName = options.SinglePackage + } + services = append(services, svc) } return services } @@ -125,15 +140,14 @@ func Generate(clients []any, dir string, opts ...Option) error { return err } - services := getTemplateDataFromClientInfos(clientInfos) + services := getTemplateDataFromClientInfos(clientInfos, options) for _, service := range services { buff := bytes.Buffer{} if err := serviceTpl.Execute(&buff, service); err != nil { return fmt.Errorf("failed to execute template: %w", err) } - filePath := path.Join(dir, service.PackageName, fmt.Sprintf("%s.go", service.PackageName)) - err := formatAndWriteFile(filePath, buff) + err := formatAndWriteFile(service.getFilePath(dir), buff) if err != nil { return fmt.Errorf("failed to format and write file for service %v: %w", service, err) } @@ -208,6 +222,17 @@ type clientInfo struct { ExtraImports []string } +func (c clientInfo) templateData(singlePackageMode bool) clientTemplateData { + var packageName string + if singlePackageMode { + packageName = caser.New().ToPascal(getPackageNames([]clientInfo{c})[0]) + } + return clientTemplateData{ + Name: packageName + c.ClientName, + Signatures: c.Signatures, + } +} + type clientTemplateData struct { Name string Signatures []string @@ -215,10 +240,18 @@ type clientTemplateData struct { type serviceTemplateData struct { PackageName string + FileName string Imports []string Clients []clientTemplateData } +func (s serviceTemplateData) getFilePath(baseDir string) string { + if s.FileName == s.PackageName { + return path.Join(baseDir, s.PackageName, fmt.Sprintf("%s.go", s.PackageName)) + } + return path.Join(baseDir, fmt.Sprintf("%s.go", s.FileName)) +} + func getClientInfo(client any, opts *Options) clientInfo { v := reflect.ValueOf(client) t := v.Type() diff --git a/interfaces/templates/service.go.tpl b/interfaces/templates/service.go.tpl index 0623bd9..73a2ebd 100644 --- a/interfaces/templates/service.go.tpl +++ b/interfaces/templates/service.go.tpl @@ -8,7 +8,7 @@ import ( ) {{ range .Clients }} -//go:generate mockgen -package=mocks -destination=../mocks/{{$.PackageName}}.go -source={{$.PackageName}}.go {{.Name}} +//go:generate mockgen -package=mocks -destination=../mocks/{{$.FileName}}.go -source={{$.FileName}}.go {{.Name}} type {{.Name}} interface { {{- range $sig := .Signatures }} {{ $sig }}