From 6c9b1d42bc152932be6ab24576a6458e97d401cd Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Sat, 18 May 2024 16:13:09 +0900 Subject: [PATCH 1/3] set Reader to Body --- cmd/aws-sdk-client-gen/main.go | 8 ++++++- main.go | 43 ++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/cmd/aws-sdk-client-gen/main.go b/cmd/aws-sdk-client-gen/main.go index 1fd5e0c..c728c71 100644 --- a/cmd/aws-sdk-client-gen/main.go +++ b/cmd/aws-sdk-client-gen/main.go @@ -20,15 +20,21 @@ import ( "context" "encoding/json" "fmt" + "io" "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) { +func {{ $.PkgName }}_{{ .Name }}(ctx context.Context, awsCfg aws.Config, b json.RawMessage, fin io.Reader) (any, error) { svc := {{ $.PkgName }}.NewFromConfig(awsCfg) var in {{ .Input }} + if fin != nil { + if err := bindBody(&in, fin); err != nil { + return nil, fmt.Errorf("failed to bind reader to request: %w", err) + } + } if err := json.Unmarshal(b, &in); err != nil { return nil, fmt.Errorf("failed to unmarshal request: %w", err) } diff --git a/main.go b/main.go index 568aed8..c3b2c6a 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,9 @@ import ( "encoding/json" "fmt" "io" + "net/http" "os" + "reflect" "sort" "strings" @@ -20,7 +22,7 @@ var Version = "HEAD" var clientMethods = make(map[string]ClientMethod) -type ClientMethod func(context.Context, aws.Config, json.RawMessage) (any, error) +type ClientMethod func(context.Context, aws.Config, json.RawMessage, io.Reader) (any, error) type CLI struct { Service string `arg:"" help:"service name" default:""` @@ -75,7 +77,7 @@ func (c *CLI) CallMethod(ctx context.Context) error { if err != nil { return err } - out, err := fn(ctx, awsCfg, json.RawMessage(c.Input)) + out, err := fn(ctx, awsCfg, json.RawMessage(c.Input), os.Stdin) if err != nil { return err } @@ -157,4 +159,41 @@ func kebabToCamel(kebab string) string { return strings.Join(results, "") } +func bindBody(v any, fin io.Reader) error { + st := reflect.ValueOf(v).Elem() + fBody := st.FieldByName("Body") + if !fBody.IsValid() { + return nil + } + fContentLength := st.FieldByName("ContentLength") + if !fContentLength.IsValid() { + return nil + } + fContentType := st.FieldByName("ContentType") + if !fContentType.IsValid() { + return nil + } + + if fBody.Type().String() != "io.Reader" { + return nil + } + if fContentLength.Type().String() != "*int64" { + return nil + } + if fContentType.Type().String() != "*string" { + return nil + } + b, err := io.ReadAll(fin) + if err != nil { + return err + } + fBody.Set(reflect.ValueOf(bytes.NewReader(b))) + contentLength := int64(len(b)) + fContentLength.Set(reflect.ValueOf(&contentLength)) + contentType := http.DetectContentType(b) + fContentType.Set(reflect.ValueOf(&contentType)) + + return nil +} + //go:generate go run cmd/aws-sdk-client-gen/main.go cmd/aws-sdk-client-gen/gen.go From a5029e0b51d7fadba9b8ce0a5aada73a208599a4 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Sat, 18 May 2024 16:17:03 +0900 Subject: [PATCH 2/3] more shortly --- go.mod | 10 +++++++--- go.sum | 20 ++++++++++++++------ main.go | 15 +++------------ 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 3e6ab3a..c3cc814 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,21 @@ go 1.21.0 require ( github.com/alecthomas/kong v0.9.0 - github.com/aws/aws-sdk-go-v2 v1.26.1 + github.com/aws/aws-sdk-go-v2 v1.27.0 github.com/aws/aws-sdk-go-v2/config v1.27.11 + github.com/aws/aws-sdk-go-v2/service/ecs v1.41.10 + github.com/aws/aws-sdk-go-v2/service/firehose v1.28.9 + github.com/aws/aws-sdk-go-v2/service/kinesis v1.27.7 github.com/goccy/go-yaml v1.11.3 github.com/jmespath/go-jmespath v0.4.0 ) require ( + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.11 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 // indirect diff --git a/go.sum b/go.sum index 0934db8..a1e809c 100644 --- a/go.sum +++ b/go.sum @@ -4,24 +4,32 @@ github.com/alecthomas/kong v0.9.0 h1:G5diXxc85KvoV2f0ZRVuMsi45IrBgx9zDNGNj165aPA github.com/alecthomas/kong v0.9.0/go.mod h1:Y47y5gKfHp1hDc7CH7OeXgLIpp+Q2m1Ni0L5s3bI8Os= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= -github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= +github.com/aws/aws-sdk-go-v2 v1.27.0 h1:7bZWKoXhzI+mMR/HjdMx8ZCC5+6fY0lS5tr0bbgiLlo= +github.com/aws/aws-sdk-go-v2 v1.27.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2/go.mod h1:lPprDr1e6cJdyYeGXnRaJoP4Md+cDBvi2eOj00BlGmg= github.com/aws/aws-sdk-go-v2/config v1.27.11 h1:f47rANd2LQEYHda2ddSCKYId18/8BhSRM4BULGmfgNA= github.com/aws/aws-sdk-go-v2/config v1.27.11/go.mod h1:SMsV78RIOYdve1vf36z8LmnszlRWkwMQtomCAI0/mIE= github.com/aws/aws-sdk-go-v2/credentials v1.17.11 h1:YuIB1dJNf1Re822rriUOTxopaHHvIq0l/pX3fwO+Tzs= github.com/aws/aws-sdk-go-v2/credentials v1.17.11/go.mod h1:AQtFPsDH9bI2O+71anW6EKL+NcD7LG3dpKGMV4SShgo= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 h1:FVJ0r5XTHSmIHJV6KuDmdYhEpvlHpiSd38RQWhut5J4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1/go.mod h1:zusuAeqezXzAB24LGuzuekqMAEgWkVYukBec3kr3jUg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 h1:lf/8VTF2cM+N4SLzaYJERKEWAXq8MOMpZfU6wEPWsPk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7/go.mod h1:4SjkU7QiqK2M9oozyMzfZ/23LmUY+h3oFqhdeP5OMiI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 h1:4OYVp0705xu8yjdyoWix0r9wPIRXnIzzOoUpQVHIJ/g= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7/go.mod h1:vd7ESTEvI76T2Na050gODNmNU7+OyKrIKroYTu4ABiI= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= +github.com/aws/aws-sdk-go-v2/service/ecs v1.41.10 h1:hdACUSUHlhnWwtPk8IGRCfkMhtxjk2AII1B5AuAYryc= +github.com/aws/aws-sdk-go-v2/service/ecs v1.41.10/go.mod h1:ixRB9qcKi35waDtPb6uw31Eb7Df+MOcjtpWxxPO5XvI= +github.com/aws/aws-sdk-go-v2/service/firehose v1.28.9 h1:kxjpxgqndr2SC5ImyAve/NMktbjwMh8zaucXF0S1igY= +github.com/aws/aws-sdk-go-v2/service/firehose v1.28.9/go.mod h1:OR8yuOpz93vNK/cSUQLUWGU5N1uDYoevC6YM5dxbjkM= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk= +github.com/aws/aws-sdk-go-v2/service/kinesis v1.27.7 h1:eTLhZSlnfVg9tCeMST7Fw7Nr3BCB+ChBSWfr4f2edEQ= +github.com/aws/aws-sdk-go-v2/service/kinesis v1.27.7/go.mod h1:YxRRhvHMl4YR2OZR3369QQUc2iLqTc3KUCv9ayD8758= github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 h1:vN8hEbpRnL7+Hopy9dzmRle1xmDc7o8tmY0klsr175w= github.com/aws/aws-sdk-go-v2/service/sso v1.20.5/go.mod h1:qGzynb/msuZIE8I75DVRCUXw3o3ZyBmUvMwQ2t/BrGM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 h1:Jux+gDDyi1Lruk+KHF91tK2KCuY61kzoCpvtvJJBtOE= diff --git a/main.go b/main.go index c3b2c6a..748e592 100644 --- a/main.go +++ b/main.go @@ -162,27 +162,18 @@ func kebabToCamel(kebab string) string { func bindBody(v any, fin io.Reader) error { st := reflect.ValueOf(v).Elem() fBody := st.FieldByName("Body") - if !fBody.IsValid() { + if !fBody.IsValid() || fBody.Type().String() != "io.Reader" { return nil } fContentLength := st.FieldByName("ContentLength") - if !fContentLength.IsValid() { + if !fContentLength.IsValid() || fContentLength.Type().String() != "*int64" { return nil } fContentType := st.FieldByName("ContentType") - if !fContentType.IsValid() { + if !fContentType.IsValid() || fContentType.Type().String() != "*string" { return nil } - if fBody.Type().String() != "io.Reader" { - return nil - } - if fContentLength.Type().String() != "*int64" { - return nil - } - if fContentType.Type().String() != "*string" { - return nil - } b, err := io.ReadAll(fin) if err != nil { return err From 233b69a690870e1baca879c5f00713ab48641fe4 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Sat, 18 May 2024 18:15:48 +0900 Subject: [PATCH 3/3] fix tests --- cli_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cli_test.go b/cli_test.go index 8862725..fb54cfc 100644 --- a/cli_test.go +++ b/cli_test.go @@ -13,19 +13,19 @@ import ( ) func init() { - sdkclient.SetClientMethod("foo#Client.List", func(_ context.Context, _ aws.Config, _ json.RawMessage) (any, error) { + sdkclient.SetClientMethod("foo#Client.List", func(_ context.Context, _ aws.Config, _ json.RawMessage, _ io.Reader) (any, error) { return []string{"a", "b", "c"}, nil }) - sdkclient.SetClientMethod("foo#Client.Get", func(_ context.Context, _ aws.Config, _ json.RawMessage) (any, error) { + sdkclient.SetClientMethod("foo#Client.Get", func(_ context.Context, _ aws.Config, _ json.RawMessage, _ io.Reader) (any, error) { return struct{ Name string }{Name: "foo"}, nil }) - sdkclient.SetClientMethod("bar#Client.List", func(_ context.Context, _ aws.Config, _ json.RawMessage) (any, error) { + sdkclient.SetClientMethod("bar#Client.List", func(_ context.Context, _ aws.Config, _ json.RawMessage, _ io.Reader) (any, error) { return []string{"x", "y", "z"}, nil }) - sdkclient.SetClientMethod("bar#Client.Get", func(_ context.Context, _ aws.Config, _ json.RawMessage) (any, error) { + sdkclient.SetClientMethod("bar#Client.Get", func(_ context.Context, _ aws.Config, _ json.RawMessage, _ io.Reader) (any, error) { return struct{ Name string }{Name: "bar"}, nil }) - sdkclient.SetClientMethod("baz#Client.Echo", func(_ context.Context, _ aws.Config, b json.RawMessage) (any, error) { + sdkclient.SetClientMethod("baz#Client.Echo", func(_ context.Context, _ aws.Config, b json.RawMessage, _ io.Reader) (any, error) { var v any err := json.Unmarshal(b, &v) return v, err