From 096c6fc88249819188a9b3d66a9a6550dad512dc Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Sat, 30 Aug 2025 16:53:14 +0200 Subject: [PATCH] chore: adopted swag v0.24.0 modules go-openapi has introduced a new API to better insulate dependencies. We move to the new modules, even though at this stage this doesn't change our indirect dependencies. Signed-off-by: Frederic BIDON --- go.mod | 19 +++++++++++++++---- go.sum | 40 +++++++++++++++++++++++++++++++--------- jsonschema_test.go | 8 ++++---- schema.go | 12 ++++++++++-- schema_test.go | 4 ++-- spec.go | 10 ++++++++-- type.go | 7 ++++--- type_test.go | 7 ++++--- values.go | 20 ++++++++++---------- 9 files changed, 88 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index ae45fd5..eb8d8de 100644 --- a/go.mod +++ b/go.mod @@ -4,25 +4,36 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/go-openapi/analysis v0.23.0 github.com/go-openapi/errors v0.22.2 - github.com/go-openapi/jsonpointer v0.21.2 + github.com/go-openapi/jsonpointer v0.22.0 github.com/go-openapi/loads v0.22.0 github.com/go-openapi/spec v0.21.0 github.com/go-openapi/strfmt v0.23.0 - github.com/go-openapi/swag v0.23.1 + github.com/go-openapi/swag/conv v0.24.0 + github.com/go-openapi/swag/fileutils v0.24.0 + github.com/go-openapi/swag/jsonutils v0.24.0 + github.com/go-openapi/swag/stringutils v0.24.0 github.com/stretchr/testify v1.11.1 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.1 // indirect + github.com/go-openapi/swag v0.24.1 // indirect + github.com/go-openapi/swag/cmdutils v0.24.0 // indirect + github.com/go-openapi/swag/jsonname v0.24.0 // indirect + github.com/go-openapi/swag/loading v0.24.0 // indirect + github.com/go-openapi/swag/mangling v0.24.0 // indirect + github.com/go-openapi/swag/netutils v0.24.0 // indirect + github.com/go-openapi/swag/typeutils v0.24.0 // indirect + github.com/go-openapi/swag/yamlutils v0.24.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.mongodb.org/mongo-driver v1.14.0 // indirect + go.mongodb.org/mongo-driver v1.17.4 // indirect ) go 1.20 diff --git a/go.sum b/go.sum index 1560a4e..5d9befc 100644 --- a/go.sum +++ b/go.sum @@ -6,19 +6,41 @@ github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC0 github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= github.com/go-openapi/errors v0.22.2 h1:rdxhzcBUazEcGccKqbY1Y7NS8FDcMyIRr0934jrYnZg= github.com/go-openapi/errors v0.22.2/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0= -github.com/go-openapi/jsonpointer v0.21.2 h1:AqQaNADVwq/VnkCmQg6ogE+M3FOsKTytwges0JdwVuA= -github.com/go-openapi/jsonpointer v0.21.2/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/jsonpointer v0.22.0 h1:TmMhghgNef9YXxTu1tOopo+0BGEytxA+okbry0HjZsM= +github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= +github.com/go-openapi/jsonreference v0.21.1 h1:bSKrcl8819zKiOgxkbVNRUBIr6Wwj9KYrDbMjRs0cDA= +github.com/go-openapi/jsonreference v0.21.1/go.mod h1:PWs8rO4xxTUqKGu+lEvvCxD5k2X7QYkKAepJyCmSTT8= github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/go-openapi/swag v0.24.1 h1:DPdYTZKo6AQCRqzwr/kGkxJzHhpKxZ9i/oX0zag+MF8= +github.com/go-openapi/swag v0.24.1/go.mod h1:sm8I3lCPlspsBBwUm1t5oZeWZS0s7m/A+Psg0ooRU0A= +github.com/go-openapi/swag/cmdutils v0.24.0 h1:KlRCffHwXFI6E5MV9n8o8zBRElpY4uK4yWyAMWETo9I= +github.com/go-openapi/swag/cmdutils v0.24.0/go.mod h1:uxib2FAeQMByyHomTlsP8h1TtPd54Msu2ZDU/H5Vuf8= +github.com/go-openapi/swag/conv v0.24.0 h1:ejB9+7yogkWly6pnruRX45D1/6J+ZxRu92YFivx54ik= +github.com/go-openapi/swag/conv v0.24.0/go.mod h1:jbn140mZd7EW2g8a8Y5bwm8/Wy1slLySQQ0ND6DPc2c= +github.com/go-openapi/swag/fileutils v0.24.0 h1:U9pCpqp4RUytnD689Ek/N1d2N/a//XCeqoH508H5oak= +github.com/go-openapi/swag/fileutils v0.24.0/go.mod h1:3SCrCSBHyP1/N+3oErQ1gP+OX1GV2QYFSnrTbzwli90= +github.com/go-openapi/swag/jsonname v0.24.0 h1:2wKS9bgRV/xB8c62Qg16w4AUiIrqqiniJFtZGi3dg5k= +github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q= +github.com/go-openapi/swag/jsonutils v0.24.0 h1:F1vE1q4pg1xtO3HTyJYRmEuJ4jmIp2iZ30bzW5XgZts= +github.com/go-openapi/swag/jsonutils v0.24.0/go.mod h1:vBowZtF5Z4DDApIoxcIVfR8v0l9oq5PpYRUuteVu6f0= +github.com/go-openapi/swag/loading v0.24.0 h1:ln/fWTwJp2Zkj5DdaX4JPiddFC5CHQpvaBKycOlceYc= +github.com/go-openapi/swag/loading v0.24.0/go.mod h1:gShCN4woKZYIxPxbfbyHgjXAhO61m88tmjy0lp/LkJk= +github.com/go-openapi/swag/mangling v0.24.0 h1:PGOQpViCOUroIeak/Uj/sjGAq9LADS3mOyjznmHy2pk= +github.com/go-openapi/swag/mangling v0.24.0/go.mod h1:Jm5Go9LHkycsz0wfoaBDkdc4CkpuSnIEf62brzyCbhc= +github.com/go-openapi/swag/netutils v0.24.0 h1:Bz02HRjYv8046Ycg/w80q3g9QCWeIqTvlyOjQPDjD8w= +github.com/go-openapi/swag/netutils v0.24.0/go.mod h1:WRgiHcYTnx+IqfMCtu0hy9oOaPR0HnPbmArSRN1SkZM= +github.com/go-openapi/swag/stringutils v0.24.0 h1:i4Z/Jawf9EvXOLUbT97O0HbPUja18VdBxeadyAqS1FM= +github.com/go-openapi/swag/stringutils v0.24.0/go.mod h1:5nUXB4xA0kw2df5PRipZDslPJgJut+NjL7D25zPZ/4w= +github.com/go-openapi/swag/typeutils v0.24.0 h1:d3szEGzGDf4L2y1gYOSSLeK6h46F+zibnEas2Jm/wIw= +github.com/go-openapi/swag/typeutils v0.24.0/go.mod h1:q8C3Kmk/vh2VhpCLaoR2MVWOGP8y7Jc8l82qCTd1DYI= +github.com/go-openapi/swag/yamlutils v0.24.0 h1:bhw4894A7Iw6ne+639hsBNRHg9iZg/ISrOVr+sJGp4c= +github.com/go-openapi/swag/yamlutils v0.24.0/go.mod h1:DpKv5aYuaGm/sULePoeiG8uwMpZSfReo1HR3Ik0yaG8= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -36,8 +58,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= -go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw= +go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= 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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/jsonschema_test.go b/jsonschema_test.go index b8af57e..5658816 100644 --- a/jsonschema_test.go +++ b/jsonschema_test.go @@ -25,7 +25,7 @@ import ( "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag/stringutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -93,15 +93,15 @@ var extendedFixtures = []string{ } func isEnabled(nm string) bool { - return swag.ContainsStringsCI(enabled(), nm) + return stringutils.ContainsStringsCI(enabled(), nm) } func isOptionalEnabled(nm string) bool { - return swag.ContainsStringsCI(optionalFixtures, nm) + return stringutils.ContainsStringsCI(optionalFixtures, nm) } func isExtendedEnabled(nm string) bool { - return swag.ContainsStringsCI(extendedFixtures, nm) + return stringutils.ContainsStringsCI(extendedFixtures, nm) } func TestJSONSchemaSuite(t *testing.T) { diff --git a/schema.go b/schema.go index db65264..5ab7adb 100644 --- a/schema.go +++ b/schema.go @@ -21,7 +21,7 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag/jsonutils" ) // SchemaValidator validates data against a JSON schema @@ -176,7 +176,15 @@ func (s *SchemaValidator) Validate(data interface{}) *Result { // this means that all strfmt types passed here (e.g. strfmt.Datetime, etc..) // are converted here to strings, and structs are systematically converted // to map[string]interface{}. - d = swag.ToDynamicJSON(data) + var dd any + if err := jsonutils.FromDynamicJSON(data, &dd); err != nil { + result.AddErrors(err) + result.Inc() + + return result + } + + d = dd } // TODO: this part should be handed over to type validator diff --git a/schema_test.go b/schema_test.go index 4ece59c..e4cd848 100644 --- a/schema_test.go +++ b/schema_test.go @@ -25,7 +25,7 @@ import ( "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag/conv" ) func TestSchemaValidator_Validate_Pattern(t *testing.T) { @@ -171,7 +171,7 @@ func TestSchemaValidator_EdgeCases(t *testing.T) { r = s.Validate(j) assert.True(t, r.IsValid()) - bignum := swag.FormatFloat64(math.MaxFloat64) + bignum := conv.FormatFloat(math.MaxFloat64) j = json.Number(bignum) r = s.Validate(j) assert.False(t, r.IsValid()) diff --git a/spec.go b/spec.go index 9b57b4d..aef0cc3 100644 --- a/spec.go +++ b/spec.go @@ -28,7 +28,7 @@ import ( "github.com/go-openapi/loads" "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag/jsonutils" ) // Spec validates an OpenAPI 2.0 specification document. @@ -696,7 +696,13 @@ func (s *SpecValidator) validateParameters() *Result { for _, pr := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) { // An expanded parameter must validate the Parameter schema (an unexpanded $ref always passes high-level schema validation) schv := newSchemaValidator(¶mSchema, s.schema, fmt.Sprintf("%s.%s.parameters.%s", path, method, pr.Name), s.KnownFormats, s.schemaOptions) - obj := swag.ToDynamicJSON(pr) + var obj any + if err := jsonutils.FromDynamicJSON(pr, &obj); err != nil { + res.AddErrors(err) + + return res + } + res.Merge(schv.Validate(obj)) // Validate pattern regexp for parameters with a Pattern property diff --git a/type.go b/type.go index d64ece8..91ae341 100644 --- a/type.go +++ b/type.go @@ -21,7 +21,8 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag/conv" + "github.com/go-openapi/swag/fileutils" ) type typeValidator struct { @@ -100,7 +101,7 @@ func (t *typeValidator) Validate(data interface{}) *Result { // TODO: check json.Number (see schema.go) isLowerInt := t.Format == integerFormatInt64 && format == integerFormatInt32 isLowerFloat := t.Format == numberFormatFloat64 && format == numberFormatFloat32 - isFloatInt := schType == numberType && swag.IsFloat64AJSONInteger(val.Float()) && t.Type.Contains(integerType) + isFloatInt := schType == numberType && conv.IsFloat64AJSONInteger(val.Float()) && t.Type.Contains(integerType) isIntFloat := schType == integerType && t.Type.Contains(numberType) if kind != reflect.String && kind != reflect.Slice && t.Format != "" && !t.Type.Contains(schType) && format != t.Format && !isFloatInt && !isIntFloat && !isLowerInt && !isLowerFloat { @@ -134,7 +135,7 @@ func (t *typeValidator) schemaInfoForType(data interface{}) (string, string) { return stringType, stringFormatDateTime case strfmt.Duration, *strfmt.Duration: return stringType, stringFormatDuration - case swag.File, *swag.File: + case fileutils.File, *fileutils.File: return fileType, "" case strfmt.Email, *strfmt.Email: return stringType, stringFormatEmail diff --git a/type_test.go b/type_test.go index 845ffe0..fccf9a8 100644 --- a/type_test.go +++ b/type_test.go @@ -21,7 +21,8 @@ import ( "time" "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag/fileutils" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -52,7 +53,7 @@ func TestType_schemaInfoForType(t *testing.T) { }, { // TODO: this exception is really prone to errors: should alias runtime.File in strfmt - value: swag.File{}, + value: fileutils.File{}, expectedJSONType: "file", expectedSwaggerFormat: "", }, @@ -287,7 +288,7 @@ func TestType_schemaInfoForType(t *testing.T) { } // Check file declarations as io.ReadCloser are properly detected - myFile := swag.File{} + myFile := fileutils.File{} var myReader io.ReadCloser = &myFile jsonType, swaggerFormat := v.schemaInfoForType(myReader) assert.Equal(t, "file", jsonType) diff --git a/values.go b/values.go index b263795..9df4a95 100644 --- a/values.go +++ b/values.go @@ -23,7 +23,7 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag/conv" ) type valueError string @@ -266,7 +266,7 @@ func MultipleOf(path, in string, data, factor float64) *errors.Validation { } else { mult = data / factor } - if !swag.IsFloat64AJSONInteger(mult) { + if !conv.IsFloat64AJSONInteger(mult) { return errors.NotMultipleOf(path, in, factor, data) } return nil @@ -410,11 +410,11 @@ func IsValueValidAgainstRange(val interface{}, typeName, format, prefix, path st var stringRep string switch kind { //nolint:exhaustive case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - stringRep = swag.FormatUint64(valueHelp.asUint64(val)) + stringRep = conv.FormatUinteger(valueHelp.asUint64(val)) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - stringRep = swag.FormatInt64(valueHelp.asInt64(val)) + stringRep = conv.FormatInteger(valueHelp.asInt64(val)) case reflect.Float32, reflect.Float64: - stringRep = swag.FormatFloat64(valueHelp.asFloat64(val)) + stringRep = conv.FormatFloat(valueHelp.asFloat64(val)) default: return fmt.Errorf("%s value number range checking called with invalid (non numeric) val type in %s: %w", prefix, path, ErrValue) } @@ -425,22 +425,22 @@ func IsValueValidAgainstRange(val interface{}, typeName, format, prefix, path st case integerType: switch format { case integerFormatInt32: - _, errVal = swag.ConvertInt32(stringRep) + _, errVal = conv.ConvertInt32(stringRep) case integerFormatUInt32: - _, errVal = swag.ConvertUint32(stringRep) + _, errVal = conv.ConvertUint32(stringRep) case integerFormatUInt64: - _, errVal = swag.ConvertUint64(stringRep) + _, errVal = conv.ConvertUint64(stringRep) case integerFormatInt64: fallthrough default: - _, errVal = swag.ConvertInt64(stringRep) + _, errVal = conv.ConvertInt64(stringRep) } case numberType: fallthrough default: switch format { case numberFormatFloat, numberFormatFloat32: - _, errVal = swag.ConvertFloat32(stringRep) + _, errVal = conv.ConvertFloat32(stringRep) case numberFormatDouble, numberFormatFloat64: fallthrough default: