diff --git a/cmd/aws-sdk-client-gen-gen/main.go b/cmd/aws-sdk-client-gen-gen/main.go index a7931cd..52b9eaf 100644 --- a/cmd/aws-sdk-client-gen-gen/main.go +++ b/cmd/aws-sdk-client-gen-gen/main.go @@ -1,47 +1,63 @@ package main import ( - "fmt" + "bytes" "log" "os" + "text/template" "github.com/goccy/go-yaml" ) +const templateStr = `// Code generated by cmd/aws-sdk-client-gen-gen/main.go; DO NOT EDIT. +package main + +import ( + "reflect" +{{ range $key, $value := .Services }} + "github.com/aws/aws-sdk-go-v2/service/{{ $key }}" +{{- end }} +) + +func generateAll() { +{{ range $key, $value := .Services }} +{{- if eq (len $value) 0 }} + gen("{{ $key }}", reflect.TypeOf({{ $key }}.New({{ $key }}.Options{})), nil) +{{- else }} + gen("{{ $key }}", reflect.TypeOf({{ $key }}.New({{ $key }}.Options{})), {{ printf "%#v" $value }}) +{{- end }} +{{ end }} +} +` + type GenerateConfig struct { Services map[string][]string `json:"services"` } func main() { log.Println("generating gen.go") - o, err := os.Create("gen.go") - if err != nil { - log.Fatalf("failed to create gen.go: %v", err) - } + f, err := os.Open("../../gen.yaml") if err != nil { log.Fatalf("failed to open gen.yaml: %v", err) } defer f.Close() + cfg := GenerateConfig{} if err := yaml.NewDecoder(f).Decode(&cfg); err != nil { log.Fatalf("failed to decode gen.yaml: %v", err) } - - fmt.Fprintln(o, "// Code generated by cmd/aws-sdk-client-gen-gen/main.go; DO NOT EDIT.") - fmt.Fprintln(o, "package main") - fmt.Fprintln(o, "import \"reflect\"") - for k := range cfg.Services { - fmt.Fprintf(o, "import \"github.com/aws/aws-sdk-go-v2/service/%s\"\n", k) + tmpl, err := template.New("gen").Parse(templateStr) + if err != nil { + log.Fatalf("failed to parse template: %v", err) + } + buf := &bytes.Buffer{} + if err := tmpl.Execute(buf, cfg); err != nil { + log.Fatalf("failed to execute template: %v", err) } - fmt.Fprintln(o, "func generateAll() {") - for k, v := range cfg.Services { - if len(v) == 0 { - fmt.Fprintf(o, " gen(\"%s\", reflect.TypeOf(%s.New(%s.Options{})), nil)\n", k, k, k) - } else { - fmt.Fprintf(o, " gen(\"%s\", reflect.TypeOf(%s.New(%s.Options{})), %#v)\n", k, k, k, v) - } + + if err := os.WriteFile("gen.go", buf.Bytes(), 0644); err != nil { + log.Fatalf("failed to write gen.go: %v", err) } - fmt.Fprintln(o, "}") log.Println("generated gen.go") } diff --git a/cmd/aws-sdk-client-gen/main.go b/cmd/aws-sdk-client-gen/main.go index 01fdebc..1fd5e0c 100644 --- a/cmd/aws-sdk-client-gen/main.go +++ b/cmd/aws-sdk-client-gen/main.go @@ -1,36 +1,57 @@ package main import ( + "bytes" "fmt" "log" "os" "reflect" "strings" + "text/template" ) //go:generate go run ../aws-sdk-client-gen-gen/main.go //go:generate go get ./... +const templateStr = `// Code generated by cmd/aws-sdk-client-gen/main.go; DO NOT EDIT. +package sdkclient + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/{{ .PkgName }}" +) + +{{ range .Methods }} +func {{ $.PkgName }}_{{ .Name }}(ctx context.Context, awsCfg aws.Config, b json.RawMessage) (any, error) { + svc := {{ $.PkgName }}.NewFromConfig(awsCfg) + var in {{ .Input }} + if err := json.Unmarshal(b, &in); err != nil { + return nil, fmt.Errorf("failed to unmarshal request: %w", err) + } + return svc.{{ .Name }}(ctx, &in) +} + +{{ end }} + +func init() { +{{- range .Methods }} + clientMethods["{{ $.PkgName }}#Client.{{ .Name }}"] = {{ $.PkgName }}_{{ .Name }} +{{- end }} +} +` + func main() { generateAll() } func gen(pkgName string, clientType reflect.Type, genNames []string) error { log.Printf("generating %s_gen.go", pkgName) - buf := &strings.Builder{} - fmt.Fprintln(buf, "// Code generated by cmd/aws-sdk-client-gen/main.go; DO NOT EDIT.") - fmt.Fprintln(buf, "package sdkclient") - fmt.Fprintln(buf) - fmt.Fprintf(buf, `import ( - "context" - "encoding/json" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/service/%s" - ) - `, pkgName) - var methodNames []string + methods := make([]map[string]string, 0) for i := 0; i < clientType.NumMethod(); i++ { method := clientType.Method(i) if len(genNames) > 0 && !contains(genNames, method.Name) { @@ -44,32 +65,27 @@ func gen(pkgName string, clientType reflect.Type, genNames []string) error { log.Printf("no params func %s", method.Name) continue } - methodNames = append(methodNames, method.Name) - log.Printf("generating %s_%s", pkgName, method.Name) - fmt.Fprintf(buf, `func %s_%s(ctx context.Context, awsCfg aws.Config, b json.RawMessage) (any, error) { - svc := %s.NewFromConfig(awsCfg) - var in %s - if err := json.Unmarshal(b, &in); err != nil { - return nil, fmt.Errorf("failed to unmarshal request: %%w", err) - } - return svc.%s(ctx, &in) - } - `, - pkgName, - method.Name, - pkgName, - strings.TrimPrefix(params[2], "*"), // (receiver, context.Context, *Request, ...) - method.Name, - ) - fmt.Fprintln(buf) + methods = append(methods, map[string]string{ + "Name": method.Name, + "Input": strings.TrimPrefix(params[2], "*"), + }) } - fmt.Fprintln(buf, `func init() {`) - for _, name := range methodNames { - fmt.Fprintf(buf, " clientMethods[\"%s#Client.%s\"] = %s_%s\n", pkgName, name, pkgName, name) + + tmpl, err := template.New("clientGen").Parse(templateStr) + if err != nil { + return fmt.Errorf("failed to parse template: %w", err) + } + + data := map[string]interface{}{ + "PkgName": pkgName, + "Methods": methods, } - fmt.Fprintln(buf, "}") - if err := os.WriteFile(pkgName+"_gen.go", []byte(buf.String()), 0644); err != nil { + buf := &bytes.Buffer{} + if err := tmpl.Execute(buf, data); err != nil { + return fmt.Errorf("failed to execute template: %w", err) + } + if err := os.WriteFile(pkgName+"_gen.go", buf.Bytes(), 0644); err != nil { return err } log.Printf("generated %s_gen.go", pkgName)