diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68d9fba639..a57001cc72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,10 +7,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.18 + - name: Set up Go 1.19 uses: actions/setup-go@v3.2.1 with: - go-version: 1.18 + go-version: 1.19 id: go - name: Check out code into the Go module directory @@ -34,10 +34,10 @@ jobs: runs-on: windows-latest steps: - - name: Set up Go 1.18 + - name: Set up Go 1.19 uses: actions/setup-go@v3.2.1 with: - go-version: 1.18 + go-version: 1.19 id: go - name: Check out code into the Go module directory diff --git a/cmd/goa/gen.go b/cmd/goa/gen.go index 14259851a6..6060b45aa3 100644 --- a/cmd/goa/gen.go +++ b/cmd/goa/gen.go @@ -6,7 +6,6 @@ import ( "go/build" "go/parser" "go/token" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -67,7 +66,7 @@ func NewGenerator(cmd string, path, output string) *Generator { } } for _, gof := range pkg.GoFiles { - if bs, err := ioutil.ReadFile(gof); err == nil { + if bs, err := os.ReadFile(gof); err == nil { if f, err := parser.ParseFile(fset, "", string(bs), parser.ImportsOnly); err == nil { for _, s := range f.Imports { matches := p.FindStringSubmatch(s.Path.Value) @@ -106,7 +105,7 @@ func (g *Generator) Write(debug bool) error { if cwd, err := os.Getwd(); err != nil { wd = cwd } - tmp, err := ioutil.TempDir(wd, "goa") + tmp, err := os.MkdirTemp(wd, "goa") if err != nil { return err } diff --git a/codegen/file.go b/codegen/file.go index f6bdcdbb04..4f112d71c1 100644 --- a/codegen/file.go +++ b/codegen/file.go @@ -9,7 +9,6 @@ import ( "go/scanner" "go/token" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -138,7 +137,7 @@ func finalizeGoSource(path string) error { fset := token.NewFileSet() file, err := parser.ParseFile(fset, path, nil, parser.ParseComments) if err != nil { - content, _ := ioutil.ReadFile(path) + content, _ := os.ReadFile(path) var buf bytes.Buffer scanner.PrintError(&buf, err) return fmt.Errorf("%s\n========\nContent:\n%s", buf.String(), content) @@ -169,7 +168,7 @@ func finalizeGoSource(path string) error { w.Close() // Format code using goimport standard - bs, err := ioutil.ReadFile(path) + bs, err := os.ReadFile(path) if err != nil { return err } @@ -181,5 +180,5 @@ func finalizeGoSource(path string) error { if err != nil { return err } - return ioutil.WriteFile(path, bs, os.ModePerm) + return os.WriteFile(path, bs, os.ModePerm) } diff --git a/codegen/generator/generate.go b/codegen/generator/generate.go index 133eab59ed..d61710b00f 100644 --- a/codegen/generator/generate.go +++ b/codegen/generator/generate.go @@ -1,7 +1,6 @@ package generator import ( - "io/ioutil" "os" "path/filepath" "sort" @@ -36,7 +35,7 @@ func Generate(dir, cmd string) (outputs []string, err1 error) { } // We create a temporary Go file to make sure the directory is a valid Go package - dummy, err := ioutil.TempFile(path, "temp.*.go") + dummy, err := os.CreateTemp(path, "temp.*.go") if err != nil { return nil, err } diff --git a/codegen/go_transform.go b/codegen/go_transform.go index 4289b732ff..b6c90b4fdd 100644 --- a/codegen/go_transform.go +++ b/codegen/go_transform.go @@ -348,6 +348,10 @@ func transformMap(source, target *expr.Map, sourceVar, targetVar string, newVar } // transformUnion generates Go code to transform source union to target union. +// +// Note: transport to/from service transforms are always object to union or +// union to object. The only case a transform is union to union is when +// converting a projected type from/to a service type. func transformUnion(source, target *expr.AttributeExpr, sourceVar, targetVar string, newVar bool, ta *TransformAttrs) (string, error) { if expr.IsObject(target.Type) { return transformUnionToObject(source, target, sourceVar, targetVar, newVar, ta) @@ -365,7 +369,7 @@ func transformUnion(source, target *expr.AttributeExpr, sourceVar, targetVar str } sourceTypeRefs := make([]string, len(srcUnion.Values)) for i, st := range srcUnion.Values { - sourceTypeRefs[i] = ta.TargetCtx.Scope.Ref(st.Attribute, ta.TargetCtx.Pkg(st.Attribute)) + sourceTypeRefs[i] = ta.TargetCtx.Scope.Ref(st.Attribute, ta.SourceCtx.Pkg(st.Attribute)) } targetTypeNames := make([]string, len(tgtUnion.Values)) for i, tt := range tgtUnion.Values { @@ -661,8 +665,7 @@ for key, val := range {{ .SourceVar }} { {{ end }}switch actual := {{ .SourceVar }}.(type) { {{- range $i, $ref := .SourceTypeRefs }} case {{ $ref }}: - {{ transformAttribute (index $.SourceTypes $i).Attribute (index $.TargetTypes $i).Attribute "actual" "val" true $.TransformAttrs -}} - {{ $.TargetVar }} = {{ $.TargetTypeName }}{ Value: val } + {{- transformAttribute (index $.SourceTypes $i).Attribute (index $.TargetTypes $i).Attribute "actual" $.TargetVar false $.TransformAttrs -}} {{- end }} } ` diff --git a/codegen/go_transform_union_test.go b/codegen/go_transform_union_test.go index 3a84ac74b3..c864b3d6f0 100644 --- a/codegen/go_transform_union_test.go +++ b/codegen/go_transform_union_test.go @@ -13,12 +13,13 @@ func TestGoTransformUnion(t *testing.T) { scope = NewNameScope() // types to test - unionString = root.UserType("Container").Attribute().Find("UnionString").Find("UnionString") - unionString2 = root.UserType("Container").Attribute().Find("UnionString2").Find("UnionString2") - unionStringInt = root.UserType("Container").Attribute().Find("UnionStringInt").Find("UnionStringInt") - unionSomeType = root.UserType("Container").Attribute().Find("UnionSomeType").Find("UnionSomeType") - userType = &expr.AttributeExpr{Type: root.UserType("UnionUserType")} - defaultCtx = NewAttributeContext(false, false, true, "", scope) + unionString = root.UserType("Container").Attribute().Find("UnionString").Find("UnionString") + unionString2 = root.UserType("Container").Attribute().Find("UnionString2").Find("UnionString2") + unionStringInt = root.UserType("Container").Attribute().Find("UnionStringInt").Find("UnionStringInt") + unionStringInt2 = root.UserType("Container").Attribute().Find("UnionStringInt2").Find("UnionStringInt2") + unionSomeType = root.UserType("Container").Attribute().Find("UnionSomeType").Find("UnionSomeType") + userType = &expr.AttributeExpr{Type: root.UserType("UnionUserType")} + defaultCtx = NewAttributeContext(false, false, true, "", scope) ) tc := []struct { Name string @@ -27,6 +28,7 @@ func TestGoTransformUnion(t *testing.T) { Expected string }{ {"UnionString to UnionString2", unionString, unionString2, unionToUnionCode}, + {"UnionStringInt to UnionStringInt2", unionStringInt, unionStringInt2, unionMultiToUnionMultiCode}, {"UnionString to User Type", unionString, userType, unionStringToUserTypeCode}, {"UnionStringInt to User Type", unionStringInt, userType, unionStringIntToUserTypeCode}, @@ -89,8 +91,21 @@ const unionToUnionCode = `func transform() { var target *UnionString2 switch actual := source.(type) { case UnionStringString: - val := UnionString2String(actual) - target = UnionString2{Value: val} + target = UnionString2String(actual) + + } +} +` + +const unionMultiToUnionMultiCode = `func transform() { + var target *UnionStringInt2 + switch actual := source.(type) { + case UnionStringIntString: + target = UnionStringInt2String(actual) + + case UnionStringIntInt: + target = UnionStringInt2Int(actual) + } } ` diff --git a/codegen/service/service_data.go b/codegen/service/service_data.go index 1a1b3531fa..695c2ea123 100644 --- a/codegen/service/service_data.go +++ b/codegen/service/service_data.go @@ -78,6 +78,8 @@ type ( // projectedTypes lists the types which uses pointers for all fields to // define view specific validation logic. projectedTypes []*ProjectedTypeData + // union methods that need to be defined in views package. + viewedUnionMethods []*UnionValueMethodData // viewedResultTypes lists all the viewed method result types. viewedResultTypes []*ViewedResultTypeData // unionValueMethods lists the methods used to define union types. @@ -538,19 +540,20 @@ func (s SchemesData) Append(d *SchemeData) SchemesData { // It records the user types needed by the service definition in userTypes. func (d ServicesData) analyze(service *expr.ServiceExpr) *Data { var ( - scope *codegen.NameScope - viewScope *codegen.NameScope - pkgName string - viewspkg string - types []*UserTypeData - errTypes []*UserTypeData - errorInits []*ErrorInitData - projTypes []*ProjectedTypeData - viewedRTs []*ViewedResultTypeData - seenErrors map[string]struct{} - seen map[string]struct{} - seenProj map[string]*ProjectedTypeData - seenViewed map[string]*ViewedResultTypeData + scope *codegen.NameScope + viewScope *codegen.NameScope + pkgName string + viewspkg string + types []*UserTypeData + errTypes []*UserTypeData + errorInits []*ErrorInitData + projTypes []*ProjectedTypeData + viewedUnionMeths []*UnionValueMethodData + viewedRTs []*ViewedResultTypeData + seenErrors map[string]struct{} + seen map[string]struct{} + seenProj map[string]*ProjectedTypeData + seenViewed map[string]*ViewedResultTypeData ) { scope = codegen.NewNameScope() @@ -593,7 +596,9 @@ func (d ServicesData) analyze(service *expr.ServiceExpr) *Data { if _, ok := m.Result.Type.(*expr.ResultTypeExpr); ok { // collect projected types for the corresponding result type projected := expr.DupAtt(m.Result) - projTypes = append(projTypes, collectProjectedTypes(projected, m.Result, viewspkg, scope, viewScope, seenProj)...) + types, umeths := collectProjectedTypes(projected, m.Result, viewspkg, scope, viewScope, seenProj) + projTypes = append(projTypes, types...) + viewedUnionMeths = append(viewedUnionMeths, umeths...) } for _, er := range m.Errors { recordError(er) @@ -724,23 +729,24 @@ func (d ServicesData) analyze(service *expr.ServiceExpr) *Data { varName := codegen.Goify(service.Name, false) data := &Data{ - Name: service.Name, - Description: desc, - VarName: varName, - PathName: codegen.SnakeCase(varName), - StructName: codegen.Goify(service.Name, true), - PkgName: pkgName, - ViewsPkg: viewspkg, - Methods: methods, - Schemes: schemes, - Scope: scope, - ViewScope: viewScope, - errorTypes: errTypes, - errorInits: errorInits, - userTypes: types, - projectedTypes: projTypes, - viewedResultTypes: viewedRTs, - unionValueMethods: ms, + Name: service.Name, + Description: desc, + VarName: varName, + PathName: codegen.SnakeCase(varName), + StructName: codegen.Goify(service.Name, true), + PkgName: pkgName, + ViewsPkg: viewspkg, + Methods: methods, + Schemes: schemes, + Scope: scope, + ViewScope: viewScope, + errorTypes: errTypes, + errorInits: errorInits, + userTypes: types, + projectedTypes: projTypes, + viewedUnionMethods: viewedUnionMeths, + viewedResultTypes: viewedRTs, + unionValueMethods: ms, } d[service.Name] = data @@ -1149,8 +1155,8 @@ func BuildSchemeData(s *expr.SchemeExpr, m *expr.MethodExpr) *SchemeData { // make use of views. We need to build projected types for all user types - not // just result types - because user types make contain result types and thus may // need to be marshalled in different ways depending on the view being used. -func collectProjectedTypes(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope, seen map[string]*ProjectedTypeData) (data []*ProjectedTypeData) { - collect := func(projected, att *expr.AttributeExpr) []*ProjectedTypeData { +func collectProjectedTypes(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope, seen map[string]*ProjectedTypeData) (data []*ProjectedTypeData, umeths []*UnionValueMethodData) { + collect := func(projected, att *expr.AttributeExpr) ([]*ProjectedTypeData, []*UnionValueMethodData) { return collectProjectedTypes(projected, att, viewspkg, scope, viewScope, seen) } switch pt := projected.Type.(type) { @@ -1171,22 +1177,44 @@ func collectProjectedTypes(projected, att *expr.AttributeExpr, viewspkg string, pt.Rename(pt.Name() + "View") // We recurse before building the projected type so that user types within // a projected type is also converted to their respective projected types. - types := collect(pt.Attribute(), dt.Attribute()) + types, ms := collect(pt.Attribute(), dt.Attribute()) pd := buildProjectedType(projected, att, viewspkg, scope, viewScope) seen[dt.ID()] = pd data = append(data, pd) data = append(data, types...) + umeths = append(umeths, ms...) case *expr.Array: dt := att.Type.(*expr.Array) - data = append(data, collect(pt.ElemType, dt.ElemType)...) + types, ms := collect(pt.ElemType, dt.ElemType) + data = append(data, types...) + umeths = append(umeths, ms...) case *expr.Map: dt := att.Type.(*expr.Map) - data = append(data, collect(pt.KeyType, dt.KeyType)...) - data = append(data, collect(pt.ElemType, dt.ElemType)...) + types, ms := collect(pt.KeyType, dt.KeyType) + data = append(data, types...) + umeths = append(umeths, ms...) + types, ms = collect(pt.ElemType, dt.ElemType) + data = append(data, types...) + umeths = append(umeths, ms...) case *expr.Object: dt := att.Type.(*expr.Object) for _, n := range *pt { - data = append(data, collect(n.Attribute, dt.Attribute(n.Name))...) + types, ms := collect(n.Attribute, dt.Attribute(n.Name)) + data = append(data, types...) + umeths = append(umeths, ms...) + } + case *expr.Union: + dt := att.Type.(*expr.Union) + for i, n := range pt.Values { + types, ms := collect(n.Attribute, dt.Values[i].Attribute) + data = append(data, types...) + umeths = append(umeths, ms...) + } + for _, nat := range pt.Values { + umeths = append(umeths, &UnionValueMethodData{ + Name: codegen.UnionValTypeName(pt.Name()), + TypeRef: scope.GoTypeRef(nat.Attribute), + }) } } return diff --git a/codegen/service/views.go b/codegen/service/views.go index dd7b8043cd..95f3c1b30e 100644 --- a/codegen/service/views.go +++ b/codegen/service/views.go @@ -49,6 +49,16 @@ func ViewsFile(genpkg string, service *expr.ServiceExpr) *codegen.File { }) } + // Union methods + for _, m := range svc.viewedUnionMethods { + sections = append(sections, &codegen.SectionTemplate{ + // addTypeDefSection(pathWithDefault(m.Loc, svcPath), "~"+m.TypeRef+"."+m.Name, &codegen.SectionTemplate{ + Name: "viewed-union-value-method", + Source: unionValueMethodT, + Data: m, + }) + } + // generate a map for result types with view name as key and the fields // rendered in the view as value. var ( diff --git a/codegen/testdata/union_dsls.go b/codegen/testdata/union_dsls.go index 3d0310128a..f37dfdd34e 100644 --- a/codegen/testdata/union_dsls.go +++ b/codegen/testdata/union_dsls.go @@ -26,6 +26,12 @@ var TestUnionDSL = func() { Attribute("Int", Int) }) }) + UnionStringInt2 = Type("UnionStringInt2", func() { + OneOf("UnionStringInt2", func() { + Attribute("String", String) + Attribute("Int", Int) + }) + }) UnionSomeType = Type("UnionSomeType", func() { OneOf("UnionSomeType", func() { Attribute("SomeType", SomeType) @@ -36,6 +42,7 @@ var TestUnionDSL = func() { Attribute("UnionString", UnionString) Attribute("UnionString2", UnionString2) Attribute("UnionStringInt", UnionStringInt) + Attribute("UnionStringInt2", UnionStringInt2) Attribute("UnionSomeType", UnionSomeType) }) diff --git a/codegen/testing.go b/codegen/testing.go index bde65df6b4..6d5cea5157 100644 --- a/codegen/testing.go +++ b/codegen/testing.go @@ -3,7 +3,6 @@ package codegen import ( "bytes" "fmt" - "io/ioutil" "os" "os/exec" "strings" @@ -83,7 +82,7 @@ func FormatTestCode(t *testing.T, code string) string { if err := finalizeGoSource(tmp); err != nil { t.Fatal(err) } - content, err := ioutil.ReadFile(tmp) + content, err := os.ReadFile(tmp) if err != nil { t.Fatal(err) } @@ -113,7 +112,7 @@ func Diff(t *testing.T, s1, s2 string) string { // It is used only for testing. func CreateTempFile(t *testing.T, content string) string { t.Helper() - f, err := ioutil.TempFile("", "") + f, err := os.CreateTemp("", "") if err != nil { t.Fatal(err) } diff --git a/expr/hasher.go b/expr/hasher.go index 0bbc28c30a..8376b4ad5a 100644 --- a/expr/hasher.go +++ b/expr/hasher.go @@ -69,11 +69,13 @@ func hashMap(m *Map, ignoreFields, ignoreNames, ignoreTags bool, seen map[*Objec } func hashUnion(u *Union, ignoreFields, ignoreNames, ignoreTags bool, seen map[*Object]*string) *string { - sort.Slice(u.Values, func(i, j int) bool { + sorted := make([]*NamedAttributeExpr, len(u.Values)) + copy(sorted, u.Values) + sort.Slice(sorted, func(i, j int) bool { return u.Values[i].Name < u.Values[j].Name }) h := unionTypePrefix + u.TypeName - for _, nat := range u.Values { + for _, nat := range sorted { h += unionAttributePrefix + nat.Name + unionAttributeTypePrefix + *hash(nat.Attribute.Type, ignoreFields, ignoreNames, ignoreTags, seen) } return &h diff --git a/expr/testing.go b/expr/testing.go index 79e537a6da..f88c599b14 100644 --- a/expr/testing.go +++ b/expr/testing.go @@ -1,7 +1,6 @@ package expr import ( - "io/ioutil" "os" "os/exec" "strings" @@ -76,7 +75,7 @@ func Diff(t *testing.T, s1, s2 string) string { // It is used only for testing. func CreateTempFile(t *testing.T, content string) string { t.Helper() - f, err := ioutil.TempFile("", "") + f, err := os.CreateTemp("", "") if err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index ce7c9ed5cb..7c090ef678 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module goa.design/goa/v3 -go 1.18 +go 1.19 require ( github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 @@ -32,9 +32,9 @@ require ( github.com/manveru/gobdd v0.0.0-20131210092515-f1a17fdd710b // indirect github.com/smartystreets/goconvey v1.7.2 // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect - golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect + golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b // indirect + golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 // indirect golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect - google.golang.org/genproto v0.0.0-20220715211116-798f69b842b9 // indirect + google.golang.org/genproto v0.0.0-20220803205849-8f55acc8769f // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index c3e514e640..e005df0ae9 100644 --- a/go.sum +++ b/go.sum @@ -134,6 +134,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0= +golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -148,6 +150,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 h1:Y7NOhdqIOU8kYI7BxsgL38d0ot0raxvcW+EMQU2QrT4= +golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= @@ -172,6 +176,8 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20220715211116-798f69b842b9 h1:1aEQRgZ4Gks2SRAkLzIPpIszRazwVfjSFe1cKc+e0Jg= google.golang.org/genproto v0.0.0-20220715211116-798f69b842b9/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220803205849-8f55acc8769f h1:ywoA0TLvF/4n7P2lr/+bNRueYxWYUJZbRwV3hyYt8gY= +google.golang.org/genproto v0.0.0-20220803205849-8f55acc8769f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/http/client.go b/http/client.go index 343f386e17..e3f73d1eec 100644 --- a/http/client.go +++ b/http/client.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "net" "net/http" "os" @@ -63,8 +62,8 @@ func NewDebugDoer(d Doer) DebugDoer { func (dd *debugDoer) Do(req *http.Request) (*http.Response, error) { var reqb []byte if req.Body != nil { - reqb, _ = ioutil.ReadAll(req.Body) - req.Body = ioutil.NopCloser(bytes.NewBuffer(reqb)) + reqb, _ = io.ReadAll(req.Body) + req.Body = io.NopCloser(bytes.NewBuffer(reqb)) } resp, err := dd.Doer.Do(req) @@ -73,15 +72,15 @@ func (dd *debugDoer) Do(req *http.Request) (*http.Response, error) { return nil, err } - respb, err := ioutil.ReadAll(resp.Body) + respb, err := io.ReadAll(resp.Body) if err != nil { respb = []byte(fmt.Sprintf("!!failed to read response: %s", err)) } - resp.Body = ioutil.NopCloser(bytes.NewBuffer(respb)) + resp.Body = io.NopCloser(bytes.NewBuffer(respb)) dd.Response = resp - req.Body = ioutil.NopCloser(bytes.NewBuffer(reqb)) + req.Body = io.NopCloser(bytes.NewBuffer(reqb)) dd.Request = req dd.Fprint(os.Stderr) @@ -108,9 +107,9 @@ func (dd *debugDoer) Fprint(w io.Writer) { buf.WriteString(fmt.Sprintf("\n> %s: %s", k, strings.Join(dd.Request.Header[k], ", "))) } - b, _ := ioutil.ReadAll(dd.Request.Body) + b, _ := io.ReadAll(dd.Request.Body) if len(b) > 0 { - dd.Request.Body = ioutil.NopCloser(bytes.NewBuffer(b)) // reset the request body + dd.Request.Body = io.NopCloser(bytes.NewBuffer(b)) // reset the request body buf.WriteByte('\n') buf.Write(b) } @@ -132,9 +131,9 @@ func (dd *debugDoer) Fprint(w io.Writer) { buf.WriteString(fmt.Sprintf("\n< %s: %s", k, strings.Join(dd.Response.Header[k], ", "))) } - rb, _ := ioutil.ReadAll(dd.Response.Body) // this is reading from a memory buffer so safe to ignore errors + rb, _ := io.ReadAll(dd.Response.Body) // this is reading from a memory buffer so safe to ignore errors if len(rb) > 0 { - dd.Response.Body = ioutil.NopCloser(bytes.NewBuffer(rb)) // reset the response body + dd.Response.Body = io.NopCloser(bytes.NewBuffer(rb)) // reset the response body buf.WriteByte('\n') buf.Write(rb) } diff --git a/http/codegen/openapi/v2/files_test.go b/http/codegen/openapi/v2/files_test.go index ca1480a2fe..0260c045cd 100644 --- a/http/codegen/openapi/v2/files_test.go +++ b/http/codegen/openapi/v2/files_test.go @@ -6,7 +6,7 @@ import ( "errors" "flag" "fmt" - "io/ioutil" + "os" "path/filepath" "testing" "text/template" @@ -76,12 +76,12 @@ func TestSections(t *testing.T) { golden := filepath.Join(goldenPath, fmt.Sprintf("%s_%s.golden", c.Name, tname)) if *update { - if err := ioutil.WriteFile(golden, buf.Bytes(), 0644); err != nil { + if err := os.WriteFile(golden, buf.Bytes(), 0644); err != nil { t.Fatalf("failed to update golden file: %s", err) } } - want, err := ioutil.ReadFile(golden) + want, err := os.ReadFile(golden) want = bytes.Replace(want, []byte{'\r', '\n'}, []byte{'\n'}, -1) if err != nil { t.Fatalf("failed to read golden file: %s", err) @@ -166,12 +166,12 @@ func TestValidations(t *testing.T) { golden := filepath.Join(goldenPath, fmt.Sprintf("%s_%s.golden", c.Name, tname)) if *update { - if err := ioutil.WriteFile(golden, buf.Bytes(), 0644); err != nil { + if err := os.WriteFile(golden, buf.Bytes(), 0644); err != nil { t.Fatalf("failed to update golden file: %s", err) } } - want, err := ioutil.ReadFile(golden) + want, err := os.ReadFile(golden) want = bytes.Replace(want, []byte{'\r', '\n'}, []byte{'\n'}, -1) if err != nil { t.Fatalf("failed to read golden file: %s", err) @@ -233,12 +233,12 @@ func TestExtensions(t *testing.T) { golden := filepath.Join(goldenPath, fmt.Sprintf("%s_%s.golden", c.Name, tname)) if *update { - if err := ioutil.WriteFile(golden, buf.Bytes(), 0644); err != nil { + if err := os.WriteFile(golden, buf.Bytes(), 0644); err != nil { t.Fatalf("failed to update golden file: %s", err) } } - want, err := ioutil.ReadFile(golden) + want, err := os.ReadFile(golden) want = bytes.Replace(want, []byte{'\r', '\n'}, []byte{'\n'}, -1) if err != nil { t.Fatalf("failed to read golden file: %s", err) diff --git a/http/codegen/openapi/v3/files_test.go b/http/codegen/openapi/v3/files_test.go index e0255933c2..a9e0fcfd86 100644 --- a/http/codegen/openapi/v3/files_test.go +++ b/http/codegen/openapi/v3/files_test.go @@ -6,7 +6,7 @@ import ( "encoding/json" "flag" "fmt" - "io/ioutil" + "os" "path/filepath" "strings" "testing" @@ -83,12 +83,12 @@ func TestFiles(t *testing.T) { golden := filepath.Join(goldenPath, fmt.Sprintf("%s_%s.golden", strings.TrimSuffix(c.Name, "-swagger"), tname)) if *update { - if err := ioutil.WriteFile(golden, buf.Bytes(), 0644); err != nil { + if err := os.WriteFile(golden, buf.Bytes(), 0644); err != nil { t.Fatalf("failed to update golden file: %s", err) } } - want, err := ioutil.ReadFile(golden) + want, err := os.ReadFile(golden) want = bytes.Replace(want, []byte{'\r', '\n'}, []byte{'\n'}, -1) if err != nil { t.Fatalf("failed to read golden file: %s", err) diff --git a/http/codegen/testdata/result_decode_functions.go b/http/codegen/testdata/result_decode_functions.go index 21cd72e0b2..04bdfce3ff 100644 --- a/http/codegen/testdata/result_decode_functions.go +++ b/http/codegen/testdata/result_decode_functions.go @@ -746,8 +746,8 @@ var ValidateErrorResponseTypeDecodeCode = `// DecodeMethodAResponse returns a de // ValidateErrorResponseType MethodA endpoint. restoreBody controls whether the // response body should be restored after having been read. // DecodeMethodAResponse may return the following errors: -// - "some_error" (type *validateerrorresponsetype.AError): http.StatusBadRequest -// - error: internal error +// - "some_error" (type *validateerrorresponsetype.AError): http.StatusBadRequest +// - error: internal error func DecodeMethodAResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) { return func(resp *http.Response) (interface{}, error) { if restoreBody { @@ -831,9 +831,9 @@ var EmptyErrorResponseBodyDecodeCode = `// DecodeMethodEmptyErrorResponseBodyRes // endpoint. restoreBody controls whether the response body should be restored // after having been read. // DecodeMethodEmptyErrorResponseBodyResponse may return the following errors: -// - "internal_error" (type *goa.ServiceError): http.StatusInternalServerError -// - "not_found" (type serviceemptyerrorresponsebody.NotFound): http.StatusNotFound -// - error: internal error +// - "internal_error" (type *goa.ServiceError): http.StatusInternalServerError +// - "not_found" (type serviceemptyerrorresponsebody.NotFound): http.StatusNotFound +// - error: internal error func DecodeMethodEmptyErrorResponseBodyResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) { return func(resp *http.Response) (interface{}, error) { if restoreBody { diff --git a/http/encoding.go b/http/encoding.go index 778af1cf66..fa87dfa0b2 100644 --- a/http/encoding.go +++ b/http/encoding.go @@ -8,7 +8,6 @@ import ( "encoding/xml" "fmt" "io" - "io/ioutil" "mime" "net/http" "strings" @@ -175,7 +174,7 @@ func RequestEncoder(r *http.Request) Encoder { r.Header.Set(k, "application/json") } var buf bytes.Buffer - r.Body = ioutil.NopCloser(&buf) + r.Body = io.NopCloser(&buf) return json.NewEncoder(&buf) } @@ -294,7 +293,7 @@ type textDecoder struct { } func (e *textDecoder) Decode(v interface{}) error { - b, err := ioutil.ReadAll(e.r) + b, err := io.ReadAll(e.r) if err != nil { return err } diff --git a/http/middleware/debug.go b/http/middleware/debug.go index 0eb2380224..37c7ad6fd8 100644 --- a/http/middleware/debug.go +++ b/http/middleware/debug.go @@ -7,7 +7,6 @@ import ( "encoding/base64" "fmt" "io" - "io/ioutil" "net" "net/http" "sort" @@ -66,7 +65,7 @@ func Debug(mux goahttp.Muxer, w io.Writer) func(http.Handler) http.Handler { } // Request body - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) if err != nil { b = []byte("failed to read body: " + err.Error()) } @@ -77,7 +76,7 @@ func Debug(mux goahttp.Muxer, w io.Writer) func(http.Handler) http.Handler { buf.WriteString(fmt.Sprintf("[%s] %s\n", reqID, line)) } } - r.Body = ioutil.NopCloser(bytes.NewBuffer(b)) + r.Body = io.NopCloser(bytes.NewBuffer(b)) dupper := &responseDupper{ResponseWriter: rw, Buffer: &bytes.Buffer{}} h.ServeHTTP(dupper, r)