diff --git a/Makefile b/Makefile index cb484f175..a6f14752b 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ CIRRUS_CLI ?= v1.0.0 # renovate: datasource=github-releases depName=actions/runner GITHUB_RUNNER ?= 2.336.0 # renovate: datasource=gitlab-releases depName=gitlab-org/gitlab-runner -GITLAB_RUNNER ?= 19.3.0 +GITLAB_RUNNER ?= 19.3.1 # renovate: datasource=github-releases depName=open-telemetry/opentelemetry-collector-releases OTELCOL_VERSION ?= 0.151.0 diff --git a/go.mod b/go.mod index dd2d6f27a..cd5417fed 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.26.0 replace ( github.com/charmbracelet/bubbles/v2 => charm.land/bubbles/v2 v2.1.1 - github.com/charmbracelet/bubbletea/v2 => charm.land/bubbletea/v2 v2.0.8 + github.com/charmbracelet/bubbletea/v2 => charm.land/bubbletea/v2 v2.0.9 github.com/charmbracelet/lipgloss/v2 => charm.land/lipgloss/v2 v2.0.6 ) @@ -14,13 +14,13 @@ require ( github.com/pulumi/pulumi-command/sdk v1.2.1 github.com/pulumi/pulumi-random/sdk/v4 v4.21.1 github.com/pulumi/pulumi/sdk/v3 v3.258.0 - github.com/sirupsen/logrus v1.10.1 + github.com/sirupsen/logrus v1.10.2 github.com/spf13/cobra v1.10.2 ) require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.1 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v7 v7.3.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.10.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 @@ -71,7 +71,7 @@ require ( github.com/go-git/gcfg/v2 v2.0.2 // indirect github.com/go-git/go-billy/v6 v6.0.0-alpha.2 // indirect github.com/go-git/go-git/v6 v6.0.0-alpha.5 // indirect - github.com/go-openapi/swag/pools v0.28.0 // indirect + github.com/go-openapi/swag/pools v0.29.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/godbus/dbus/v5 v5.2.2 // indirect @@ -84,15 +84,15 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/stretchr/objx v0.5.3 // indirect github.com/zalando/go-keyring v0.2.8 // indirect - go.opentelemetry.io/contrib/bridges/otelslog v0.20.0 // indirect + go.opentelemetry.io/contrib/bridges/otelslog v0.20.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.21.0 // indirect - go.opentelemetry.io/otel/log v0.21.0 // indirect + go.opentelemetry.io/otel/log v0.22.0 // indirect go.opentelemetry.io/otel/sdk/log v0.21.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect ) require ( - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.38 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.30 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.38 // indirect @@ -121,12 +121,12 @@ require ( github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.37 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.37 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.37 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.17 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.37 // indirect github.com/aws/aws-sdk-go-v2/service/signin v1.5.6 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.33.6 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.38.6 // indirect - github.com/aws/smithy-go v1.27.8 // indirect + github.com/aws/smithy-go v1.28.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect // github.com/charmbracelet/bubbles v1.0.0 // indirect @@ -144,27 +144,27 @@ require ( github.com/fxamacker/cbor/v2 v2.9.3 // indirect github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.26.0 // indirect + github.com/go-openapi/analysis v0.26.2 // indirect github.com/go-openapi/errors v0.22.8 // indirect github.com/go-openapi/jsonpointer v1.0.0 // indirect - github.com/go-openapi/jsonreference v1.0.0 // indirect - github.com/go-openapi/loads v0.25.1 // indirect - github.com/go-openapi/runtime v0.33.0 // indirect - github.com/go-openapi/runtime/server-middleware v0.33.0 // indirect - github.com/go-openapi/spec v0.22.9 // indirect + github.com/go-openapi/jsonreference v1.0.1 // indirect + github.com/go-openapi/loads v0.25.2 // indirect + github.com/go-openapi/runtime v0.33.1 // indirect + github.com/go-openapi/runtime/server-middleware v0.33.1 // indirect + github.com/go-openapi/spec v0.22.11 // indirect github.com/go-openapi/strfmt v0.27.0 // indirect github.com/go-openapi/swag v0.28.0 // indirect github.com/go-openapi/swag/cmdutils v0.28.0 // indirect - github.com/go-openapi/swag/conv v0.28.0 // indirect - github.com/go-openapi/swag/fileutils v0.28.0 // indirect - github.com/go-openapi/swag/jsonutils v0.28.0 // indirect - github.com/go-openapi/swag/loading v0.28.0 // indirect - github.com/go-openapi/swag/mangling v0.28.0 // indirect + github.com/go-openapi/swag/conv v0.29.1 // indirect + github.com/go-openapi/swag/fileutils v0.29.1 // indirect + github.com/go-openapi/swag/jsonutils v0.29.1 // indirect + github.com/go-openapi/swag/loading v0.29.1 // indirect + github.com/go-openapi/swag/mangling v0.29.1 // indirect github.com/go-openapi/swag/netutils v0.28.0 // indirect - github.com/go-openapi/swag/stringutils v0.28.0 // indirect - github.com/go-openapi/swag/typeutils v0.28.0 // indirect - github.com/go-openapi/swag/yamlutils v0.28.0 // indirect - github.com/go-openapi/validate v0.26.3 // indirect + github.com/go-openapi/swag/stringutils v0.29.1 // indirect + github.com/go-openapi/swag/typeutils v0.29.1 // indirect + github.com/go-openapi/swag/yamlutils v0.29.1 // indirect + github.com/go-openapi/validate v0.26.5 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golang/glog v1.2.5 // indirect @@ -204,12 +204,12 @@ require ( go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/featuregate v1.65.0 // indirect go.opentelemetry.io/collector/pdata v1.65.0 // indirect - go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel v1.46.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.46.0 // indirect go.opentelemetry.io/otel/sdk v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.46.0 // indirect go.opentelemetry.io/proto/otlp v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect @@ -236,7 +236,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ecs v1.90.2 github.com/aws/aws-sdk-go-v2/service/iam v1.59.1 github.com/blang/semver v3.5.1+incompatible // indirect - github.com/cheggaaa/pb v1.0.29 // indirect + github.com/cheggaaa/pb v1.0.30 // indirect github.com/djherbis/times v1.6.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/fsnotify/fsnotify v1.10.1 // indirect @@ -269,7 +269,7 @@ require ( golang.org/x/sys v0.47.0 // indirect golang.org/x/term v0.45.0 // indirect golang.org/x/text v0.41.0 // indirect - google.golang.org/grpc v1.83.0 // indirect + google.golang.org/grpc v1.83.2 // indirect google.golang.org/protobuf v1.36.12 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect lukechampine.com/frand v1.5.1 // indirect diff --git a/go.sum b/go.sum index 249dd8a7e..7543f93e3 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.0 h1:4gRPBpN1f6xt88yi4WR26m7XaD9OlWtVT6bWPdGUIok= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.0/go.mod h1:G7QVLxw1j1JVyrO1MA95S8m8HStaaleDZYTcfGgjB2o= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0 h1:CU4+EJeJi3TKYWEcYuSdWsjzw0nVsK/H0MSQOiPcymU= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0/go.mod h1:q0+UTSRvShwUCrR/s5HtyInYphN7Wvxb7snFM3u+SLA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.1 h1:zvXfGJCWvywnCA814d8ZiVyt+fm9nnTE8xSb99zRyfo= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.1/go.mod h1:iptorS+VYKFL2N6PnebpS91dubG35eAOEERnT4PJbQU= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.1 h1:u93s+zU2JD62im61Bm5CZIc1ZrOJaIAWEg0WOrMVkEo= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.1/go.mod h1:oXtinPO4OLj9d1DOTrqrL1oRwGhcqadvAmrl6wTeGlk= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.4.0 h1:xFaZZ+IubdftrDHnGGwZ6QvQ3KHTtWl2MCK+GMt2vxs= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.4.0/go.mod h1:mCBhUhlMjLLJKr5aqw2TNS/VqJOie8MzWq3DAMJeKso= github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4= @@ -68,8 +68,8 @@ github.com/aws/amazon-ec2-instance-selector/v3 v3.1.3 h1:13qtG4reL2+2UiCm2U7gM9Q github.com/aws/amazon-ec2-instance-selector/v3 v3.1.3/go.mod h1:wdlMRtz9G4IO6H1yZPsqfGBxR8E6B/bdxHlGkls4kGQ= github.com/aws/aws-sdk-go-v2 v1.43.6 h1:RrmFcqCBxkJuf7g1axVo5krB4jM/AO8r5e5oujrgdoQ= github.com/aws/aws-sdk-go-v2 v1.43.6/go.mod h1:tXpPM+v0D1lndmga+HqqLDIzUFJlEeR21aspVklHF00= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18 h1:LAfOuhAH331fmOjTQpAaOlH+Ftn7RzSDJ2VFwjdMMy4= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18/go.mod h1:4e5xhuXHx1e4U9EthvbPP1r/DIMp5c2823OL8karzcM= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20 h1:GPRlPwz40I2B2VrBEASOA3Bi77NyeqejNLkifosX0rs= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20/go.mod h1:g7PNzKcsOKWb4fkSRBA7BZVAS6Y8IcxzN+nRohhQ1Q8= github.com/aws/aws-sdk-go-v2/config v1.32.37 h1:Ljl7LOJB6ym0liuEl0+TZ3d7f5I8MEZN1Cj9PINlj/g= github.com/aws/aws-sdk-go-v2/config v1.32.37/go.mod h1:WJ7pe7ZPpmG8Q5kKS53zeypIV4FBGACxmte8Uc6SgUc= github.com/aws/aws-sdk-go-v2/credentials v1.19.36 h1:84s5xMme6ENYEdKG8rsbSFFg/8+lbHBeM9QYSO0gnDk= @@ -88,8 +88,8 @@ github.com/aws/aws-sdk-go-v2/service/ecs v1.90.2 h1:qVT/ixJEmfC2SAv4FdkpTFRLt7re github.com/aws/aws-sdk-go-v2/service/ecs v1.90.2/go.mod h1:bZR2sTaOf5t+iLUB756XNv2HJhMFav1GLUbD8XNu4Dk= github.com/aws/aws-sdk-go-v2/service/iam v1.59.1 h1:Dr7wQQgyc9YVkIR6AWIOSWuOFZ6A0K2jFL6Ld6uJQ1E= github.com/aws/aws-sdk-go-v2/service/iam v1.59.1/go.mod h1:WmY9HZODfCg9inthJD2PctQbn7uEMMGnSv5MZ2BIjcM= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.17 h1:OvYZOB3qA6zvfdRFiRFRzVSiElMYrz3GdntkXZxlp1o= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.17/go.mod h1:JgR/2Ew50ACfIWau1oeMRX59tMtC0kM+PYQGEaT04cY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19 h1:bAdDl/HkGCcGPoe25ToSHEw23VIxt6CT5fLcg111BKg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19/go.mod h1:KaUzbLxv4CeSxh6ZCl9B4m7CuFenS8kUEaDs+f/DQr4= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.30 h1:5437eMoOwqqQpZn2XJy74mlDCuPYL81texMT3mXqgtU= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.30/go.mod h1:xfu2m3dOpvW8lj98wQYa8V9ku/Rta59hsbireGzhh3A= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.37 h1:a3D4AjrOrTrP8+d9ILBthqrElf0z1JNol09Xvnwcys8= @@ -108,8 +108,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.38.6 h1:49BBtY68A+KJCQ3a2F3eUe6R github.com/aws/aws-sdk-go-v2/service/ssooidc v1.38.6/go.mod h1:ptG2hbs7QltE1GcQY0MpS4bfrc51KCnBXUr7OT1EEfE= github.com/aws/aws-sdk-go-v2/service/sts v1.45.6 h1:JvExZWabChDM0qJAirQYGfOYo0ndT3edXj+fqSPNjkE= github.com/aws/aws-sdk-go-v2/service/sts v1.45.6/go.mod h1:XZcaQkV2cItp6yEkrwljyaPOf22RuX7T43jxap/FOmM= -github.com/aws/smithy-go v1.27.8 h1:FR0dxZfIlV7Z8eh2iHfIofdunw382XsDV3Mxt9nUvRY= -github.com/aws/smithy-go v1.27.8/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/smithy-go v1.28.1 h1:R/nXH00c8qcfCzQVELtRw+eLQWtzv+VAIEFJ1/xxXlQ= +github.com/aws/smithy-go v1.28.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o= @@ -140,8 +140,8 @@ github.com/charmbracelet/x/exp/golden v0.0.0-20260816001655-68d539dca504 h1:6OnD github.com/charmbracelet/x/exp/golden v0.0.0-20260816001655-68d539dca504/go.mod h1:6fMpcW6iwN/kX+xJ52eqVWsDiBTe0UJD24JLoHFe+P0= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= -github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= -github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= +github.com/cheggaaa/pb v1.0.30 h1:NylhgqJfXx3JVBGx6ywsXuhpz8caSMPmLArXyAv1bwU= +github.com/cheggaaa/pb v1.0.30/go.mod h1:YgTBwa6PqwwDB/2UKdLuuFRNTwEkcCPsA5AmWivrBAg= github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= @@ -204,56 +204,56 @@ github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/analysis v0.26.0 h1:1xECln1iMMmQnTjgcknC1vi1hA4KISt6IHpSwnqcuwI= -github.com/go-openapi/analysis v0.26.0/go.mod h1:40gERFi/2dyXA1FaqRRLxkv1IlC6X+GPDNd1xrYAjZE= +github.com/go-openapi/analysis v0.26.2 h1:Q6wOwXW8mcVAkpDFMshj/F4PlK2Fx86tmLJjZW4vyEs= +github.com/go-openapi/analysis v0.26.2/go.mod h1:KAxGydTYCbs6dK9zjCMQ1AoEVD2RzSWEQNgmb64dRpI= github.com/go-openapi/errors v0.22.8 h1:oP7sW7TWc3wFFjrzzj0nI83H2qMBkNjNfSd+XRejk/I= github.com/go-openapi/errors v0.22.8/go.mod h1:BuUoHcYrU6E7V9gfj1I5wLQqgtIHnup/alXZ8KdgQ0w= github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s= github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= -github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY= -github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0= -github.com/go-openapi/loads v0.25.1 h1:toKQdIDLxlqfKLLGUUmUsiTd5/X0Chzvde9EGYQP/Ac= -github.com/go-openapi/loads v0.25.1/go.mod h1:33Hen4tsKXHL45TyYojvfD5fZUFN4O1y4r/XhsRW2zc= -github.com/go-openapi/runtime v0.33.0 h1:Dd3Oj2ig+WH8ckK95l0Wn2V8a4bH/UqWPRZVT0vc8yU= -github.com/go-openapi/runtime v0.33.0/go.mod h1:+rsupH3+TFKqmFysqkmgBOTxpVJV8eV+j9myvvea2Xw= -github.com/go-openapi/runtime/server-middleware v0.33.0 h1:ZFUNyaa2eUs9DhLd6MTe/QRsuxeYn4Lq0C8iAoY13XE= -github.com/go-openapi/runtime/server-middleware v0.33.0/go.mod h1:OQHTBqMGquJShXhPYQ62yAqDMtC1rYpsEwldNWjYKhA= -github.com/go-openapi/spec v0.22.9 h1:/vKIFDcGKp0ktZWGbym/tJEWbk6/XOEmAVU0kqKMH+w= -github.com/go-openapi/spec v0.22.9/go.mod h1:b/mNUYIOQOyIiUzUzXEE8xzyZqf93KvM9hQGP91yfl0= +github.com/go-openapi/jsonreference v1.0.1 h1:4zJ7AmYDKNmD3aSpfPnFNCFA5E80/xMHUNKgydaLh38= +github.com/go-openapi/jsonreference v1.0.1/go.mod h1:dYplQXa6p5lXprLcJ8LE2iU7vNpXsAHDQ5ZAgL+Qx3A= +github.com/go-openapi/loads v0.25.2 h1:+uNsDlRQfYtZTrh+3pdwampcAqZVPuBJW0IA82aZHII= +github.com/go-openapi/loads v0.25.2/go.mod h1:RXsfJEQGGNv4uw8u/KdmF8Vh8OR4fTfs9ZO4QrzNohA= +github.com/go-openapi/runtime v0.33.1 h1:jCvhI+wAdsn29byy+RgcPcg+j39YT6E304QOE/WqIVk= +github.com/go-openapi/runtime v0.33.1/go.mod h1:Dl5SMVRnJz+d8bX6Y1zxy0QKpqe/ysvVeUEh1nCpEZ4= +github.com/go-openapi/runtime/server-middleware v0.33.1 h1:IAeKbwWnBnpsYTpuPVS8t73ZrPpKvRZnK2iJ2KJGUV0= +github.com/go-openapi/runtime/server-middleware v0.33.1/go.mod h1:2Gej5fDxqeJxY+w38vxXYW0BgFASfgBsJ5rXwN1Fseg= +github.com/go-openapi/spec v0.22.11 h1:/ZW28n4PCghbBpwjmvoMeyCeDwd6pIe715Ov8T3kAaQ= +github.com/go-openapi/spec v0.22.11/go.mod h1:Ypu+u1KTejey7/QCr3j1ChdjwhGgXuklbH7l8+YP1J4= github.com/go-openapi/strfmt v0.27.0 h1:kbcTeaD9TXuXD0hhMXzuYa1sdTo6+dWGvwjW93E80IM= github.com/go-openapi/strfmt v0.27.0/go.mod h1:s/qhDqfY72irigXUGJmtgid2Rm+3tnz3k8hZaRmvWYc= github.com/go-openapi/swag v0.28.0 h1:xkgbOSKj6DZziNpyqRRAOt3GJGtgjgsd2RoyT30VWuw= github.com/go-openapi/swag v0.28.0/go.mod h1:4qYnT3Cqr1p1VknOdPo70evN4rgQnAg6jwApHyxSGIg= github.com/go-openapi/swag/cmdutils v0.28.0 h1:7TOeNtkYru1SG8Y34tDh9WBbLsMqGnptuxWiHREPZ4Q= github.com/go-openapi/swag/cmdutils v0.28.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= -github.com/go-openapi/swag/conv v0.28.0 h1:GtqqbyFe7vR5Y7ehxG9W6/OvrSFdf1OLeTGp40TqxH8= -github.com/go-openapi/swag/conv v0.28.0/go.mod h1:mbUE+mzctnhxi864m0Q07SpN8OowD9JhxmxuYvZZD/k= -github.com/go-openapi/swag/fileutils v0.28.0 h1:Z04XWQD7R8Eq+7GnOrjovBxPPmZzsS4gt2H2GPGIViU= -github.com/go-openapi/swag/fileutils v0.28.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= -github.com/go-openapi/swag/jsonutils v0.28.0 h1:YIch6FwO7RXzeAnbO8Tu7dWBZeUEH+4nA0HXltVTnv4= -github.com/go-openapi/swag/jsonutils v0.28.0/go.mod h1:CYM3WlTUcagR2ZoHdz54di/cbBqt82tuxuXgAjxw+mg= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0 h1:qV+VVUAx5Oro8WjVWpZeql7YReTKhT4smR4zhcOQZr0= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= -github.com/go-openapi/swag/loading v0.28.0 h1:td8QZdZC9MIYGGSnSPKShKiK22I2tU5UQvuUhIBPRLU= -github.com/go-openapi/swag/loading v0.28.0/go.mod h1:rXB0QiQX5mMveXEA7ouM4KiiM9jVJe4K6BVbwhD1M4k= -github.com/go-openapi/swag/mangling v0.28.0 h1:pH8eyeNO9SLYsTMWJrurnNfKmDa28XrlA+HePVD53VM= -github.com/go-openapi/swag/mangling v0.28.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= +github.com/go-openapi/swag/conv v0.29.1 h1:AC4Eh/5c/eUDOUCzzsRC9ghmFgOSBHeRMGIngY0ZUGA= +github.com/go-openapi/swag/conv v0.29.1/go.mod h1:S1X7/ZrBEZOC0Wc8AGxjbcGS92l3WEjA7aPtpl+RaqM= +github.com/go-openapi/swag/fileutils v0.29.1 h1:ZcPzMceVhU1WPbK6N1G6sNQKdd1CWJlf3cA08UHuoM0= +github.com/go-openapi/swag/fileutils v0.29.1/go.mod h1:/wofKYckbtRl2p3+EwQsosie5CT1B38+dQ+PS579BzI= +github.com/go-openapi/swag/jsonutils v0.29.1 h1:AFCxs0eQZ24/QyfhVHM2t49rMz7Vv3XCsZQI6yrNy+c= +github.com/go-openapi/swag/jsonutils v0.29.1/go.mod h1:u3+sCfJpttDpcmS5kpm0yxL6GK0eWgODsx8Yw8fcqNM= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.29.1 h1:BiiXE31Bx9SfpsMmOQj5KYpUhTZBpLVriVhJDuLuY2o= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.29.1/go.mod h1:julgTUKZ9/D0j6O7GKajmRs+812FWxQg/mMpGunWSjg= +github.com/go-openapi/swag/loading v0.29.1 h1:FCv5fG8UhTdDJa2R7w+5O9Ekpcbw7tt0nFWvmDKGBjc= +github.com/go-openapi/swag/loading v0.29.1/go.mod h1:N0ESuem4p2oedKal8EJhciqnJ9Q9Wmt83L1CRB3Fouw= +github.com/go-openapi/swag/mangling v0.29.1 h1:lHALtvYCdxVnRl4GrHmFPwfBTZYIObqdGNSKyu/8D6I= +github.com/go-openapi/swag/mangling v0.29.1/go.mod h1:SAop9pB7PUjQ/CGCNf/JmCKTRK+GDO+RqE9UHqC/N6s= github.com/go-openapi/swag/netutils v0.28.0 h1:YXN6TALEi2pzts8/8GNm6T61HTAZsieukGZidap989k= github.com/go-openapi/swag/netutils v0.28.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= -github.com/go-openapi/swag/pools v0.28.0 h1:HPMZWSAfce3rdVTFcjFiCIBtDg9h4x2QlRrHipwhxeU= -github.com/go-openapi/swag/pools v0.28.0/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE= -github.com/go-openapi/swag/stringutils v0.28.0 h1:ixsc9iYgDPubHL/8nSkbnryEHpD2VRlBMLKpQyPXcDU= -github.com/go-openapi/swag/stringutils v0.28.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= -github.com/go-openapi/swag/typeutils v0.28.0 h1:nRBKSBXjDgf01VDPB3fWeD9nQuhCOVeIYAkUx2tbkyY= -github.com/go-openapi/swag/typeutils v0.28.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= -github.com/go-openapi/swag/yamlutils v0.28.0 h1:TV3JXH6DS46KUroDtMLAYHGkdWf5VDq3wVWFirmzROY= -github.com/go-openapi/swag/yamlutils v0.28.0/go.mod h1:x0q/yndZHEgk9Rx3DyDqzFUmHy55KTvIZldvF2dTJXs= -github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0= -github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo= -github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug= -github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= -github.com/go-openapi/validate v0.26.3 h1:OkfZgLvLDnGP2hrRGD+42WBiPWWkoHomTJ+IVI+KaDc= -github.com/go-openapi/validate v0.26.3/go.mod h1:7DOOa4raU6NRe7A8VQSKbm3VcuUIioREYHFt+er9Sk8= +github.com/go-openapi/swag/pools v0.29.1 h1:NRogYxdEW9SjRM4mkAOji9iefO4MRXq3p/ZJcoQbUKg= +github.com/go-openapi/swag/pools v0.29.1/go.mod h1:leDcaghjkRAhCuCRv9NfJU5f0mjoU3cT/XZObhMk3pc= +github.com/go-openapi/swag/stringutils v0.29.1 h1:1ykunK7iJQk1uOO7+oUH1ukbsK85fFCOiCFMOVSY+F0= +github.com/go-openapi/swag/stringutils v0.29.1/go.mod h1:7fSqZ+z8Qc0tOfAAK0jVa5qFGrnIlRi6n7NeGGrr1vc= +github.com/go-openapi/swag/typeutils v0.29.1 h1:Nzv9nhnlLCRBPQqfOX+7lB6Guju370or8StT+lIOf6M= +github.com/go-openapi/swag/typeutils v0.29.1/go.mod h1:hxpgDZJVBkBsi/d3MIUosafoFdE5exaQRmVp0zwu3YE= +github.com/go-openapi/swag/yamlutils v0.29.1 h1:69w3tsBajm7MR/fejLy7HD/3J68Ys1SeeZMEzZ3w2sk= +github.com/go-openapi/swag/yamlutils v0.29.1/go.mod h1:rgsp3vT/QdWzKwn43CigDwjOGIenPyTZMKnxEM8jZOA= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.1 h1:Jm+/ze2rMtbD98yen92AhATGLGREDYXG56Xr4gMjEtE= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.1/go.mod h1:YDPnwCRDu38/oJBVMBVXOUDiJ9cIeBHWvfImHaXqnv4= +github.com/go-openapi/testify/v2 v2.7.0 h1:bycOreEj6wfBvijg3YFogZ/sFjTCDmQnwSodSzHa3X8= +github.com/go-openapi/testify/v2 v2.7.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= +github.com/go-openapi/validate v0.26.5 h1:Vm02dSmhevDx/4v4m8KAtMwffHGfq9wRLqICeebE/D4= +github.com/go-openapi/validate v0.26.5/go.mod h1:2VVi2kpxSvInv/OOI6echOcYddydjXOxJvkHQ5VsoZw= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -466,8 +466,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/sirupsen/logrus v1.10.1 h1:xi4336Zh11WpU14fXR6I67V3yaTPQYwRx2WEtHbRg4Q= -github.com/sirupsen/logrus v1.10.1/go.mod h1:vsQHnG7xzNsxk3NrwboUiWPnIC3dmbjcGPykD7+tiHk= +github.com/sirupsen/logrus v1.10.2 h1:G2SED73/qrAu6YwbdxOD6peLkCBI3z7L+ykJFTXJBBo= +github.com/sirupsen/logrus v1.10.2/go.mod h1:SLEg8TqYulVKKfIGHldVp2K2aYz2DKSVBq4g/H5bR7Q= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= @@ -485,8 +485,8 @@ github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+Q github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI= -github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= @@ -513,20 +513,20 @@ go.opentelemetry.io/collector/internal/testutil v0.159.0 h1:/OfAv3ZRIc3eVFFq4bFc go.opentelemetry.io/collector/internal/testutil v0.159.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= go.opentelemetry.io/collector/pdata v1.65.0 h1:6bQ3sIrEzOdapetxYFjdCns90kKXg1qCoIZ3la1aR5E= go.opentelemetry.io/collector/pdata v1.65.0/go.mod h1:r5vRY0p7nZcEif06twUW09Sf6vaNsyPzij+EpwI/xeI= -go.opentelemetry.io/contrib/bridges/otelslog v0.20.0 h1:oEl2Pw/i4OQwhAuda2pAHFAcOMivA+Xa+iTccBfab/g= -go.opentelemetry.io/contrib/bridges/otelslog v0.20.0/go.mod h1:yMSQaiiq5dpfrSJCYLBcqFeJkFFI67seT4ngvx6jfVo= -go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= -go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= +go.opentelemetry.io/contrib/bridges/otelslog v0.20.1 h1:5sHc4ToTFjfSZCtGAAM6jPunICAmJX73htv372T4ipc= +go.opentelemetry.io/contrib/bridges/otelslog v0.20.1/go.mod h1:oa6kgvyz/3GYW04dohd0++xJIH4xdQY8PAbpeCMaM8M= +go.opentelemetry.io/otel v1.46.0 h1:FHt5/CDyVxi/8IM1CH7VE/rRgq3kLHa2mSTVMO8AWyc= +go.opentelemetry.io/otel v1.46.0/go.mod h1:Gj3SEScelsNC45tp4nSxRYlS+f5iez7W8XPMCt905kE= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.21.0 h1:WseeVYf5dJZTsyPiyW5L14k5qsSibqXAMTSiFEDiWr0= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.21.0/go.mod h1:SiLZnQS6Qk2eCpvr2CH/XMAOa64TWGXxEZJZCpD2Lmc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 h1:QRefszxJmfPdjXUUm3j6iDzY03mTPXMjqErFqQ67vUg= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0/go.mod h1:Tiz03lTBVBrm7eWZBOidzEaYaJa8tjwGUGv6d8mlTyk= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 h1:fG5MCxGz8+2VtrN/WgqSpJFctVz24gpxj8CxkKmc8Ww= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0/go.mod h1:BmAYTn+3ysbRe+IU2msxmf5Rx3g6DHvex+tWI3LdhYI= -go.opentelemetry.io/otel/log v0.21.0 h1:SLsVDGmtyBrdw8/a2Z0bOIxou/+bN4z56GebH7T0LvA= -go.opentelemetry.io/otel/log v0.21.0/go.mod h1:iReetQrZL9Wyg84cCkOoCmqDHS5RCFfyxC7J+r8fn8g= -go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= -go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= +go.opentelemetry.io/otel/log v0.22.0 h1:5DBNnfvaJ6CVdkJ+Jle8Tzs50aSSv49TXGj9XRsEYw0= +go.opentelemetry.io/otel/log v0.22.0/go.mod h1:gzOt/R67vF2GniAqWu8Qv0SXy89f71muHcrkz76PCdc= +go.opentelemetry.io/otel/metric v1.46.0 h1:yBnkXvgV7AXFILZc5K6IZe/CBFF3OS7BJ8ov6/lj0K8= +go.opentelemetry.io/otel/metric v1.46.0/go.mod h1:iPmdWqifKUdzziPkvvzIJXITl56fQx2mGM/DHLB3/2o= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/log v0.21.0 h1:QsE7XSR0ktQdKmRKGnR+f1ObGF32WG+7MER/P9KgmYc= @@ -535,8 +535,8 @@ go.opentelemetry.io/otel/sdk/log/logtest v0.21.0 h1:X+JBBgKlswCGYsmgL0CnoUUtlE// go.opentelemetry.io/otel/sdk/log/logtest v0.21.0/go.mod h1:HD1575K8e6sIFBBDd5tZB3t9DlMytWXq9FuR+Y4rfjE= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= -go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= +go.opentelemetry.io/otel/trace v1.46.0 h1:OULy7ccdJnZtJ0UDYFOIGaCmiWzJ8Vi2G/Rsu60qs1c= +go.opentelemetry.io/otel/trace v1.46.0/go.mod h1:J7GAXweO77XSFkB/rmAqk9D6ihszhFjLU+d9WuUxDLI= go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk= go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E= go.opentelemetry.io/proto/slim/otlp v1.11.0 h1:zB37f+f99+y6UIZR4h7UpwbXd5kFNyip35U7GaJ/Jik= @@ -622,8 +622,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260818201246-1b0934165a6f h1: google.golang.org/genproto/googleapis/api v0.0.0-20260818201246-1b0934165a6f/go.mod h1:q/3oV3jAi5vwelxsVAprMBC8BcM2zmNe+IjRGd+9/ks= google.golang.org/genproto/googleapis/rpc v0.0.0-20260818201246-1b0934165a6f h1:kMQMi+2r0XRQ/Ad2/tgd+5S7JYSBGYO4pwkLTE8F2y0= google.golang.org/genproto/googleapis/rpc v0.0.0-20260818201246-1b0934165a6f/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ= -google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tools/go.mod b/tools/go.mod index 0d0da84a1..59a9d6925 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -4,7 +4,7 @@ go 1.26.0 replace ( github.com/charmbracelet/bubbles/v2 => charm.land/bubbles/v2 v2.1.1 - github.com/charmbracelet/bubbletea/v2 => charm.land/bubbletea/v2 v2.0.8 + github.com/charmbracelet/bubbletea/v2 => charm.land/bubbletea/v2 v2.0.9 github.com/charmbracelet/lipgloss/v2 => charm.land/lipgloss/v2 v2.0.6 ) @@ -112,7 +112,7 @@ require ( github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/gofrs/flock v0.13.0 // indirect + github.com/gofrs/flock v0.13.1 // indirect github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202 // indirect github.com/golangci/go-printf-func-name v0.1.1 // indirect; ind github.com/golangci/misspell v0.8.0 // indirect @@ -173,7 +173,7 @@ require ( github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect - github.com/raeperd/recvcheck v0.3.0 // indirect + github.com/raeperd/recvcheck v0.3.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.16.0 // indirect github.com/ryanrolds/sqlclosecheck v0.6.0 // indirect @@ -183,7 +183,7 @@ require ( github.com/sashamelentyev/interfacebloat v1.1.0 // indirect github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect github.com/securego/gosec/v2 v2.28.0 // indirect - github.com/sirupsen/logrus v1.10.1 // indirect + github.com/sirupsen/logrus v1.10.2 // indirect github.com/sivchari/containedctx v1.0.3 // indirect github.com/sonatard/noctx v0.5.1 // indirect github.com/sourcegraph/go-diff v0.8.0 // indirect @@ -195,7 +195,7 @@ require ( github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.3.1 // indirect github.com/stretchr/objx v0.5.3 // indirect - github.com/stretchr/testify v1.12.0 // indirect + github.com/stretchr/testify v1.12.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tetafro/godot v1.5.6 // indirect github.com/timakin/bodyclose v0.0.0-20260723120731-857993a2939c // indirect @@ -205,7 +205,7 @@ require ( github.com/ultraware/funlen v0.2.0 // indirect github.com/ultraware/whitespace v0.2.0 // indirect github.com/uudashr/gocognit v1.2.1 // indirect - github.com/uudashr/iface v1.5.0 // indirect + github.com/uudashr/iface v1.5.1 // indirect github.com/xen0n/gosmopolitan v1.3.0 // indirect github.com/xo/terminfo v1.0.0 // indirect github.com/yagipy/maintidx v1.0.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index e332ad2ac..b95b19d35 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -172,8 +172,8 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godoc-lint/godoc-lint v0.11.2 h1:Bp0FkJWoSdNsBikdNgIcgtaoo+xz6I/Y9s5WSBQUeeM= github.com/godoc-lint/godoc-lint v0.11.2/go.mod h1:iVpGdL1JCikNH2gGeAn3Hh+AgN5Gx/I/cxV+91L41jo= -github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= -github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= +github.com/gofrs/flock v0.13.1 h1:jjREztyBeSKBZYAC+mgc1laB+xsgy4kYMf3FbKF2UBo= +github.com/gofrs/flock v0.13.1/go.mod h1:sf4BFiHwnvgxa25DlQoDqXQnwRMEOwqxRq37P6MzzmE= github.com/golangci/asciicheck v0.5.0 h1:jczN/BorERZwK8oiFBOGvlGPknhvq0bjnysTj4nUfo0= github.com/golangci/asciicheck v0.5.0/go.mod h1:5RMNAInbNFw2krqN6ibBxN/zfRFa9S6tA1nPdM0l8qQ= github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202 h1:CbTB8KpqnViI6lIXxp03Oclc4VFHi3K4BWC1TacsZ+A= @@ -340,8 +340,8 @@ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= -github.com/raeperd/recvcheck v0.3.0 h1:PM+XYvyxIj3bo+kobJfFTdTuU3Lmfu96mKDbyHDbRt8= -github.com/raeperd/recvcheck v0.3.0/go.mod h1:PZNwG+HztFYMH2ZPq0Hu3QgkV2yiA6VrtNz9c1fXWJo= +github.com/raeperd/recvcheck v0.3.1 h1:p7nZMxiCWkdUtY2i3o+pv1h4fJCR5gpvqAXr9326hEY= +github.com/raeperd/recvcheck v0.3.1/go.mod h1:CbE7iRocQ4uc71JwpW/CPSh4BShnkre4A9Gb508RypU= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.16.0 h1:O9DK+vNMDVGLr2BeZqmpLeMjiMNkuXfcqntWbZV6S5g= @@ -367,8 +367,8 @@ github.com/securego/gosec/v2 v2.28.0 h1:ZsSdiDb0AtTpLFVol5z91gbMei9ZiLEPG/pZjZuj github.com/securego/gosec/v2 v2.28.0/go.mod h1:lb4/9AHe+lJy/kjWmWRWWsEipvbwGKuxf+tY1Pmjdnk= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sirupsen/logrus v1.10.1 h1:xi4336Zh11WpU14fXR6I67V3yaTPQYwRx2WEtHbRg4Q= -github.com/sirupsen/logrus v1.10.1/go.mod h1:vsQHnG7xzNsxk3NrwboUiWPnIC3dmbjcGPykD7+tiHk= +github.com/sirupsen/logrus v1.10.2 h1:G2SED73/qrAu6YwbdxOD6peLkCBI3z7L+ykJFTXJBBo= +github.com/sirupsen/logrus v1.10.2/go.mod h1:SLEg8TqYulVKKfIGHldVp2K2aYz2DKSVBq4g/H5bR7Q= github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= github.com/sonatard/noctx v0.5.1 h1:wklWg9c9ZYugOAk7qG4yP4PBrlQsmSLPTvW1K4PRQMs= @@ -396,8 +396,8 @@ github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI= -github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= @@ -420,8 +420,8 @@ github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSW github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8= github.com/uudashr/gocognit v1.2.1 h1:CSJynt5txTnORn/DkhiB4mZjwPuifyASC8/6Q0I/QS4= github.com/uudashr/gocognit v1.2.1/go.mod h1:acaubQc6xYlXFEMb9nWX2dYBzJ/bIjEkc1zzvyIZg5Q= -github.com/uudashr/iface v1.5.0 h1:PgdMt4uAettGG8K/Kbamc4B9FABgUgnS3TLbl6fnjEk= -github.com/uudashr/iface v1.5.0/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg= +github.com/uudashr/iface v1.5.1 h1:BS3yrgaT55s3dAtJoxuTnsZNbsejq/mVuzp49YDyfBA= +github.com/uudashr/iface v1.5.1/go.mod h1:5UWoT6SvTdTww/KToRj6clO+n4Kg3/NrAQvgOB+5Ggw= github.com/xen0n/gosmopolitan v1.3.0 h1:zAZI1zefvo7gcpbCOrPSHJZJYA9ZgLfJqtKzZ5pHqQM= github.com/xen0n/gosmopolitan v1.3.0/go.mod h1:rckfr5T6o4lBtM1ga7mLGKZmLxswUoH1zxHgNXOsEt4= github.com/xo/terminfo v1.0.0 h1:2ZpYzqWzyyytjk3TP6aJVDhkMAkc99/1xKQdA3TDTBY= @@ -546,8 +546,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 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/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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/tools/vendor/github.com/gofrs/flock/.golangci.yml b/tools/vendor/github.com/gofrs/flock/.golangci.yml index bc837b266..b35be7de8 100644 --- a/tools/vendor/github.com/gofrs/flock/.golangci.yml +++ b/tools/vendor/github.com/gofrs/flock/.golangci.yml @@ -6,7 +6,9 @@ formatters: - goimports settings: gofumpt: - extra-rules: true + extra: + clothe-returns: true + group-params: true linters: enable: diff --git a/tools/vendor/github.com/gofrs/flock/flock.go b/tools/vendor/github.com/gofrs/flock/flock.go index 4cb0746a7..156c4bf2b 100644 --- a/tools/vendor/github.com/gofrs/flock/flock.go +++ b/tools/vendor/github.com/gofrs/flock/flock.go @@ -1,5 +1,5 @@ // Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. +// Copyright 2018-2026 The Gofrs. All rights reserved. // Use of this source code is governed by the BSD 3-Clause // license that can be found in the LICENSE file. @@ -100,7 +100,7 @@ func (f *Flock) Close() error { return f.Unlock() } -// Path returns the path as provided in NewFlock(). +// Path returns the path as provided in New(). func (f *Flock) Path() string { return f.path } diff --git a/tools/vendor/github.com/gofrs/flock/flock_others.go b/tools/vendor/github.com/gofrs/flock/flock_others.go index 92d0f7e95..822ace0da 100644 --- a/tools/vendor/github.com/gofrs/flock/flock_others.go +++ b/tools/vendor/github.com/gofrs/flock/flock_others.go @@ -1,5 +1,5 @@ // Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. +// Copyright 2018-2026 The Gofrs. All rights reserved. // Use of this source code is governed by the BSD 3-Clause // license that can be found in the LICENSE file. diff --git a/tools/vendor/github.com/gofrs/flock/flock_unix.go b/tools/vendor/github.com/gofrs/flock/flock_unix.go index 77de7a883..c486c5e6b 100644 --- a/tools/vendor/github.com/gofrs/flock/flock_unix.go +++ b/tools/vendor/github.com/gofrs/flock/flock_unix.go @@ -1,5 +1,5 @@ // Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. +// Copyright 2018-2026 The Gofrs. All rights reserved. // Use of this source code is governed by the BSD 3-Clause // license that can be found in the LICENSE file. diff --git a/tools/vendor/github.com/gofrs/flock/flock_unix_fcntl.go b/tools/vendor/github.com/gofrs/flock/flock_unix_fcntl.go index 05c2f88c6..76a29fc08 100644 --- a/tools/vendor/github.com/gofrs/flock/flock_unix_fcntl.go +++ b/tools/vendor/github.com/gofrs/flock/flock_unix_fcntl.go @@ -1,5 +1,5 @@ // Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. +// Copyright 2018-2026 The Gofrs. All rights reserved. // Use of this source code is governed by the BSD 3-Clause // license that can be found in the LICENSE file. diff --git a/tools/vendor/github.com/gofrs/flock/flock_windows.go b/tools/vendor/github.com/gofrs/flock/flock_windows.go index aa144f156..d9f9f8832 100644 --- a/tools/vendor/github.com/gofrs/flock/flock_windows.go +++ b/tools/vendor/github.com/gofrs/flock/flock_windows.go @@ -1,5 +1,5 @@ // Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. +// Copyright 2018-2026 The Gofrs. All rights reserved. // Use of this source code is governed by the BSD 3-Clause // license that can be found in the LICENSE file. diff --git a/tools/vendor/github.com/gofrs/flock/zizmor.yml b/tools/vendor/github.com/gofrs/flock/zizmor.yml new file mode 100644 index 000000000..39d1b180c --- /dev/null +++ b/tools/vendor/github.com/gofrs/flock/zizmor.yml @@ -0,0 +1,3 @@ +rules: + secrets-outside-env: + disable: true diff --git a/tools/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/tools/vendor/github.com/sirupsen/logrus/CHANGELOG.md index 3e6675633..683cec908 100644 --- a/tools/vendor/github.com/sirupsen/logrus/CHANGELOG.md +++ b/tools/vendor/github.com/sirupsen/logrus/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## 1.10.2 + +Changed: + + * Update `github.com/stretchr/testify` to v1.12.1, removing the legacy + `gopkg.in/yaml.v3` dependency. + ## 1.10.1 Fixes: diff --git a/tools/vendor/github.com/stretchr/testify/assert/assertions.go b/tools/vendor/github.com/stretchr/testify/assert/assertions.go index 1419e4776..166f63726 100644 --- a/tools/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/tools/vendor/github.com/stretchr/testify/assert/assertions.go @@ -17,7 +17,7 @@ import ( "unicode" "unicode/utf8" - // Wrapper around gopkg.in/yaml.v3 + // Wrapper around go.yaml.in/yaml/v3 "github.com/stretchr/testify/assert/yaml" "github.com/stretchr/testify/internal/difflib" "github.com/stretchr/testify/internal/spew" diff --git a/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go b/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go index 5a74c4f4d..956227ca2 100644 --- a/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go +++ b/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go @@ -7,7 +7,7 @@ // go test -tags testify_yaml_custom // // This implementation can be used at build time to replace the default implementation -// to avoid linking with [gopkg.in/yaml.v3]. +// to avoid linking with [go.yaml.in/yaml/v3]. // // In your test package: // diff --git a/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go b/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go index 0bae80e34..dd89ac03a 100644 --- a/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go +++ b/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go @@ -6,7 +6,7 @@ // indirection with an alternative implementation of this package that uses // another implementation of YAML deserialization. This allows to not either not // use YAML deserialization at all, or to use another implementation than -// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]). +// [go.yaml.in/yaml/v3] (for example for license compatibility reasons, see [PR #1120]). // // Alternative implementations are selected using build tags: // @@ -28,9 +28,9 @@ // [PR #1120]: https://github.com/stretchr/testify/pull/1120 package yaml -import goyaml "gopkg.in/yaml.v3" +import goyaml "go.yaml.in/yaml/v3" -// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal]. +// Unmarshal is just a wrapper of [go.yaml.in/yaml/v3.Unmarshal]. func Unmarshal(in []byte, out interface{}) error { return goyaml.Unmarshal(in, out) } diff --git a/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go b/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go index 8041803fd..a51d27925 100644 --- a/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go +++ b/tools/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go @@ -3,7 +3,7 @@ // Package yaml is an implementation of YAML functions that always fail. // // This implementation can be used at build time to replace the default implementation -// to avoid linking with [gopkg.in/yaml.v3]: +// to avoid linking with [go.yaml.in/yaml/v3]: // // go test -tags testify_yaml_fail package yaml diff --git a/tools/vendor/github.com/uudashr/iface/unexported/unexported.go b/tools/vendor/github.com/uudashr/iface/unexported/unexported.go index c933d1b76..5e0c5c745 100644 --- a/tools/vendor/github.com/uudashr/iface/unexported/unexported.go +++ b/tools/vendor/github.com/uudashr/iface/unexported/unexported.go @@ -5,7 +5,6 @@ import ( "go/ast" "go/types" "os" - "strings" "github.com/uudashr/iface/internal/directive" "golang.org/x/tools/go/analysis" @@ -55,19 +54,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { var recvName string if recv := funcDecl.Recv; recv != nil { - recvType := recv.List[0].Type - - if r.debug { - infoType := pass.TypesInfo.TypeOf(recvType) - fmt.Fprintf(os.Stderr, " recvType: %v infoType: %v reflectType: %T\n", recvType, infoType, recvType) - } - - inner := recvType - if star, ok := inner.(*ast.StarExpr); ok { - inner = star.X - } - - recvName = typeName(inner) + recvName = r.recvName(pass, recv.List[0].Type) } if !funcDecl.Name.IsExported() { @@ -121,62 +108,36 @@ func findIdent(expr ast.Expr) ast.Expr { case *ast.Ident, *ast.SelectorExpr: return e default: + // should not happen return nil } } } -// typeName reconstructs the type string as written in source from an AST expression. -func typeName(expr ast.Expr) string { - switch e := expr.(type) { - case *ast.ArrayType: - if e.Len == nil { - return "[]" + typeName(e.Elt) +func formatType(pass *analysis.Pass, expr ast.Expr, infoType types.Type) string { + qualifier := func(p *types.Package) string { + if p == pass.Pkg { + return "" } - return "[" + typeName(e.Len) + "]" + typeName(e.Elt) - case *ast.BasicLit: - return e.Value - case *ast.Ident: - return e.Name - case *ast.StarExpr: - return "*" + typeName(e.X) - case *ast.Ellipsis: - return "..." + typeName(e.Elt) - case *ast.ChanType: - switch e.Dir { - case ast.SEND: - return "chan<- " + typeName(e.Value) - case ast.RECV: - return "<-chan " + typeName(e.Value) - default: - return "chan " + typeName(e.Value) - } - case *ast.MapType: - return "map[" + typeName(e.Key) + "]" + typeName(e.Value) - case *ast.SelectorExpr: - return typeName(e.X) + "." + e.Sel.Name - case *ast.IndexExpr: - return typeName(e.X) + "[" + typeName(e.Index) + "]" - case *ast.IndexListExpr: - var b strings.Builder - b.WriteString(typeName(e.X)) - b.WriteByte('[') - - for i, idx := range e.Indices { - if i > 0 { - b.WriteString(", ") - } - - b.WriteString(typeName(idx)) - } + return p.Name() + } - b.WriteByte(']') + if ellipsis, ok := expr.(*ast.Ellipsis); ok { + elemType := pass.TypesInfo.TypeOf(ellipsis.Elt) - return b.String() - default: - return fmt.Sprintf("%T", expr) + return "..." + types.TypeString(elemType, qualifier) } + + return types.TypeString(infoType, qualifier) +} + +func funcKindName(funcDecl *ast.FuncDecl, recvName string) (kind, name string) { + if recvName != "" { + return "method", recvName + "." + funcDecl.Name.Name + } + + return "function", funcDecl.Name.Name } func (r *runner) checkType(pass *analysis.Pass, expr ast.Expr, funcDecl *ast.FuncDecl, recvName, role string) { @@ -230,20 +191,30 @@ func (r *runner) checkType(pass *analysis.Pass, expr ast.Expr, funcDecl *ast.Fun r.debugln(" unexported") - funcMethod := "function" - funcMethodName := funcDecl.Name.Name - - if recvName != "" { - funcMethod = "method" - funcMethodName = recvName + "." + funcDecl.Name.Name - } + kind, name := funcKindName(funcDecl, recvName) + typeStr := formatType(pass, expr, infoType) pass.Report(analysis.Diagnostic{ Pos: typ.Pos(), - Message: fmt.Sprintf("unexported interface '%s' used as %s in exported %s '%s'", typeName(expr), role, funcMethod, funcMethodName), + Message: fmt.Sprintf("unexported interface '%s' used as %s in exported %s '%s'", typeStr, role, kind, name), }) } +func (r *runner) recvName(pass *analysis.Pass, recvType ast.Expr) string { + inner := recvType + + if star, ok := inner.(*ast.StarExpr); ok { + inner = star.X + } + + infoType := pass.TypesInfo.TypeOf(inner) + if infoType == nil { + return "" + } + + return formatType(pass, inner, infoType) +} + func (r *runner) debugln(a ...any) { if r.debug { fmt.Fprintln(os.Stderr, a...) diff --git a/tools/vendor/github.com/uudashr/iface/unused/unused.go b/tools/vendor/github.com/uudashr/iface/unused/unused.go index 743e29425..a6ffb0572 100644 --- a/tools/vendor/github.com/uudashr/iface/unused/unused.go +++ b/tools/vendor/github.com/uudashr/iface/unused/unused.go @@ -4,6 +4,7 @@ import ( "fmt" "go/ast" "go/token" + "go/types" "os" "slices" "strings" @@ -35,8 +36,9 @@ func newAnalyzer() *analysis.Analyzer { } type ifaceEntry struct { - ts *ast.TypeSpec - decl *ast.GenDecl + ifaceName string + ts *ast.TypeSpec + decl *ast.GenDecl } type runner struct { @@ -62,7 +64,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) // Collect all interface type declarations - ifaces := make(map[string]ifaceEntry) + ifaces := make(map[*types.TypeName]ifaceEntry) nodeFilter := []ast.Node{ (*ast.GenDecl)(nil), @@ -105,14 +107,25 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { continue } - ifaces[ts.Name.Name] = ifaceEntry{ts: ts, decl: decl} + obj := pass.TypesInfo.Defs[ts.Name] + + typeName, ok := obj.(*types.TypeName) + if !ok { + continue + } + + ifaces[typeName] = ifaceEntry{ + ifaceName: ts.Name.Name, + ts: ts, + decl: decl, + } } }) if r.debug { var ifaceNames []string - for name := range ifaces { - ifaceNames = append(ifaceNames, name) + for tn := range ifaces { + ifaceNames = append(ifaceNames, tn.Name()) } fmt.Fprintln(os.Stderr, "Declared interfaces:", ifaceNames) @@ -129,23 +142,28 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { return } - entry, ok := ifaces[ident.Name] + obj := pass.TypesInfo.Uses[ident] + + typeName, ok := obj.(*types.TypeName) if !ok { return } - if entry.ts.Pos() == ident.Pos() { + entry, ok := ifaces[typeName] + if !ok { return } - delete(ifaces, ident.Name) + r.debugln(" used:", entry.ifaceName) + + delete(ifaces, typeName) }) if r.debug { fmt.Fprintf(os.Stderr, "Package %s %s\n", pass.Pkg.Path(), pass.Pkg.Name()) } - for name, entry := range ifaces { + for typeName, entry := range ifaces { ts := entry.ts decl := entry.decl @@ -166,7 +184,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { end = ts.End() } - msg := fmt.Sprintf("interface '%s' is declared but not used within the package", name) + msg := fmt.Sprintf("interface '%s' is declared but not used within the package", typeName.Name()) pass.Report(analysis.Diagnostic{ Pos: ts.Pos(), Message: msg, diff --git a/tools/vendor/modules.txt b/tools/vendor/modules.txt index 44ba2dca1..30fbb86b1 100644 --- a/tools/vendor/modules.txt +++ b/tools/vendor/modules.txt @@ -304,8 +304,8 @@ github.com/godoc-lint/godoc-lint/pkg/config github.com/godoc-lint/godoc-lint/pkg/inspect github.com/godoc-lint/godoc-lint/pkg/model github.com/godoc-lint/godoc-lint/pkg/util -# github.com/gofrs/flock v0.13.0 -## explicit; go 1.24.0 +# github.com/gofrs/flock v0.13.1 +## explicit; go 1.25.0 github.com/gofrs/flock # github.com/golangci/asciicheck v0.5.0 ## explicit; go 1.23.0 @@ -758,7 +758,7 @@ github.com/quasilyte/regex/syntax # github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 ## explicit; go 1.17 github.com/quasilyte/stdinfo -# github.com/raeperd/recvcheck v0.3.0 +# github.com/raeperd/recvcheck v0.3.1 ## explicit; go 1.25.0 github.com/raeperd/recvcheck # github.com/rivo/uniseg v0.4.7 @@ -808,7 +808,7 @@ github.com/securego/gosec/v2/internal/ssautil github.com/securego/gosec/v2/issue github.com/securego/gosec/v2/rules github.com/securego/gosec/v2/taint -# github.com/sirupsen/logrus v1.10.1 +# github.com/sirupsen/logrus v1.10.2 ## explicit; go 1.23 github.com/sirupsen/logrus # github.com/sivchari/containedctx v1.0.3 @@ -852,7 +852,7 @@ github.com/stbenjam/no-sprintf-host-port/pkg/analyzer # github.com/stretchr/objx v0.5.3 ## explicit; go 1.20 github.com/stretchr/objx -# github.com/stretchr/testify v1.12.0 +# github.com/stretchr/testify v1.12.1 ## explicit; go 1.17 github.com/stretchr/testify/assert github.com/stretchr/testify/assert/yaml @@ -893,8 +893,8 @@ github.com/ultraware/whitespace # github.com/uudashr/gocognit v1.2.1 ## explicit; go 1.24.0 github.com/uudashr/gocognit -# github.com/uudashr/iface v1.5.0 -## explicit; go 1.23.0 +# github.com/uudashr/iface v1.5.1 +## explicit; go 1.25.0 github.com/uudashr/iface/identical github.com/uudashr/iface/internal/directive github.com/uudashr/iface/opaque @@ -1329,5 +1329,5 @@ mvdan.cc/gofumpt/internal/version ## explicit; go 1.25.0 mvdan.cc/unparam/check # github.com/charmbracelet/bubbles/v2 => charm.land/bubbles/v2 v2.1.1 -# github.com/charmbracelet/bubbletea/v2 => charm.land/bubbletea/v2 v2.0.8 +# github.com/charmbracelet/bubbletea/v2 => charm.land/bubbletea/v2 v2.0.9 # github.com/charmbracelet/lipgloss/v2 => charm.land/lipgloss/v2 v2.0.6 diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md index bb215ff19..f745dca9d 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History +## 1.23.1 (2026-08-27) + +### Other Changes + +* Upgraded dependencies. + ## 1.23.0 (2026-08-11) ### Features Added diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go index 4387f71ca..fcbf011e7 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go @@ -37,5 +37,5 @@ const ( Module = "azcore" // Version is the semantic version (see http://semver.org) of this module. - Version = "v1.23.0" + Version = "v1.23.1" ) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md index ba360a30e..3dea713cc 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History +## 1.14.1 (2026-08-27) + +### Other Changes + +- Upgraded dependencies + ## 1.14.0 (2026-06-15) ### Breaking Changes diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go index f45f59697..fb5014489 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go @@ -11,5 +11,5 @@ const ( module = "github.com/Azure/azure-sdk-for-go/sdk/" + component // Version is the semantic version (see http://semver.org) of this module. - version = "v1.14.0" + version = "v1.14.1" ) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md index bc900567e..321c572f7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md @@ -1,3 +1,11 @@ +# v1.7.20 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. + +# v1.7.19 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. + # v1.7.18 (2026-08-14) * **Dependency Update**: Update to smithy-go v1.27.8. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go index 57556a8eb..d52e6b34d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go @@ -3,4 +3,4 @@ package eventstream // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.7.18" +const goModuleVersion = "1.7.20" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md index bdb3895e8..6723895d1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md @@ -1,3 +1,11 @@ +# v1.13.19 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. + +# v1.13.18 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. + # v1.13.17 (2026-08-14) * **Dependency Update**: Update to smithy-go v1.27.8. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go index 7c31cf92e..f5bc392a4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go @@ -3,4 +3,4 @@ package acceptencoding // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.17" +const goModuleVersion = "1.13.19" diff --git a/vendor/github.com/aws/smithy-go/CHANGELOG.md b/vendor/github.com/aws/smithy-go/CHANGELOG.md index 88de0403e..0d26e973c 100644 --- a/vendor/github.com/aws/smithy-go/CHANGELOG.md +++ b/vendor/github.com/aws/smithy-go/CHANGELOG.md @@ -1,3 +1,43 @@ +# Release (2026-08-26) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.28.1 + * **Bug Fix**: Fix broken AddLogger middleware since its insert point was removed. + +# Release (2026-08-25.2) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.28.0 + * **Feature**: Set `Content-Length` inline when the request body is set via `SetStream`. The `ComputeContentLength` middleware is now deprecated. + +# Release (2026-08-25) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.10 + * **Bug Fix**: Fix a data race on the underlying writer when an event stream is closed while an event write is in flight. + * **Bug Fix**: Restore draining the HTTP response body in `CloseResponseBody` to avoid issues with TCP connection reuse. + +# Release (2026-08-21) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.9 + * **Bug Fix**: Fix a generic event stream exception not carrying the error code and message from its payload. + * **Bug Fix**: Fix an event stream not being closed when its connection is lost, which would cause a caller writing to the stream to block indefinitely. + * **Bug Fix**: Fix deserialization of an empty list producing a nil slice instead of an empty one. + * **Bug Fix**: Restore draining the HTTP response body in `CloseResponseBody` to avoid issues with TCP connection reuse. + # Release (2026-08-14) ## General Highlights diff --git a/vendor/github.com/aws/smithy-go/go_module_metadata.go b/vendor/github.com/aws/smithy-go/go_module_metadata.go index 005dac8f6..c945a45db 100644 --- a/vendor/github.com/aws/smithy-go/go_module_metadata.go +++ b/vendor/github.com/aws/smithy-go/go_module_metadata.go @@ -3,4 +3,4 @@ package smithy // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.27.8" +const goModuleVersion = "1.28.1" diff --git a/vendor/github.com/aws/smithy-go/transport/http/eventstream.go b/vendor/github.com/aws/smithy-go/transport/http/eventstream.go index 251db8ac3..970ade30e 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/eventstream.go +++ b/vendor/github.com/aws/smithy-go/transport/http/eventstream.go @@ -56,7 +56,10 @@ func NewEventStreamWriter(protocol ClientProtocol, schema *smithy.Schema, stream } func (w *EventStreamWriter) writeStream() { - defer w.Close() + defer func() { + w.err.SetError(w.eventStream.Close()) + }() + defer w.signalClose() for { select { @@ -100,11 +103,14 @@ func (w *EventStreamWriter) Send(ctx context.Context, variant *smithy.Schema, ev // Close signals end-of-stream and closes the underlying writer. Close is // safe for concurrent calls. func (w *EventStreamWriter) Close() error { + w.signalClose() + return w.err.Err() +} + +func (w *EventStreamWriter) signalClose() { w.closeOnce.Do(func() { close(w.done) - w.err.SetError(w.eventStream.Close()) }) - return w.err.Err() } // Err returns the first error encountered during writing. diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go index 9969389bb..7a1c47fe3 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go +++ b/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go @@ -14,6 +14,9 @@ type ComputeContentLength struct { // AddComputeContentLengthMiddleware adds ComputeContentLength to the middleware // stack's Build step. +// +// Deprecated: Content-Length is now set when the request body is set via +// Request.SetStream, so this middleware is no longer used. func AddComputeContentLengthMiddleware(stack *middleware.Stack) error { return stack.Build.Add(&ComputeContentLength{}, middleware.After) } diff --git a/vendor/github.com/aws/smithy-go/transport/http/request.go b/vendor/github.com/aws/smithy-go/transport/http/request.go index 5cbf6f10a..87acdfe57 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/request.go +++ b/vendor/github.com/aws/smithy-go/transport/http/request.go @@ -118,6 +118,9 @@ func (r *Request) IsStreamSeekable() bool { // SetStream returns a clone of the request with the stream set to the provided // reader. May return an error if the provided reader is seekable but returns // an error. +// +// ContentLength is set to the stream's length when it can be determined, and +// left unchanged otherwise. func (r *Request) SetStream(reader io.Reader) (rc *Request, err error) { rc = r.Clone() @@ -151,6 +154,12 @@ func (r *Request) SetStream(reader io.Reader) (rc *Request, err error) { rc.isStreamSeekable = isStreamSeekable rc.streamStartPos = streamStartPos + if n, ok, err := rc.StreamLength(); err != nil { + return rc, err + } else if ok { + rc.ContentLength = n + } + return rc, err } diff --git a/vendor/github.com/aws/smithy-go/waiter/logger.go b/vendor/github.com/aws/smithy-go/waiter/logger.go index 8d70a03ff..cb31a2e09 100644 --- a/vendor/github.com/aws/smithy-go/waiter/logger.go +++ b/vendor/github.com/aws/smithy-go/waiter/logger.go @@ -30,7 +30,7 @@ func (m *Logger) HandleInitialize(ctx context.Context, in middleware.InitializeI return next.HandleInitialize(ctx, in) } -// AddLogger is a helper util to add waiter logger after `SetLogger` middleware in +// AddLogger is a helper util to add a waiter logger to the initialize stack. func (m Logger) AddLogger(stack *middleware.Stack) error { - return stack.Initialize.Insert(&m, "SetLogger", middleware.After) + return stack.Initialize.Add(&m, middleware.After) } diff --git a/vendor/github.com/cheggaaa/pb/.gitignore b/vendor/github.com/cheggaaa/pb/.gitignore new file mode 100644 index 000000000..9f11b755a --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/vendor/github.com/cheggaaa/pb/.travis.yml b/vendor/github.com/cheggaaa/pb/.travis.yml index 83a356415..7e7fada82 100644 --- a/vendor/github.com/cheggaaa/pb/.travis.yml +++ b/vendor/github.com/cheggaaa/pb/.travis.yml @@ -1,7 +1,10 @@ language: go +arch: + - amd64 + - ppc64le go: - - 1.9.x - 1.12.x + - 1.15.x sudo: false os: - linux diff --git a/vendor/github.com/cheggaaa/pb/LICENSE b/vendor/github.com/cheggaaa/pb/LICENSE index 511970333..ffe46f0f1 100644 --- a/vendor/github.com/cheggaaa/pb/LICENSE +++ b/vendor/github.com/cheggaaa/pb/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012-2015, Sergey Cherepanov +Copyright (c) 2012-2024, Sergey Cherepanov All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,4 +9,4 @@ Redistribution and use in source and binary forms, with or without modification, * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/cheggaaa/pb/README.md b/vendor/github.com/cheggaaa/pb/README.md index 07d52782d..908d14deb 100644 --- a/vendor/github.com/cheggaaa/pb/README.md +++ b/vendor/github.com/cheggaaa/pb/README.md @@ -1,58 +1,61 @@ -# Terminal progress bar for Go +# Terminal progress bar for Go + [![Coverage Status](https://coveralls.io/repos/github/cheggaaa/pb/badge.svg)](https://coveralls.io/github/cheggaaa/pb) ## Installation ``` go get github.com/cheggaaa/pb/v3 -``` +``` -Documentation for v1 bar available [here](README_V1.md) +Documentation for v1 bar available [here](README_V1.md). -## Quick start +## Quick start ```Go package main import ( "time" - + "github.com/cheggaaa/pb/v3" ) func main() { count := 100000 + // create and start new bar bar := pb.StartNew(count) - + // start bar from 'default' template // bar := pb.Default.Start(count) - + // start bar from 'simple' template // bar := pb.Simple.Start(count) - + // start bar from 'full' template // bar := pb.Full.Start(count) - + for i := 0; i < count; i++ { bar.Increment() time.Sleep(time.Millisecond) } + + // finish bar bar.Finish() } - ``` Result will be like this: ``` > go run test.go -37158 / 100000 [================>_______________________________] 37.16% 1m11s +37158 / 100000 [---------------->_______________________________] 37.16% 916 p/s ``` ## Settings -```Go +```Go // create bar bar := pb.New(count) @@ -63,7 +66,7 @@ bar.SetRefreshRate(time.Second) bar.SetWriter(os.Stdout) // bar will format numbers as bytes (B, KiB, MiB, etc) -bar.Set(pb.Byte, true) +bar.Set(pb.Bytes, true) // bar use SI bytes prefix names (B, kB) instead of IEC (B, KiB) bar.Set(pb.SIBytesPrefix, true) @@ -72,17 +75,17 @@ bar.Set(pb.SIBytesPrefix, true) bar.SetTemplateString(myTemplate) // check for error after template set -if err = bar.Err(); err != nil { +if err := bar.Err(); err != nil { return } // start bar bar.Start() - -``` +``` ## Progress bar for IO Operations -```go + +```Go package main import ( @@ -94,36 +97,43 @@ import ( ) func main() { - var limit int64 = 1024 * 1024 * 500 - // we will copy 200 Mb from /dev/rand to /dev/null + + // we will copy 500 MiB from /dev/rand to /dev/null reader := io.LimitReader(rand.Reader, limit) writer := ioutil.Discard // start new bar bar := pb.Full.Start64(limit) + // create proxy reader barReader := bar.NewProxyReader(reader) + // copy from proxy reader io.Copy(writer, barReader) + // finish bar bar.Finish() } - ``` ## Custom Progress Bar templates -Rendering based on builtin text/template package. You can use existing pb's elements or create you own. +Rendering based on builtin [text/template](https://pkg.go.dev/text/template) package. You can use existing pb's elements or create you own. + +All available elements are described in the [element.go](v3/element.go) file. +The `bar` element accepts five standard parts: left border, fill, current, empty, and right border. It also accepts optional sixth and seventh parts for the empty left border and finished right border. -All available elements are described in element.go file. +Set `UNICODE_PROGRESS_BAR=true` to use the built-in Unicode progress bar glyphs for bars that use the default bar elements when the active terminal font supports them. #### All in one example: -```go + +```Go tmpl := `{{ red "With funcs:" }} {{ bar . "<" "-" (cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | rndcolor }} {{percent .}} {{string . "my_green_string" | green}} {{string . "my_blue_string" | blue}}` + // start bar based on our template bar := pb.ProgressBarTemplate(tmpl).Start64(limit) + // set values for string elements -bar.Set("my_green_string", "green"). - Set("my_blue_string", "blue") -``` \ No newline at end of file +bar.Set("my_green_string", "green").Set("my_blue_string", "blue") +``` diff --git a/vendor/github.com/cheggaaa/pb/pb.go b/vendor/github.com/cheggaaa/pb/pb.go index 04dbce698..005961fda 100644 --- a/vendor/github.com/cheggaaa/pb/pb.go +++ b/vendor/github.com/cheggaaa/pb/pb.go @@ -13,7 +13,7 @@ import ( ) // Current version -const Version = "1.0.29" +const Version = "1.0.30" const ( // Default refresh rate - 200ms @@ -74,6 +74,7 @@ type ProgressBar struct { ShowPercent, ShowCounters bool ShowSpeed, ShowTimeLeft, ShowBar bool ShowFinalTime, ShowElapsedTime bool + HideCountersTotal bool Output io.Writer Callback Callback NotPrint bool @@ -304,16 +305,24 @@ func (pb *ProgressBar) write(total, current int64) { if pb.ShowCounters { current := Format(current).To(pb.Units).Width(pb.UnitsWidth) if total > 0 { - totalS := Format(total).To(pb.Units).Width(pb.UnitsWidth) - countersBox = fmt.Sprintf(" %s / %s ", current, totalS) + if pb.HideCountersTotal { + countersBox = fmt.Sprintf(" %s ", current) + } else { + totalS := Format(total).To(pb.Units).Width(pb.UnitsWidth) + countersBox = fmt.Sprintf(" %s / %s ", current, totalS) + } } else { - countersBox = fmt.Sprintf(" %s / ? ", current) + if pb.HideCountersTotal { + countersBox = fmt.Sprintf(" %s ", current) + } else { + countersBox = fmt.Sprintf(" %s / ? ", current) + } } } // time left currentFromStart := current - pb.startValue - fromStart := time.Now().Sub(pb.startTime) + fromStart := time.Since(pb.startTime) lastChangeTime := pb.changeTime fromChange := lastChangeTime.Sub(pb.startTime) @@ -324,8 +333,7 @@ func (pb *ProgressBar) write(total, current int64) { select { case <-pb.finish: if pb.ShowFinalTime { - var left time.Duration - left = (fromStart / time.Second) * time.Second + var left = (fromStart / time.Second) * time.Second timeLeftBox = fmt.Sprintf(" %s", left.String()) } default: @@ -350,7 +358,7 @@ func (pb *ProgressBar) write(total, current int64) { // speed if pb.ShowSpeed && currentFromStart > 0 { - fromStart := time.Now().Sub(pb.startTime) + fromStart := time.Since(pb.startTime) speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second)) speedBox = " " + Format(int64(speed)).To(pb.Units).Width(pb.UnitsWidth).PerSec().String() } @@ -372,17 +380,21 @@ func (pb *ProgressBar) write(total, current int64) { } cursorLen := escapeAwareRuneCountInString(pb.Current) - if emptySize <= 0 { - barBox += strings.Repeat(pb.Current, curSize/cursorLen) - } else if curSize > 0 { - cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN) - cursorRepetitions := (curSize - cursorEndLen) / cursorLen - barBox += strings.Repeat(pb.Current, cursorRepetitions) - barBox += pb.CurrentN + if cursorLen != 0 { + if emptySize <= 0 { + barBox += strings.Repeat(pb.Current, curSize/cursorLen) + } else if curSize > 0 { + cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN) + cursorRepetitions := (curSize - cursorEndLen) / cursorLen + barBox += strings.Repeat(pb.Current, cursorRepetitions) + barBox += pb.CurrentN + } } emptyLen := escapeAwareRuneCountInString(pb.Empty) - barBox += strings.Repeat(pb.Empty, emptySize/emptyLen) + if emptyLen != 0 { + barBox += strings.Repeat(pb.Empty, emptySize/emptyLen) + } barBox += pb.BarEnd } else { pos := size - int(current)%int(size) @@ -457,7 +469,7 @@ func (pb *ProgressBar) Update() { if c == 0 { pb.startTime = time.Now() pb.startValue = 0 - } else if c >= t && pb.isFinish != true { + } else if c >= t && !pb.isFinish{ pb.Finish() } } diff --git a/vendor/github.com/cheggaaa/pb/pb_appengine.go b/vendor/github.com/cheggaaa/pb/pb_appengine.go index 17168f39a..e8dd9eaae 100644 --- a/vendor/github.com/cheggaaa/pb/pb_appengine.go +++ b/vendor/github.com/cheggaaa/pb/pb_appengine.go @@ -1,11 +1,12 @@ -// +build appengine js +// +build appengine js wasip1 package pb import "errors" // terminalWidth returns width of the terminal, which is not supported -// and should always failed on appengine classic which is a sandboxed PaaS. +// and should always failed on appengine classic which is a sandboxed PaaS, +// and on wasip1 which has no terminal-size API. func terminalWidth() (int, error) { return 0, errors.New("Not supported") } diff --git a/vendor/github.com/cheggaaa/pb/pb_x.go b/vendor/github.com/cheggaaa/pb/pb_x.go index af4251760..e5744270b 100644 --- a/vendor/github.com/cheggaaa/pb/pb_x.go +++ b/vendor/github.com/cheggaaa/pb/pb_x.go @@ -1,4 +1,4 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly +// +build linux darwin freebsd netbsd openbsd solaris dragonfly aix zos // +build !appengine !js package pb diff --git a/vendor/github.com/cheggaaa/pb/pool.go b/vendor/github.com/cheggaaa/pb/pool.go index 861d787b0..d641a7e79 100644 --- a/vendor/github.com/cheggaaa/pb/pool.go +++ b/vendor/github.com/cheggaaa/pb/pool.go @@ -1,4 +1,4 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly windows plan9 +// +build linux darwin freebsd netbsd openbsd solaris dragonfly windows plan9 aix zos package pb @@ -64,7 +64,7 @@ func (p *Pool) Start() (err error) { func (p *Pool) writer() { var first = true defer func() { - if first == false { + if !first { p.print(false) } else { p.print(true) @@ -87,7 +87,7 @@ func (p *Pool) writer() { } } -// Restore terminal state and close pool +// Stop Restore terminal state and close pool func (p *Pool) Stop() error { p.finishOnce.Do(func() { if p.shutdownCh != nil { @@ -96,9 +96,8 @@ func (p *Pool) Stop() error { }) // Wait for the worker to complete - select { - case <-p.workerCh: - } + <-p.workerCh + return unlockEcho() } diff --git a/vendor/github.com/cheggaaa/pb/pool_x.go b/vendor/github.com/cheggaaa/pb/pool_x.go index 3d4ed94c1..330ca53dc 100644 --- a/vendor/github.com/cheggaaa/pb/pool_x.go +++ b/vendor/github.com/cheggaaa/pb/pool_x.go @@ -1,4 +1,4 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly plan9 +// +build linux darwin freebsd netbsd openbsd solaris dragonfly plan9 aix zos package pb diff --git a/vendor/github.com/cheggaaa/pb/termios_sysv.go b/vendor/github.com/cheggaaa/pb/termios_sysv.go index b10f61859..b00beaf2b 100644 --- a/vendor/github.com/cheggaaa/pb/termios_sysv.go +++ b/vendor/github.com/cheggaaa/pb/termios_sysv.go @@ -1,8 +1,4 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux solaris +// +build linux solaris aix zos // +build !appengine package pb diff --git a/vendor/github.com/go-openapi/analysis/.codecov.yml b/vendor/github.com/go-openapi/analysis/.codecov.yml index a5ba8e96d..75d4a08f9 100644 --- a/vendor/github.com/go-openapi/analysis/.codecov.yml +++ b/vendor/github.com/go-openapi/analysis/.codecov.yml @@ -7,3 +7,8 @@ coverage: patch: default: target: 80% + +ignore: + - "testdata" + - "internal/antest" + - "internal/testintegration" diff --git a/vendor/github.com/go-openapi/analysis/.golangci.yml b/vendor/github.com/go-openapi/analysis/.golangci.yml index 0d7baa1d7..8488e9771 100644 --- a/vendor/github.com/go-openapi/analysis/.golangci.yml +++ b/vendor/github.com/go-openapi/analysis/.golangci.yml @@ -10,6 +10,7 @@ linters: - gomodguard - gomodguard_v2 - exhaustruct + - exhaustruct_v5 - nlreturn - nonamedreturns - noinlineerr diff --git a/vendor/github.com/go-openapi/analysis/README.md b/vendor/github.com/go-openapi/analysis/README.md index 2a9046297..abb0de930 100644 --- a/vendor/github.com/go-openapi/analysis/README.md +++ b/vendor/github.com/go-openapi/analysis/README.md @@ -5,7 +5,7 @@ -[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] +[![Release][release-badge]][release-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] [![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] @@ -102,8 +102,6 @@ Maintainers can cut a new release by either: [release-badge]: https://badge.fury.io/gh/go-openapi%2Fanalysis.svg [release-url]: https://badge.fury.io/gh/go-openapi%2Fanalysis -[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/analysis -[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/analysis [codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/analysis [codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/analysis diff --git a/vendor/github.com/go-openapi/analysis/analyzer.go b/vendor/github.com/go-openapi/analysis/analyzer.go index 9eab8bd37..63245a182 100644 --- a/vendor/github.com/go-openapi/analysis/analyzer.go +++ b/vendor/github.com/go-openapi/analysis/analyzer.go @@ -30,6 +30,15 @@ type referenceAnalysis struct { parameterItems map[string]spec.Ref allRefs map[string]spec.Ref pathItems map[string]spec.Ref + + // unmappedRefs holds the $ref found under keywords the Swagger 2.0 model does not map, which + // land in [spec.Schema.ExtraProps] as raw JSON: propertyNames, contains, if/then/else, $defs. + // + // They are kept apart from allRefs and schemas on purpose. Flatten needs them to import their + // target and rewrite the pointer; every other consumer of this analysis - AllRefs, + // AllReferences, AllDefinitionReferences and what go-swagger builds on them - addresses schemas + // through the model, and a key naming a raw JSON node is of no use there. + unmappedRefs map[string]spec.Ref } func (r *referenceAnalysis) addRef(key string, ref spec.Ref) { @@ -48,6 +57,11 @@ func (r *referenceAnalysis) addItemsRef(key string, items *spec.Items, location } } +// addUnmappedRef records a $ref held by a keyword the model does not map. +func (r *referenceAnalysis) addUnmappedRef(key string, ref spec.Ref) { + r.unmappedRefs["#"+key] = ref +} + func (r *referenceAnalysis) addSchemaRef(key string, ref SchemaRef) { r.schemas["#"+key] = ref.Schema.Ref r.addRef(key, ref.Schema.Ref) @@ -739,6 +753,7 @@ func (s *Spec) reset() { s.references.headerItems = make(map[string]spec.Ref, allocLargeMap) s.references.parameterItems = make(map[string]spec.Ref, allocLargeMap) s.references.allRefs = make(map[string]spec.Ref, allocLargeMap) + s.references.unmappedRefs = make(map[string]spec.Ref, allocSmallMap) s.patterns.parameters = make(map[string]string, allocLargeMap) s.patterns.headers = make(map[string]string, allocLargeMap) s.patterns.items = make(map[string]string, allocLargeMap) @@ -972,6 +987,42 @@ func (s *Spec) analyzeResponse(prefix string, k int, res spec.Response) { } } +// analyzeUnmapped records the $ref held by the keywords of a schema that the Swagger 2.0 model +// does not map, which json.Unmarshal leaves in ExtraProps as raw JSON. +// +// The keys it produces address the node holding the $ref, so "#/definitions/deep/propertyNames" +// or "#/definitions/deep/if/anyOf/0". [replace.UpdateRef] writes to them through the same +// jsonpointer call every other key goes through. +func (s *Spec) analyzeUnmapped(prefix string, extra map[string]any) { + for key := range extra { + s.analyzeUnmappedNode(slashpath.Join(prefix, jsonpointer.Escape(key)), extra[key]) + } +} + +func (s *Spec) analyzeUnmappedNode(refURI string, node any) { + switch value := node.(type) { + case map[string]any: + if raw, ok := value["$ref"].(string); ok { + ref, err := spec.NewRef(raw) + if err != nil { + return // a string under a "$ref" key is not necessarily a reference + } + + s.references.addUnmappedRef(refURI, ref) + + return // a $ref makes its siblings irrelevant + } + + for key := range value { + s.analyzeUnmappedNode(slashpath.Join(refURI, jsonpointer.Escape(key)), value[key]) + } + case []any: + for i := range value { + s.analyzeUnmappedNode(slashpath.Join(refURI, strconv.Itoa(i)), value[i]) + } + } +} + func (s *Spec) analyzeSchema(name string, schema *spec.Schema, prefix string) { refURI := slashpath.Join(prefix, jsonpointer.Escape(name)) schRef := SchemaRef{ @@ -995,6 +1046,8 @@ func (s *Spec) analyzeSchema(name string, schema *spec.Schema, prefix string) { s.enums.addSchemaEnum(refURI, schema.Enum) } + s.analyzeUnmapped(refURI, schema.ExtraProps) + for k, v := range schema.Definitions { s.analyzeSchema(k, &v, slashpath.Join(refURI, "definitions")) } diff --git a/vendor/github.com/go-openapi/analysis/flatten.go b/vendor/github.com/go-openapi/analysis/flatten.go index c90456f6a..2b7371f54 100644 --- a/vendor/github.com/go-openapi/analysis/flatten.go +++ b/vendor/github.com/go-openapi/analysis/flatten.go @@ -5,6 +5,7 @@ package analysis import ( "log" + "maps" "path" "slices" "sort" @@ -179,18 +180,20 @@ func normalizeRef(opts *FlattenOpts) error { debugLog("normalizeRef") altered := false - for k, w := range opts.Spec.references.allRefs { - if !strings.HasPrefix(w.String(), opts.BasePath+definitionsPath) { // may be a mix of / and \, depending on OS - continue - } + for _, refs := range []map[string]spec.Ref{opts.Spec.references.allRefs, opts.Spec.references.unmappedRefs} { + for k, w := range refs { + if !strings.HasPrefix(w.String(), opts.BasePath+definitionsPath) { // may be a mix of / and \, depending on OS + continue + } - altered = true - debugLog("stripping absolute path for: %s", w.String()) + altered = true + debugLog("stripping absolute path for: %s", w.String()) - // strip the base path from definition - if err := replace.UpdateRef(opts.Swagger(), k, - spec.MustCreateRef(path.Join(definitionsPath, path.Base(w.String())))); err != nil { - return err + // strip the base path from definition + if err := replace.UpdateRef(opts.Swagger(), k, + spec.MustCreateRef(path.Join(definitionsPath, path.Base(w.String())))); err != nil { + return err + } } } @@ -276,6 +279,10 @@ func removeUnusedSinglePass(opts *FlattenOpts) (hasRemoved bool) { delete(expected, k) } + for _, ref := range opts.Spec.references.unmappedRefs { + delete(expected, ref.String()) + } + for k := range expected { hasRemoved = true debugLog("removing unused definition %s", path.Base(k)) @@ -327,9 +334,11 @@ func importNewRef(entry sortref.RefRevIdx, refStr string, opts *FlattenOpts) err partialAnalyzer.analyzeSchema("", sch, "/") // now rewrite those refs with rebase - for key, ref := range partialAnalyzer.references.allRefs { - if err := replace.UpdateRef(sch, key, spec.MustCreateRef(normalize.RebaseRef(entry.Ref.String(), ref.String()))); err != nil { - return ErrRewriteRef(key, entry.Ref.String(), err) + for _, refs := range []map[string]spec.Ref{partialAnalyzer.references.allRefs, partialAnalyzer.references.unmappedRefs} { + for key, ref := range refs { + if err := replace.UpdateRef(sch, key, spec.MustCreateRef(normalize.RebaseRef(entry.Ref.String(), ref.String()))); err != nil { + return ErrRewriteRef(key, entry.Ref.String(), err) + } } } @@ -374,10 +383,20 @@ func importNewRef(entry sortref.RefRevIdx, refStr string, opts *FlattenOpts) err // At every iteration, new remotes may be found when digging deeper: they are rebased to the current schema before being imported. // // This returns true when no more remote references can be found. +// importableRefs returns every $ref that flatten has to bring into the root document: the ones the +// model maps, and the ones held by keywords it does not. +func importableRefs(sp *Spec) map[string]spec.Ref { + refs := make(map[string]spec.Ref, len(sp.references.schemas)+len(sp.references.unmappedRefs)) + maps.Copy(refs, sp.references.schemas) + maps.Copy(refs, sp.references.unmappedRefs) + + return refs +} + func importExternalReferences(opts *FlattenOpts) (bool, error) { debugLog("importExternalReferences") - groupedRefs := sortref.ReverseIndex(opts.Spec.references.schemas, opts.BasePath) + groupedRefs := sortref.ReverseIndex(importableRefs(opts.Spec), opts.BasePath) sortedRefStr := make([]string, 0, len(groupedRefs)) if opts.flattenContext == nil { opts.flattenContext = newContext() diff --git a/vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go b/vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go index b4c0fdd44..66cad8f39 100644 --- a/vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go +++ b/vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go @@ -19,6 +19,7 @@ import ( const ( definitionsPath = "#/definitions" + jsonRef = "$ref" allocMediumMap = 64 ) @@ -217,6 +218,17 @@ func UpdateRef(sp any, key string, ref spec.Ref) error { switch refable := value.(type) { case *spec.Schema: refable.Ref = ref + case map[string]any: + // a keyword the Swagger 2.0 model does not map: the node is raw JSON, and the map it + // holds is the one in the document - writing to it reaches the document + refable[jsonRef] = ref.String() + case *any: + raw, ok := (*refable).(map[string]any) + if !ok { + return ErrNoSchemaWithRef(key, value) + } + + raw[jsonRef] = ref.String() case *spec.SchemaOrArray: if refable.Schema != nil { refable.Schema.Ref = ref diff --git a/vendor/github.com/go-openapi/analysis/revive.toml b/vendor/github.com/go-openapi/analysis/revive.toml new file mode 100644 index 000000000..eef9c1712 --- /dev/null +++ b/vendor/github.com/go-openapi/analysis/revive.toml @@ -0,0 +1,18 @@ +# revive configuration used by codefactor.io. +# +# This is redundant with .golangci.yml, since revive is part of golangci-lint, +# but we need to configure it to remain consistent across reporting tools. + +ignore-generated-header = false +severity = "warning" +confidence = 0.8 +error-code = 0 +warning-code = 0 +enable-default-rules = true + +[rule.exported] +disabled = true +[rule.cyclomatic] +arguments = [25] +[rule.cognitive-complexity] +arguments = [25] diff --git a/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md b/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md index d20737c94..605e03795 100644 --- a/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md @@ -4,11 +4,11 @@ | Total Contributors | Total Contributions | | --- | --- | -| 9 | 83 | +| 9 | 84 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | -| @fredbi | 46 | | +| @fredbi | 47 | | | @casualjim | 25 | | | @youyuanwu | 5 | | | @olivierlemasle | 2 | | diff --git a/vendor/github.com/go-openapi/jsonreference/README.md b/vendor/github.com/go-openapi/jsonreference/README.md index fbd16cf89..000a1feb5 100644 --- a/vendor/github.com/go-openapi/jsonreference/README.md +++ b/vendor/github.com/go-openapi/jsonreference/README.md @@ -5,7 +5,7 @@ -[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] +[![Release][release-badge]][release-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] [![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] @@ -97,8 +97,6 @@ Maintainers can cut a new release by either: [gomod-badge]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fjsonreference.svg [gomod-url]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fjsonreference -[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/jsonreference -[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/jsonreference [codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/jsonreference [codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/jsonreference diff --git a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go index a08b47320..6ef640e3b 100644 --- a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go +++ b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go @@ -5,19 +5,12 @@ package internal import ( "net/url" - "regexp" "strings" ) const ( - defaultHTTPPort = ":80" - defaultHTTPSPort = ":443" -) - -// Regular expressions used by the normalizations. -var ( - rxPort = regexp.MustCompile(`(:\d+)/?$`) - rxDupSlashes = regexp.MustCompile(`/{2,}`) + defaultHTTPPort = "80" + defaultHTTPSPort = "443" ) // NormalizeURL will normalize the specified URL @@ -55,20 +48,66 @@ func lowercaseHost(u *url.URL) { } } +// removeDefaultPort drops :80 from an http URL and :443 from an https one. +// +// The port stays when dropping it would leave an authority url.Parse no longer accepts, so the +// shortened host is parsed before being kept. url.Parse reads "https://:a:443" as the host ":a" +// on port 443, and ":a" on its own is an invalid port, so "https://:a" no longer parses. +// +// A degenerate authority can spell a default port twice - url.Parse reads "http://:80:80" as the +// host ":80" on port 80 - so removal repeats until nothing more comes off. Each pass shortens the +// host, so the loop ends, and normalizing the result again changes nothing. func removeDefaultPort(u *url.URL) { - if len(u.Host) > 0 { - scheme := strings.ToLower(u.Scheme) - u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string { - if (scheme == "http" && val == defaultHTTPPort) || (scheme == "https" && val == defaultHTTPSPort) { - return "" - } - return val - }) + for { + port := u.Port() + if port == "" || port != defaultPortForScheme(strings.ToLower(u.Scheme)) { + return + } + + host := strings.TrimSuffix(u.Host, ":"+port) + if _, err := url.Parse("//" + host); err != nil { + return + } + + u.Host = host + } +} + +func defaultPortForScheme(scheme string) string { + switch scheme { + case "http": + return defaultHTTPPort + case "https": + return defaultHTTPSPort + default: + return "" } } +// removeDuplicateSlashes collapses every run of slashes in the path to a single one, however +// long the run is: "/a//b///c" becomes "/a/b/c". +// +// A path holding no "//" is left as it is, which is the common case and costs one scan and no +// allocation. func removeDuplicateSlashes(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDupSlashes.ReplaceAllString(u.Path, "/") + const doubleSlash = "//" + + start := strings.Index(u.Path, doubleSlash) + if start < 0 { + return } + + var collapsed strings.Builder + collapsed.Grow(len(u.Path)) + collapsed.WriteString(u.Path[:start+1]) // everything up to and including the first slash of the run + + for i := start + 1; i < len(u.Path); i++ { + c := u.Path[i] + if c == '/' && u.Path[i-1] == '/' { + continue + } + collapsed.WriteByte(c) + } + + u.Path = collapsed.String() } diff --git a/vendor/github.com/go-openapi/loads/README.md b/vendor/github.com/go-openapi/loads/README.md index 293f79bb6..8fa5b4bc7 100644 --- a/vendor/github.com/go-openapi/loads/README.md +++ b/vendor/github.com/go-openapi/loads/README.md @@ -5,7 +5,7 @@ -[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] +[![Release][release-badge]][release-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] [![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] @@ -127,8 +127,6 @@ Maintainers can cut a new release by either: [release-badge]: https://badge.fury.io/gh/go-openapi%2Floads.svg [release-url]: https://badge.fury.io/gh/go-openapi%2Floads -[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/loads -[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/loads [codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/loads [codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/loads diff --git a/vendor/github.com/go-openapi/loads/spec.go b/vendor/github.com/go-openapi/loads/spec.go index e9e4b57b7..ea64717cf 100644 --- a/vendor/github.com/go-openapi/loads/spec.go +++ b/vendor/github.com/go-openapi/loads/spec.go @@ -5,21 +5,16 @@ package loads import ( "bytes" - "encoding/gob" "encoding/json" "fmt" "maps" "github.com/go-openapi/analysis" "github.com/go-openapi/spec" + "github.com/go-openapi/swag/jsonutils" "github.com/go-openapi/swag/yamlutils" ) -func init() { - gob.Register(map[string]any{}) - gob.Register([]any{}) -} - // Document represents a swagger spec document. type Document struct { // specAnalyzer @@ -276,14 +271,16 @@ func (d *Document) SpecFilePath() string { return d.specFilePath } +// cloneSpec deep-copies a specification through its JSON representation. +// +// It used to go through gob, which omits a field holding the zero value for its type and +// flattens a pointer to what it points at, so an optional number that was present and zero came +// back nil: "minimum": 0, "maximum": 0, "maxLength": 0, "maxItems": 0 and "maxProperties": 0 were +// dropped from the copy, at any depth and with no error. That copy is what OrigSpec returns and +// what ResetDefinitions writes back over the live definitions. func cloneSpec(src *spec.Swagger) (*spec.Swagger, error) { - var b bytes.Buffer - if err := gob.NewEncoder(&b).Encode(src); err != nil { - return nil, err - } - var dst spec.Swagger - if err := gob.NewDecoder(&b).Decode(&dst); err != nil { + if err := jsonutils.FromDynamicJSON(src, &dst); err != nil { return nil, err } diff --git a/vendor/github.com/go-openapi/runtime/.golangci.yml b/vendor/github.com/go-openapi/runtime/.golangci.yml index affd69c88..3e917ed30 100644 --- a/vendor/github.com/go-openapi/runtime/.golangci.yml +++ b/vendor/github.com/go-openapi/runtime/.golangci.yml @@ -5,6 +5,7 @@ linters: - depguard - err113 # disabled temporarily: there are just too many issues to address - exhaustruct + - exhaustruct_v5 - funlen - gochecknoglobals - gochecknoinits diff --git a/vendor/github.com/go-openapi/runtime/CONTRIBUTORS.md b/vendor/github.com/go-openapi/runtime/CONTRIBUTORS.md index 9c959ef48..10195c33b 100644 --- a/vendor/github.com/go-openapi/runtime/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/runtime/CONTRIBUTORS.md @@ -4,12 +4,12 @@ | Total Contributors | Total Contributions | | --- | --- | -| 71 | 570 | +| 73 | 573 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | | @casualjim | 268 | | -| @fredbi | 144 | | +| @fredbi | 145 | | | @youyuanwu | 19 | | | @josephwoodward | 13 | | | @kenjones-cisco | 12 | | @@ -40,12 +40,13 @@ | @tschaub | 1 | | | @pytlesk4 | 1 | | | @tgraf | 1 | | +| @delthas | 1 | | | @seanprince | 1 | | | @rodriguise | 1 | | | @petrkotas | 1 | | +| @fpawel | 1 | | | @maxatome | 1 | | | @maxkarelov | 1 | | -| @tooolbox | 1 | | | @akutz | 1 | | | @yabberyabber | 1 | | | @elv-gilles | 1 | | @@ -79,5 +80,6 @@ | @KuaaMU | 1 | | | @germanhs | 1 | | | @pracucci | 1 | | +| @tooolbox | 1 | | _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/runtime/multipart_stream.go b/vendor/github.com/go-openapi/runtime/multipart_stream.go index 76e1bf460..78bc97559 100644 --- a/vendor/github.com/go-openapi/runtime/multipart_stream.go +++ b/vendor/github.com/go-openapi/runtime/multipart_stream.go @@ -342,6 +342,10 @@ func (s *MultipartFormStream) Drain() error { // particular, a net/http server request body may discard a limited amount of // unread data to allow connection reuse, so Close is not guaranteed to return // immediately. Call Drain when trailing form fields must be collected. +// +// Close returns the error reported by the request body, except io.EOF: a +// net/http server body reports io.EOF once it discards that unread remainder, +// which tells us the body ended, not that closing it failed. func (s *MultipartFormStream) Close() error { if s == nil || s.closed { return nil @@ -357,7 +361,14 @@ func (s *MultipartFormStream) Close() error { return nil } - return s.request.Body.Close() + // Since go1.27.0, net/http (*body).Close returns io.EOF when it discards + // the unread remainder of the request itself. Reaching the end of the body + // is not a close failure. + if err := s.request.Body.Close(); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil } func supportsMultipartFormStream(method string) bool { diff --git a/vendor/github.com/go-openapi/spec/.golangci.yml b/vendor/github.com/go-openapi/spec/.golangci.yml index 9d2733176..3f3b5af8d 100644 --- a/vendor/github.com/go-openapi/spec/.golangci.yml +++ b/vendor/github.com/go-openapi/spec/.golangci.yml @@ -9,6 +9,7 @@ linters: - gomodguard - gomodguard_v2 - exhaustruct + - exhaustruct_v5 - nlreturn - nonamedreturns - noinlineerr diff --git a/vendor/github.com/go-openapi/spec/CONTRIBUTORS.md b/vendor/github.com/go-openapi/spec/CONTRIBUTORS.md index 12fd069b0..5871da529 100644 --- a/vendor/github.com/go-openapi/spec/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/spec/CONTRIBUTORS.md @@ -4,12 +4,12 @@ | Total Contributors | Total Contributions | | --- | --- | -| 38 | 403 | +| 38 | 414 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | | @casualjim | 191 | | -| @fredbi | 101 | | +| @fredbi | 112 | | | @pytlesk4 | 26 | | | @kul-amr | 10 | | | @keramix | 10 | | diff --git a/vendor/github.com/go-openapi/spec/README.md b/vendor/github.com/go-openapi/spec/README.md index 7c96eb9a5..9188f8308 100644 --- a/vendor/github.com/go-openapi/spec/README.md +++ b/vendor/github.com/go-openapi/spec/README.md @@ -5,7 +5,7 @@ -[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] +[![Release][release-badge]][release-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] [![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] @@ -120,8 +120,6 @@ Maintainers can cut a new release by either: [gomod-badge]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fspec.svg [gomod-url]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fspec -[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/spec -[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/spec [codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/spec [codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/spec diff --git a/vendor/github.com/go-openapi/spec/expander.go b/vendor/github.com/go-openapi/spec/expander.go index 00eb5b53a..2922fccb5 100644 --- a/vendor/github.com/go-openapi/spec/expander.go +++ b/vendor/github.com/go-openapi/spec/expander.go @@ -4,8 +4,12 @@ package spec import ( + "cmp" "encoding/json" "fmt" + "iter" + "maps" + "slices" "github.com/go-openapi/swag/loading" ) @@ -109,7 +113,8 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error { specBasePath := options.RelativeBase if !options.SkipSchemas { - for key, definition := range spec.Definitions { + for key := range sortedKeys(spec.Definitions) { + definition := spec.Definitions[key] parentRefs := make([]string, 0, smallPrealloc) parentRefs = append(parentRefs, "#/definitions/"+key) @@ -123,7 +128,7 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error { } } - for key := range spec.Parameters { + for key := range sortedKeys(spec.Parameters) { parameter := spec.Parameters[key] if err := expandParameterOrResponse(¶meter, resolver, specBasePath); resolver.shouldStopOnError(err) { return err @@ -131,7 +136,7 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error { spec.Parameters[key] = parameter } - for key := range spec.Responses { + for key := range sortedKeys(spec.Responses) { response := spec.Responses[key] if err := expandParameterOrResponse(&response, resolver, specBasePath); resolver.shouldStopOnError(err) { return err @@ -140,7 +145,7 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error { } if spec.Paths != nil { - for key := range spec.Paths.Paths { + for key := range sortedKeys(spec.Paths.Paths) { pth := spec.Paths.Paths[key] if err := expandPathItem(&pth, resolver, specBasePath); resolver.shouldStopOnError(err) { return err @@ -278,6 +283,38 @@ func expandItems(target Schema, parentRefs []string, resolver *schemaLoader, bas return &target, nil } +// sortedKeys walks the keys of a map in a fixed order. +// +// Expansion inlines the first branch that reaches a cycle and leaves a $ref on the others, so +// the order the walk visits siblings in decides which node ends up holding the $ref. Ranging a +// map straight gives that decision to Go's map iteration, and the same document then expands +// differently from one run to the next - see go-openapi/spec#93. +// +// A map of fewer than two keys has only one order, so it is yielded without sorting: schemata +// with a single property or definition are most of what a walk of a large document visits, and +// the slice this would otherwise allocate is paid at every node. +func sortedKeys[K cmp.Ordered, V any](m map[K]V) iter.Seq[K] { + const alreadyOrdered = 2 // a map of fewer keys than this has only one order + + return func(yield func(K) bool) { + if len(m) < alreadyOrdered { + for key := range m { + yield(key) + + return + } + + return + } + + for _, key := range slices.Sorted(maps.Keys(m)) { + if !yield(key) { + return + } + } + } +} + //nolint:gocognit,gocyclo,cyclop // complex but well-tested $ref expansion logic; refactoring deferred to dedicated PR func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) { if err := resolver.context.countNode(); err != nil { @@ -312,7 +349,9 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba return &target, nil } - for k := range target.Definitions { + rebaseExtraRefs(target.ExtraProps, resolver, basePath) + + for k := range sortedKeys(target.Definitions) { tt, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { return &target, err @@ -370,7 +409,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba } } - for k := range target.Properties { + for k := range sortedKeys(target.Properties) { t, err := expandSchema(target.Properties[k], parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { return &target, err @@ -390,7 +429,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba } } - for k := range target.PatternProperties { + for k := range sortedKeys(target.PatternProperties) { t, err := expandSchema(target.PatternProperties[k], parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { return &target, err @@ -400,7 +439,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba } } - for k := range target.Dependencies { + for k := range sortedKeys(target.Dependencies) { if target.Dependencies[k].Schema != nil { t, err := expandSchema(*target.Dependencies[k].Schema, parentRefs, resolver, basePath) if resolver.shouldStopOnError(err) { @@ -424,6 +463,67 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba return &target, nil } +// rebaseExtraRefs rewrites the $ref held by keywords this model does not map, so that +// they still point at their target once the schema is inlined into another document. +// +// expandSchema walks the fields of [Schema] and stops there. A keyword the Swagger 2.0 +// model predates - propertyNames, contains, if/then/else, $defs - lands in ExtraProps as +// raw JSON, and a $ref inside it is copied into the root verbatim: "#/definitions/leaf" +// then names a definition of the root document instead of the one it came from. +// +// Rebasing makes the pointer correct. It does not expand it, and it does not make the +// expanded document self-contained: a $ref that came from another document keeps pointing +// there. +func rebaseExtraRefs(extra map[string]any, resolver *schemaLoader, basePath string) { + for key := range extra { + rebaseRawRefs(extra[key], resolver, basePath) + } +} + +// rebaseRawRefs walks raw JSON and rebases every "$ref" string value it finds. +func rebaseRawRefs(node any, resolver *schemaLoader, basePath string) { + switch value := node.(type) { + case map[string]any: + for key := range value { + if key == jsonRef { + if ref, ok := value[key].(string); ok { + if rebased, ok := rebaseRawRef(ref, resolver, basePath); ok { + value[key] = rebased + } + + continue + } + } + + rebaseRawRefs(value[key], resolver, basePath) + } + case []any: + for i := range value { + rebaseRawRefs(value[i], resolver, basePath) + } + } +} + +// rebaseRawRef resolves a $ref against basePath, then spells it relative to the document +// being expanded, like the SkipSchemas branch of [expandSchema] does for a mapped $ref. +// +// It reports false when the $ref is empty or does not parse: an unmapped keyword may hold +// any JSON, and a string under a "$ref" key is not necessarily a reference. +func rebaseRawRef(ref string, resolver *schemaLoader, basePath string) (string, bool) { + if ref == "" { + return "", false + } + + rebased, err := NewRef(normalizeURI(ref, basePath)) + if err != nil { + return "", false + } + + denormalized := denormalizeRef(&rebased, resolver.context.basePath, resolver.context.rootID) + + return denormalized.String(), true +} + func expandSchemaRef(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) { // if a Ref is found, all sibling fields are skipped // Ref also changes the resolution scope of children expandSchema @@ -483,7 +583,7 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string) pathItem.Ref = Ref{} for i := range pathItem.Parameters { - if err := expandParameterOrResponse(&(pathItem.Parameters[i]), resolver, basePath); resolver.shouldStopOnError(err) { + if err := expandParameterOrResponse(&pathItem.Parameters[i], resolver, basePath); resolver.shouldStopOnError(err) { return err } } @@ -528,7 +628,7 @@ func expandOperation(op *Operation, resolver *schemaLoader, basePath string) err return err } - for code := range responses.StatusCodeResponses { + for code := range sortedKeys(responses.StatusCodeResponses) { response := responses.StatusCodeResponses[code] if err := expandParameterOrResponse(&response, resolver, basePath); resolver.shouldStopOnError(err) { return err diff --git a/vendor/github.com/go-openapi/spec/normalizer.go b/vendor/github.com/go-openapi/spec/normalizer.go index 68252dc30..ced7f9935 100644 --- a/vendor/github.com/go-openapi/spec/normalizer.go +++ b/vendor/github.com/go-openapi/spec/normalizer.go @@ -41,10 +41,11 @@ func normalizeURI(refPath, base string) string { if refURL.Path == "." { refURL.Path = "" } + forgetSpelling(refURL) r := MustCreateRef(refURL.String()) if r.IsCanonical() { - return refURL.String() + return r.String() } baseURL, _ := parseURL(base) @@ -56,6 +57,14 @@ func normalizeURI(refPath, base string) string { // copying fragment from ref to base baseURL.Fragment = refURL.Fragment + if baseURL.Scheme != "" && baseURL.Path != "" && !path.IsAbs(baseURL.Path) { + // a base that carries no path of its own (e.g. "smb://host") leaves the join relative. + // Anchor it, because a relative path under a scheme does not survive rendering: it is + // either promoted to a host component, which is not even guaranteed to be a legal one + // ("a://some file.json" no longer parses), or read back as absolute anyway. + baseURL.Path = path.Join("/", baseURL.Path) + } + return baseURL.String() } @@ -82,23 +91,45 @@ func denormalizeRef(ref *Ref, originalRelativeBase, id string) Ref { } if id != "" { - idBaseURL, err := parseURL(id) - if err == nil { // if the schema id is not usable as a URI, ignore it - if ref, ok := rebase(ref, idBaseURL, true); ok { // rebase, but keep references to root unchanged (do not want $ref: "") + if _, err := parseURL(id); err == nil { // if the schema id is not usable as a URI, ignore it + // rebase, but keep references to root unchanged (do not want $ref: "") + if ref, ok := rebase(ref, canonicalURL(id), true); ok { // $ref relative to the ID of the schema in the root document return ref } } } - originalRelativeBaseURL, _ := parseURL(originalRelativeBase) - - r, _ := rebase(ref, originalRelativeBaseURL, false) + r, _ := rebase(ref, canonicalURL(originalRelativeBase), false) return r } -func rebase(ref *Ref, v *url.URL, notEqual bool) (Ref, bool) { +// canonicalURL parses a URI the way a Ref does, so that rebase compares authorities that are +// spelled alike. +// +// Turning a URI into a Ref lower-cases the host and drops a default port, whereas the normalizer +// keeps the spelling it was handed: comparing the two spellings directly makes a $ref look like +// it belongs to another host, and leaves it absolute when it should have been rebased. +func canonicalURL(in string) *url.URL { + if ref, err := NewRef(in); err == nil { + return ref.GetURL() + } + + if u, err := parseURL(in); err == nil { + return u + } + + return &url.URL{} +} + +// rebase expresses a $ref relative to v, which is either the URI of the base document or +// the "id" that anchors the root schema. +// +// The two differ in what v stands for. An "id" anchors a namespace, so a $ref below it is +// expressed relative to the id itself. A base is a document, so a $ref is expressed relative +// to the folder that holds it, and only a $ref to that very document collapses to an empty $ref. +func rebase(ref *Ref, v *url.URL, isID bool) (Ref, bool) { var newBase url.URL u := ref.GetURL() @@ -118,26 +149,78 @@ func rebase(ref *Ref, v *url.URL, notEqual bool) (Ref, bool) { newBase.Fragment = u.Fragment - if after, ok := strings.CutPrefix(u.Path, docPath); ok { - newBase.Path = after - } else { + switch { + case isID: + if after, ok := cutPathPrefix(u.Path, docPath); ok { + newBase.Path = after + } else { + newBase.Path = strings.TrimPrefix(u.Path, v.Path) + } + + if newBase.Path == "" && newBase.Fragment == "" { + // do not want rebasing to end up in an empty $ref + return *ref, false + } + + case u.Path == docPath: + // the $ref points to the base document itself + newBase.Path = "" + + default: newBase.Path = strings.TrimPrefix(u.Path, v.Path) - } - if notEqual && newBase.Path == "" && newBase.Fragment == "" { - // do not want rebasing to end up in an empty $ref - return *ref, false + if newBase.Path == "" { + // the $ref points to the folder that holds the base, not to a document: + // a $ref with no path of its own would denote the base document instead + return *ref, false + } } if path.IsAbs(newBase.Path) { - // whenever we end up with an absolute path, specify the scheme and host + // whenever we end up with an absolute path, we render a whole URI newBase.Scheme = v.Scheme newBase.Host = v.Host + newBase.User = u.User + newBase.RawQuery = u.RawQuery + newBase.ForceQuery = u.ForceQuery + } else if u.RawQuery != v.RawQuery || u.ForceQuery != v.ForceQuery || !sameUserinfo(u.User, v.User) { + // a relative $ref carries neither credentials nor query of its own: normalizing one + // applies those of the base. Leave the $ref absolute rather than have it resolve + // against a different query or different credentials. + return *ref, false } return MustCreateRef(newBase.String()), true } +// sameUserinfo compares the userinfo components of two URIs. +// +// An absent userinfo differs from an empty one: "file:///x" and "file://@/x" do not render alike. +func sameUserinfo(a, b *url.Userinfo) bool { + if a == nil || b == nil { + return a == b + } + + return a.String() == b.String() +} + +// cutPathPrefix is strings.CutPrefix, cutting on path separators only. +// +// "/base/spec.json" is a prefix of "/base/spec.json/x" but not of "/base/spec.json.orig": +// cutting the latter would leave ".orig" to be rebased against the wrong folder. +func cutPathPrefix(pth, prefix string) (string, bool) { + after, ok := strings.CutPrefix(pth, prefix) + if !ok { + return "", false + } + + if after == "" || strings.HasPrefix(after, "/") || strings.HasSuffix(prefix, "/") { + return after, true + } + + return "", false +} + // normalizeRef canonicalize a Ref, using a canonical relativeBase as its absolute anchor. func normalizeRef(ref *Ref, relativeBase string) *Ref { r := MustCreateRef(normalizeURI(ref.String(), relativeBase)) @@ -170,11 +253,12 @@ func normalizeBase(in string) string { if u.Path == "." { // empty after Clean() u.Path = "" } + forgetSpelling(u) if u.Scheme != "" { if path.IsAbs(u.Path) || u.Scheme != fileScheme { // this is absolute or explicitly not a local file: we're good - return u.String() + return canonicalString(u) } } @@ -187,5 +271,41 @@ func normalizeBase(in string) string { u.Scheme = fileScheme u.Path = absPath(u.Path) // platform-dependent u.RawQuery = "" // any query component is irrelevant for a base - return u.String() + return canonicalString(u) +} + +// forgetSpelling drops the escaped spelling url.Parse recorded, so that rendering the URL +// derives it from Path and Fragment again. +// +// url.URL.String returns RawPath whenever it still decodes to Path, and the normalizer rewrites +// Path - path.Clean, then a join onto the base. A RawPath describing the path as it was written +// no longer describes the path we now hold, and rendering it can produce a URI that does not +// parse: normalizeBase("%2F") used to return "file://%2F", where the escaped form lost the +// leading slash that Path carries and what is left reads as an authority. +func forgetSpelling(u *url.URL) { + u.RawPath = "" + u.RawFragment = "" +} + +// canonicalString renders a URL the way jsonreference does. +// +// The normalizer and jsonreference each canonicalize a URI, and they used to disagree: the +// normalizer kept the spelling it was handed while a Ref lower-cases the host, drops a default +// port and re-escapes path and fragment. Everything the expander stores - cache keys, the +// parentRefs chain, a $ref written back into the document - goes through both, so the two must +// agree or one document splits into two spellings of itself. +// +// A URI that jsonreference cannot parse is returned as it stands, rather than panicking through +// MustCreateRef. Such a URI is a defect in the normalizer, and the fuzz target reports it as one. +func canonicalString(u *url.URL) string { + rendered := u.String() + + r, err := NewRef(rendered) + if err != nil { + specLogger.Printf("warning: the normalizer produced an unparseable URI %q: %v", rendered, err) + + return rendered + } + + return r.String() } diff --git a/vendor/github.com/go-openapi/spec/normalizer_windows.go b/vendor/github.com/go-openapi/spec/normalizer_windows.go index 61515c9a1..a439f432a 100644 --- a/vendor/github.com/go-openapi/spec/normalizer_windows.go +++ b/vendor/github.com/go-openapi/spec/normalizer_windows.go @@ -1,4 +1,4 @@ -// -build windows +//go:build windows // SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers // SPDX-License-Identifier: Apache-2.0 diff --git a/vendor/github.com/go-openapi/spec/swagger.go b/vendor/github.com/go-openapi/spec/swagger.go index dbe32db8a..61a278e2d 100644 --- a/vendor/github.com/go-openapi/spec/swagger.go +++ b/vendor/github.com/go-openapi/spec/swagger.go @@ -403,7 +403,9 @@ func (s *SchemaOrArray) ContainsType(name string) bool { // MarshalJSON converts this schema object or array into JSON structure. func (s SchemaOrArray) MarshalJSON() ([]byte, error) { - if len(s.Schemas) > 0 { + if s.Schemas != nil { + // an empty array is still the array form: marshalling it as the single form + // would yield "null", which is not a schema return json.Marshal(s.Schemas) } return json.Marshal(s.Schema) diff --git a/vendor/github.com/go-openapi/swag/fileutils/doc.go b/vendor/github.com/go-openapi/swag/fileutils/doc.go index 859a200d8..d5ca57b96 100644 --- a/vendor/github.com/go-openapi/swag/fileutils/doc.go +++ b/vendor/github.com/go-openapi/swag/fileutils/doc.go @@ -3,8 +3,14 @@ // Package fileutils exposes utilities to deal with files and paths. // -// Currently, there is: -// - [File] to represent an abstraction of an uploaded file. -// For instance, this is used by [github.com/go-openapi/runtime.File]. -// - path search utilities (e.g. finding packages in the GO search path) +// It provides: +// +// - [File], an abstraction of an uploaded file. +// It is used by [github.com/go-openapi/runtime.File]. +// - Implementations of [fs.FS]: [OsFS] and [GlobOsFS] wrap the os package, +// [MapFS] serves files held in memory, [OverlayFS] stacks file systems on top of one another, +// [OpaqueFS] lets a layer claim a directory for itself, and [FileReaderFS] adds a ReadFile +// method to any [fs.FS]. +// - [MustSub], to re-root a file system inline when the directory is a constant of the program. +// - path search utilities, to locate a package in the go search path. package fileutils diff --git a/vendor/github.com/go-openapi/swag/fileutils/file.go b/vendor/github.com/go-openapi/swag/fileutils/file.go index 5ad4cfaea..a5ff03c75 100644 --- a/vendor/github.com/go-openapi/swag/fileutils/file.go +++ b/vendor/github.com/go-openapi/swag/fileutils/file.go @@ -6,17 +6,22 @@ package fileutils import "mime/multipart" // File represents an uploaded file. +// +// Data holds the payload, and Header the multipart metadata. +// File implements [io.ReadCloser] by delegating both methods to Data. +// +// The zero File is not usable: [File.Read] and [File.Close] both panic when Data is nil. type File struct { Data multipart.File Header *multipart.FileHeader } -// Read bytes from the file +// Read reads bytes from the payload. func (f *File) Read(p []byte) (n int, err error) { return f.Data.Read(p) } -// Close the file +// Close closes the payload. func (f *File) Close() error { return f.Data.Close() } diff --git a/vendor/github.com/go-openapi/swag/fileutils/fs.go b/vendor/github.com/go-openapi/swag/fileutils/fs.go new file mode 100644 index 000000000..56b0a1f53 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/fileutils/fs.go @@ -0,0 +1,106 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package fileutils + +import ( + "fmt" + "io/fs" + "os" +) + +// OsFS exposes package os features as an [fs.FS], without having to use [os.Root]. +// +// Existing alternatives from the standard library are [os.DirFS], which requires a base directory, +// and [os.Root.FS], which requires a root. +// [OsFS] is intended to be used when none of these alternatives are workable, +// that is when the caller does not know which root it should run in. +// +// Names are passed to the os package unchanged, +// so [OsFS] accepts absolute and relative paths, which a conforming [fs.FS] rejects. +// It offers no containment: every file that the process may read is reachable. +// +// [OsFS] implements [fs.FS], [fs.ReadFileFS] and [fs.ReadDirFS]. +type OsFS struct { +} + +// NewReadOnlyOsFS builds an [OsFS], a read-only view of the os file system. +func NewReadOnlyOsFS() *OsFS { + return &OsFS{} +} + +// Open opens the named file for reading. +func (f *OsFS) Open(name string) (fs.File, error) { + return os.Open(name) +} + +// ReadFile reads the named file and returns its content. +func (f *OsFS) ReadFile(name string) ([]byte, error) { + return os.ReadFile(name) +} + +// ReadDir reads the named directory and returns its entries sorted by file name. +func (f *OsFS) ReadDir(name string) ([]fs.DirEntry, error) { + return os.ReadDir(name) +} + +// FileReaderFS makes a [fs.FS] into a [fs.ReadFileFS], with a [FileReaderFS.ReadFile] method. +type FileReaderFS struct { + fs.FS +} + +// NewFileReaderFS transforms a [fs.FS] into a [fs.ReadFileFS]. +func NewFileReaderFS(base fs.FS) *FileReaderFS { + return &FileReaderFS{ + FS: base, + } +} + +// ReadFile reads the named file from the base file system and returns its content. +func (f *FileReaderFS) ReadFile(name string) ([]byte, error) { + return fs.ReadFile(f.FS, name) +} + +// GlobOsFS is an [OsFS] that also implements [fs.GlobFS], with a [GlobOsFS.Glob] method. +type GlobOsFS struct { + *OsFS +} + +// NewGlobOsFS is like [NewReadOnlyOsFS], augmented to match the [fs.GlobFS] interface. +func NewGlobOsFS() *GlobOsFS { + return &GlobOsFS{ + OsFS: NewReadOnlyOsFS(), + } +} + +// Glob returns the names matching pattern, sorted in lexical order. +// +// It returns a nil slice and no error when nothing matches, +// and [path.ErrBadPattern] when the pattern is malformed. +func (f *GlobOsFS) Glob(pattern string) ([]string, error) { + return fs.Glob(f.OsFS, pattern) +} + +// MustSub re-roots a file system at one of its directories, and panics when it cannot. +// +// It is [fs.Sub] for the cases where the directory is a constant of the program, such as a folder +// of an [embed.FS] assembled at initialization time: there, a failure means the program is wrong, +// not that its input is. +// +// Use [fs.Sub] itself whenever the directory comes from the outside, such as a flag, +// a configuration file or a request, so that an invalid one is reported rather than fatal. +// +// It is meant to be composed inline: +// +// assets := NewOverlayFS( +// MustSub(embedded, "templates"), +// MustSub(embedded, "templates/contrib/mine"), +// ) +func MustSub(fsys fs.FS, dir string) fs.FS { + subFS, err := fs.Sub(fsys, dir) + if err != nil { + panic(fmt.Errorf("fileutils.MustSub: cannot re-root at %q: %w", dir, err)) + } + + return subFS +} diff --git a/vendor/github.com/go-openapi/swag/fileutils/mapfs.go b/vendor/github.com/go-openapi/swag/fileutils/mapfs.go new file mode 100644 index 000000000..5a81879f6 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/fileutils/mapfs.go @@ -0,0 +1,366 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package fileutils + +import ( + "bytes" + "errors" + "io" + "io/fs" + "path" + "slices" + "strings" + "time" +) + +// Default modes of the entries of a [MapFS]. +// +// A [MapFS] is read-only, so its files and directories are readable and never writable. +const ( + // DefaultFileMode is the mode reported by a file with no [MapFile.Mode] of its own. + DefaultFileMode fs.FileMode = 0o444 + + // DefaultDirMode is the mode reported by the directories of a [MapFS]. + DefaultDirMode fs.FileMode = fs.ModeDir | 0o555 +) + +var ( + // errNameIsFileAndDir is reported when the same name is held as a file and as a parent directory. + errNameIsFileAndDir = errors.New("name is held both as a file and as a directory") + + // errNotDir is reported when a regular file is listed as a directory. + errNotDir = errors.New("not a directory") +) + +// MapFile is a file held by a [MapFS]. +// +// Only [MapFile.Data] is required. [NewMapFS] fills the remaining fields with presets when they +// are left to their zero value. +type MapFile struct { + // Data is the content of the file. + Data []byte + + // Mode is the file mode reported by [fs.FileInfo.Mode]. Zero means [DefaultFileMode]. + Mode fs.FileMode + + // ModTime is the modification time reported by [fs.FileInfo.ModTime]. + // + // The zero value is left as is, so that a [MapFS] built from the same input twice + // reports the same metadata. + ModTime time.Time + + // Sys is the opaque value reported by [fs.FileInfo.Sys]. + Sys any +} + +// MapFS is a read-only in-memory [fs.FS], built from a map of file names to content. +// +// It is intended for the cases where the files to serve are held in memory rather than on disk: +// an overlay assembled from raw bytes, assets that a configuration provides, or a fixture in a test. +// +// Names are slash-separated paths, as accepted by [fs.ValidPath]. [NewMapFS] cleans them, +// so a name may be given with a leading "./" or "/", or with redundant elements. +// A name that remains invalid once cleaned, such as one climbing above the root, is reported +// as an error rather than dropped. +// +// Separators are never translated, so that the same input yields the same file system on every +// platform: a caller holding os paths converts them with [path/filepath.ToSlash] beforehand. +// +// Directories are implied by the names of the files, and are indexed once, when the file system +// is built: a name holds a file, and every one of its parents holds a directory. +// The root "." always exists, even when the file system holds no file at all. +// +// [MapFS] implements [fs.FS], [fs.ReadFileFS], [fs.StatFS] and [fs.ReadDirFS], but not [fs.GlobFS]: +// [fs.Glob] resolves against it all the same, through [MapFS.ReadDir]. +type MapFS struct { + files map[string]MapFile + dirs map[string][]fs.DirEntry +} + +// NewMapFS builds an in-memory file system from a map of file names to content. +// +// Names are normalized, and reported as an error when they remain invalid, or when the same name +// is held both as a file and as the parent directory of another one. +// A [MapFile] left with a zero [MapFile.Mode] reports [DefaultFileMode]. +// +// The map is copied, so adding or removing an entry afterwards leaves the file system alone. +// The contents are not: a caller that writes to a [MapFile.Data] slice it still holds changes +// what the file system serves. Hand over a slice nothing else keeps, or copy it first. +func NewMapFS(files map[string]MapFile) (*MapFS, error) { + normalized := make(map[string]MapFile, len(files)) + + for name, file := range files { + clean, err := normalizeMapName(name) + if err != nil { + return nil, err + } + + if _, isDuplicate := normalized[clean]; isDuplicate { + return nil, &fs.PathError{Op: "newmapfs", Path: clean, Err: fs.ErrExist} + } + + if file.Mode == 0 { + file.Mode = DefaultFileMode + } + + normalized[clean] = file + } + + dirs, err := indexMapDirs(normalized) + if err != nil { + return nil, err + } + + return &MapFS{ + files: normalized, + dirs: dirs, + }, nil +} + +// FromRawMap builds the files of a [MapFS] from raw contents, leaving every metadata field to its preset. +// +// It is the shortest way to a [MapFS] when all the caller holds is bytes: +// +// mapFS, err := NewMapFS(FromRawMap(map[string][]byte{ +// "folder/file1": raw1, +// "folder/file2": raw2, +// })) +func FromRawMap(raw map[string][]byte) map[string]MapFile { + files := make(map[string]MapFile, len(raw)) + for name, data := range raw { + files[name] = MapFile{Data: data} + } + + return files +} + +// Open opens the named file or directory. +// +// Opening a directory yields a [fs.ReadDirFile] reporting the same entries as [MapFS.ReadDir]. +func (f *MapFS) Open(name string) (fs.File, error) { + if !fs.ValidPath(name) { + return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid} + } + + if file, isFile := f.files[name]; isFile { + return &openMapFile{ + info: mapFileInfo{name: path.Base(name), file: file}, + reader: bytes.NewReader(file.Data), + }, nil + } + + entries, isDir := f.dirs[name] + if !isDir { + return nil, notFound("open", name) + } + + return &openMapDir{info: mapDirInfo{name: path.Base(name)}, entries: entries}, nil +} + +// ReadFile reads the named file and returns a copy of its content. +func (f *MapFS) ReadFile(name string) ([]byte, error) { + if !fs.ValidPath(name) { + return nil, &fs.PathError{Op: "read", Path: name, Err: fs.ErrInvalid} + } + + file, isFile := f.files[name] + if !isFile { + if _, isDir := f.dirs[name]; isDir { + return nil, &fs.PathError{Op: "read", Path: name, Err: errIsDir} + } + + return nil, notFound("read", name) + } + + // a caller mutating the result would otherwise mutate what the file system serves + return slices.Clone(file.Data), nil +} + +// Stat returns the [fs.FileInfo] of the named file or directory. +func (f *MapFS) Stat(name string) (fs.FileInfo, error) { + if !fs.ValidPath(name) { + return nil, &fs.PathError{Op: "stat", Path: name, Err: fs.ErrInvalid} + } + + if file, isFile := f.files[name]; isFile { + return mapFileInfo{name: path.Base(name), file: file}, nil + } + + if _, isDir := f.dirs[name]; isDir { + return mapDirInfo{name: path.Base(name)}, nil + } + + return nil, notFound("stat", name) +} + +// ReadDir lists the named directory, with its entries sorted by file name. +func (f *MapFS) ReadDir(name string) ([]fs.DirEntry, error) { + if !fs.ValidPath(name) { + return nil, &fs.PathError{Op: "readdir", Path: name, Err: fs.ErrInvalid} + } + + entries, isDir := f.dirs[name] + if !isDir { + if _, isFile := f.files[name]; isFile { + return nil, &fs.PathError{Op: "readdir", Path: name, Err: errNotDir} + } + + return nil, notFound("readdir", name) + } + + // the index is shared by every caller, so it must not escape + return slices.Clone(entries), nil +} + +// normalizeMapName turns the name of a file into the cleaned form that [fs.ValidPath] accepts. +// +// Separators are left alone: an [fs.FS] name is slash-separated by definition, and translating +// them here would resolve the same input differently depending on the platform. +func normalizeMapName(name string) (string, error) { + clean := path.Clean(strings.TrimPrefix(name, "/")) + + if !fs.ValidPath(clean) || clean == "." { + return "", &fs.PathError{Op: "newmapfs", Path: name, Err: fs.ErrInvalid} + } + + return clean, nil +} + +// indexMapDirs builds the directory index of a [MapFS], once, from the names of its files. +// +// Every parent of a file name holds a directory, up to the root, which always exists. +func indexMapDirs(files map[string]MapFile) (map[string][]fs.DirEntry, error) { + children := map[string]map[string]bool{".": {}} // directory -> child base name -> is a directory + + for name := range files { + dir := path.Dir(name) + addMapChild(children, dir, path.Base(name), false) + + // every ancestor of the file holds a directory + for dir != "." { + parent := path.Dir(dir) + addMapChild(children, parent, path.Base(dir), true) + dir = parent + } + } + + dirs := make(map[string][]fs.DirEntry, len(children)) + for dir, names := range children { + if _, isFile := files[dir]; isFile { + return nil, &fs.PathError{Op: "newmapfs", Path: dir, Err: errNameIsFileAndDir} + } + + entries := make([]fs.DirEntry, 0, len(names)) + for base, isDir := range names { + if isDir { + entries = append(entries, mapDirInfo{name: base}) + + continue + } + + entries = append(entries, mapFileInfo{name: base, file: files[path.Join(dir, base)]}) + } + + slices.SortFunc(entries, func(a, b fs.DirEntry) int { + return strings.Compare(a.Name(), b.Name()) + }) + dirs[dir] = entries + } + + return dirs, nil +} + +// addMapChild records that a directory holds an entry. +func addMapChild(children map[string]map[string]bool, dir, base string, isDir bool) { + entries, exists := children[dir] + if !exists { + entries = make(map[string]bool) + children[dir] = entries + } + + entries[base] = isDir +} + +// mapFileInfo reports the metadata of a file of a [MapFS]. It is both a [fs.FileInfo] and a [fs.DirEntry]. +type mapFileInfo struct { + name string + file MapFile +} + +func (i mapFileInfo) Name() string { return i.name } +func (i mapFileInfo) Size() int64 { return int64(len(i.file.Data)) } +func (i mapFileInfo) Mode() fs.FileMode { return i.file.Mode } +func (i mapFileInfo) Type() fs.FileMode { return i.file.Mode.Type() } +func (i mapFileInfo) ModTime() time.Time { return i.file.ModTime } +func (i mapFileInfo) IsDir() bool { return false } +func (i mapFileInfo) Sys() any { return i.file.Sys } +func (i mapFileInfo) Info() (fs.FileInfo, error) { return i, nil } + +// mapDirInfo reports the metadata of a directory of a [MapFS]. It is both a [fs.FileInfo] and a [fs.DirEntry]. +// +// Directories are implied by the names of the files, so they carry no metadata of their own. +type mapDirInfo struct { + name string +} + +func (i mapDirInfo) Name() string { return i.name } +func (i mapDirInfo) Size() int64 { return 0 } +func (i mapDirInfo) Mode() fs.FileMode { return DefaultDirMode } +func (i mapDirInfo) Type() fs.FileMode { return fs.ModeDir } +func (i mapDirInfo) ModTime() time.Time { return time.Time{} } +func (i mapDirInfo) IsDir() bool { return true } +func (i mapDirInfo) Sys() any { return nil } +func (i mapDirInfo) Info() (fs.FileInfo, error) { return i, nil } + +// openMapFile is the [fs.File] returned when opening a file of a [MapFS]. +type openMapFile struct { + info mapFileInfo + reader *bytes.Reader +} + +func (f *openMapFile) Stat() (fs.FileInfo, error) { return f.info, nil } + +func (f *openMapFile) Close() error { return nil } + +func (f *openMapFile) Read(p []byte) (int, error) { return f.reader.Read(p) } + +func (f *openMapFile) Seek(offset int64, whence int) (int64, error) { + return f.reader.Seek(offset, whence) +} + +// openMapDir is the [fs.ReadDirFile] returned when opening a directory of a [MapFS]. +type openMapDir struct { + info mapDirInfo + entries []fs.DirEntry + offset int +} + +func (d *openMapDir) Stat() (fs.FileInfo, error) { return d.info, nil } + +func (d *openMapDir) Close() error { return nil } + +func (d *openMapDir) Read([]byte) (int, error) { + return 0, &fs.PathError{Op: "read", Path: d.info.name, Err: errIsDir} +} + +// ReadDir returns the next n entries, or all the remaining ones when n is not positive. +func (d *openMapDir) ReadDir(n int) ([]fs.DirEntry, error) { + remaining := len(d.entries) - d.offset + if n <= 0 { + entries := slices.Clone(d.entries[d.offset:]) + d.offset = len(d.entries) + + return entries, nil + } + + if remaining == 0 { + return nil, io.EOF + } + + n = min(n, remaining) + entries := slices.Clone(d.entries[d.offset : d.offset+n]) + d.offset += n + + return entries, nil +} diff --git a/vendor/github.com/go-openapi/swag/fileutils/opaque.go b/vendor/github.com/go-openapi/swag/fileutils/opaque.go new file mode 100644 index 000000000..526e86736 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/fileutils/opaque.go @@ -0,0 +1,98 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package fileutils + +import ( + "io/fs" + "path" +) + +// OpaqueDirFS is a file system that entirely owns some of its directories. +// +// [OverlayFS] neither merges an opaque directory with the layers below it, +// nor resolves any name under it against them: +// what the owning layer holds replaces what they hold under the same name. +// +// [OpaqueFS] is the implementation provided by this package. +type OpaqueDirFS interface { + fs.FS + + // IsOpaqueDir reports whether a directory was declared as entirely owned by this file system. + // + // It answers from the declarations given to [NewOpaqueFS], and does not check that the file + // system holds the directory: a name declared opaque reports true either way. + // [OverlayFS] consults it only for a layer that holds the directory. + IsOpaqueDir(name string) bool +} + +// OpaqueDirsAll declares that a file system owns every directory it holds, except its root. +// +// It is the only pattern recognized by [NewOpaqueFS]: directories are otherwise matched +// by their exact name. +const OpaqueDirsAll = "*" + +// OpaqueFS makes a [fs.FS] into an [OpaqueDirFS], by declaring the directories that it owns. +type OpaqueFS struct { + fs.FS + + opaqueDirs map[string]struct{} +} + +// NewOpaqueFS declares the directories that a file system entirely owns, +// so that they shadow the layers below when it is stacked in an [OverlayFS]. +// +// Directories are slash-separated paths, as accepted by [fs.ValidPath], and are cleaned. +// Declaring "." makes the whole file system opaque, down from its root. +// Declaring [OpaqueDirsAll] makes every directory opaque but the root, +// so that the root still merges and the layers below keep contributing what they hold beside it. +// +// Declaring a directory that this file system does not hold changes nothing once it is stacked. +// [OverlayFS] skips a layer that does not hold the directory before it consults opacity, +// so the layers below keep resolving that directory and everything under it. +func NewOpaqueFS(base fs.FS, dirs ...string) *OpaqueFS { + opaqueDirs := make(map[string]struct{}, len(dirs)) + for _, dir := range dirs { + opaqueDirs[path.Clean(dir)] = struct{}{} + } + + return &OpaqueFS{ + FS: base, + opaqueDirs: opaqueDirs, + } +} + +// IsOpaqueDir reports whether a directory was declared as entirely owned by this file system. +// +// It answers from the declarations given to [NewOpaqueFS], and does not check that the file +// system holds the directory: a name declared opaque reports true either way. +// [OverlayFS] consults it only for a layer that holds the directory. +func (f *OpaqueFS) IsOpaqueDir(name string) bool { + if _, isOpaque := f.opaqueDirs[name]; isOpaque { + return true + } + + if name == "." { + // the root is owned only when it is declared explicitly + return false + } + + _, ownsAll := f.opaqueDirs[OpaqueDirsAll] + + return ownsAll +} + +// ReadFile reads a file from the wrapped file system. +func (f *OpaqueFS) ReadFile(name string) ([]byte, error) { + return fs.ReadFile(f.FS, name) +} + +// Stat returns the [fs.FileInfo] of a name in the wrapped file system. +func (f *OpaqueFS) Stat(name string) (fs.FileInfo, error) { + return fs.Stat(f.FS, name) +} + +// ReadDir lists a directory of the wrapped file system. +func (f *OpaqueFS) ReadDir(name string) ([]fs.DirEntry, error) { + return fs.ReadDir(f.FS, name) +} diff --git a/vendor/github.com/go-openapi/swag/fileutils/overlay.go b/vendor/github.com/go-openapi/swag/fileutils/overlay.go new file mode 100644 index 000000000..d67ab6a5f --- /dev/null +++ b/vendor/github.com/go-openapi/swag/fileutils/overlay.go @@ -0,0 +1,345 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package fileutils + +import ( + "errors" + "io" + "io/fs" + "path" + "slices" + "strings" + "syscall" +) + +// OverlayFS is a read-only [fs.FS] that stacks overlays on top of a base file system. +// +// A name is resolved in the topmost layer that holds it, then down to the base. +// See [NewOverlayFS] for the order in which layers are stacked. +// When the name is absent from all layers, every method returns a [fs.PathError] that reports +// the name and matches [fs.ErrNotExist]. +// +// [OverlayFS] implements [fs.FS], [fs.ReadFileFS], [fs.StatFS] and [fs.ReadDirFS], but not [fs.GlobFS]. +// A directory returns an error when the resolved layer does not support reading directories. +// +// Directories are merged: a directory reports the union of the entries held by every layer, +// and the topmost layer wins whenever the same name is held by several of them. +// A layer may claim a directory for itself with [NewOpaqueFS], which stops the merge +// and hides everything the lower layers hold under that directory. +type OverlayFS struct { + layers []fs.FS +} + +// NewOverlayFS builds an overlay file system from a base file system and a list of overlays. +// +// Overlays are stacked in the order in which they are provided: +// the last one sits on top and is resolved first, then the preceding ones in reverse order. +// The base is always resolved last. +// +// An empty list of overlays yields a file system that resolves against the base alone. +func NewOverlayFS(base fs.FS, overlays ...fs.FS) *OverlayFS { + layers := make([]fs.FS, 0, len(overlays)+1) + for _, overlay := range slices.Backward(overlays) { + layers = append(layers, overlay) + } + layers = append(layers, base) + + return &OverlayFS{ + layers: layers, + } +} + +// Open opens a file, resolving layers from the topmost overlay down to the base. +// +// Opening a directory yields a [fs.ReadDirFile] that reports the same entries as +// [OverlayFS.ReadDir], so that a merged directory reads alike either way. +func (f *OverlayFS) Open(name string) (fs.File, error) { + file, err := f.openInLayers(name) + if err != nil { + return nil, err + } + + info, err := file.Stat() + if err != nil { + _ = file.Close() + + return nil, err + } + + if !info.IsDir() { + return file, nil + } + + // the entries of a directory come from every layer, not from the one that resolved it + _ = file.Close() + + entries, err := f.readMergedDir(name) + if err != nil { + return nil, err + } + + return &mergedDir{name: name, info: info, entries: entries}, nil +} + +// ReadFile reads a file, resolving layers from the topmost overlay down to the base. +func (f *OverlayFS) ReadFile(name string) ([]byte, error) { + layer, err := f.findInLayers("open", name) + if err != nil { + return nil, err + } + + return fs.ReadFile(layer, name) +} + +// Stat returns the [fs.FileInfo] of a file, resolving layers from the topmost overlay down to the base. +func (f *OverlayFS) Stat(name string) (fs.FileInfo, error) { + layer, err := f.findInLayers("stat", name) + if err != nil { + return nil, err + } + + return fs.Stat(layer, name) +} + +// ReadDir lists a directory, resolving layers from the topmost overlay down to the base. +// +// The entries of every layer holding the directory are merged, sorted by file name, +// and a name held by several layers is reported by the topmost of them. +// The merge stops at the topmost layer that owns the directory, as declared by [NewOpaqueFS]. +func (f *OverlayFS) ReadDir(name string) ([]fs.DirEntry, error) { + return f.readMergedDir(name) +} + +// readMergedDir collects the entries of every layer that holds a directory. +// +// A name that is not a directory in some layer shadows the layers below it, +// just like a regular file does. +func (f *OverlayFS) readMergedDir(name string) ([]fs.DirEntry, error) { + var ( + merged []fs.DirEntry + found bool + ) + seen := make(map[string]struct{}) + + for _, layer := range f.layers { + info, err := fs.Stat(layer, name) + if err != nil { + if !isNotFound(err) { + return nil, err + } + + if ownsSubtreeOf(layer, name) { + break + } + + continue + } + + if !info.IsDir() { + if found { + // a directory held by an upper layer shadows this entry + break + } + + // let the layer report why the name cannot be listed + return fs.ReadDir(layer, name) + } + + entries, err := fs.ReadDir(layer, name) + if err != nil { + return nil, err + } + + found = true + for _, entry := range entries { + if _, isShadowed := seen[entry.Name()]; isShadowed { + continue + } + + seen[entry.Name()] = struct{}{} + merged = append(merged, entry) + } + + if declaresOpaqueDir(layer, name) || ownsSubtreeOf(layer, name) { + // this layer owns the directory, or one of its parents: + // the layers below it contribute nothing + break + } + } + + if !found { + return nil, notFound("readdir", name) + } + + slices.SortFunc(merged, func(a, b fs.DirEntry) int { + return strings.Compare(a.Name(), b.Name()) + }) + + return merged, nil +} + +// openInLayers opens a name in the topmost layer that holds it. +func (f *OverlayFS) openInLayers(name string) (fs.File, error) { + for _, layer := range f.layers { + file, err := layer.Open(name) + if err == nil { + return file, nil + } + + if !isNotFound(err) { + return nil, err + } + + if ownsSubtreeOf(layer, name) { + break + } + } + + return nil, notFound("open", name) +} + +// findInLayers returns the topmost layer that holds a name. +// +// op names the operation reported by the [fs.PathError] raised when no layer holds the name. +func (f *OverlayFS) findInLayers(op, name string) (fs.FS, error) { + for _, layer := range f.layers { + err := probeInLayer(layer, name) + if err == nil { + return layer, nil + } + + if !isNotFound(err) { + return nil, err + } + + if ownsSubtreeOf(layer, name) { + break + } + } + + return nil, notFound(op, name) +} + +// probeInLayer reports the error raised by a layer when looking a name up. +// +// A layer implementing [fs.StatFS] is probed with Stat. +// Otherwise the name is opened, then closed again. +func probeInLayer(layer fs.FS, name string) error { + if statFS, supportsStat := layer.(fs.StatFS); supportsStat { + _, err := statFS.Stat(name) + + return err + } + + file, err := layer.Open(name) + if err == nil { + _ = file.Close() + } + + return err +} + +// declaresOpaqueDir tells whether a layer marks a directory as entirely owned. +func declaresOpaqueDir(layer fs.FS, name string) bool { + opaque, isOpaqueFS := layer.(OpaqueDirFS) + + return isOpaqueFS && opaque.IsOpaqueDir(name) +} + +// ownsDir tells whether a layer marks a directory as entirely owned, and holds it. +func ownsDir(layer fs.FS, name string) bool { + if !declaresOpaqueDir(layer, name) { + return false + } + + info, err := fs.Stat(layer, name) + + return err == nil && info.IsDir() +} + +// ownsSubtreeOf tells whether a layer owns one of the parent directories of a name. +// +// The layers below such a layer hold nothing that is reachable under that name. +func ownsSubtreeOf(layer fs.FS, name string) bool { + if _, isOpaqueFS := layer.(OpaqueDirFS); !isOpaqueFS { + return false + } + + for dir := path.Dir(name); ; { + if ownsDir(layer, dir) { + return true + } + + // "." and "/" are their own parent, so this is where the walk up ends + parent := path.Dir(dir) + if parent == dir { + return false + } + + dir = parent + } +} + +// errIsDir is reported when a merged directory is read as a regular file. +var errIsDir = errors.New("is a directory") + +// mergedDir is the [fs.ReadDirFile] returned when opening a directory with merged layers. +// +// Its [fs.FileInfo] is the one of the topmost layer holding the directory, +// while its entries come from all the layers holding it. +type mergedDir struct { + name string + info fs.FileInfo + entries []fs.DirEntry + offset int +} + +func (d *mergedDir) Stat() (fs.FileInfo, error) { return d.info, nil } + +func (d *mergedDir) Close() error { return nil } + +func (d *mergedDir) Read([]byte) (int, error) { + return 0, &fs.PathError{Op: "read", Path: d.name, Err: errIsDir} +} + +// ReadDir returns the next n entries, or all the remaining ones when n is not positive. +func (d *mergedDir) ReadDir(n int) ([]fs.DirEntry, error) { + remaining := len(d.entries) - d.offset + if n <= 0 { + entries := d.entries[d.offset:] + d.offset = len(d.entries) + + return entries, nil + } + + if remaining == 0 { + return nil, io.EOF + } + + n = min(n, remaining) + entries := d.entries[d.offset : d.offset+n] + d.offset += n + + return entries, nil +} + +// notFound builds the error reported when a name is absent from all layers. +// +// It mirrors what the os package raises for a missing file, +// so that a caller may retrieve the name from the error alone. +func notFound(op, name string) error { + return &fs.PathError{Op: op, Path: name, Err: fs.ErrNotExist} +} + +// isNotFound tells whether an error raised by a layer means that the name is absent from that layer. +// +// The whole error chain is inspected, so a layer that wraps its errors resolves like any other, +// and so does a layer that is itself an [OverlayFS]. +// +// [syscall.ENOTDIR] is matched explicitly, because a path traversing a regular file +// does not report [fs.ErrNotExist] on all platforms. +// Any other error stops the resolution and is reported to the caller. +func isNotFound(err error) bool { + return errors.Is(err, fs.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) +} diff --git a/vendor/github.com/go-openapi/swag/fileutils/path.go b/vendor/github.com/go-openapi/swag/fileutils/path.go index dd09f690b..647df7609 100644 --- a/vendor/github.com/go-openapi/swag/fileutils/path.go +++ b/vendor/github.com/go-openapi/swag/fileutils/path.go @@ -10,10 +10,17 @@ import ( "strings" ) -// GOPATHKey represents the env key for gopath +// GOPATHKey is the name of the environment variable that holds the go search path. const GOPATHKey = "GOPATH" -// FindInSearchPath finds a package in a provided lists of paths +// FindInSearchPath finds a package in a list of search paths. +// +// searchPath lists directories separated by the OS path separator, +// in the form accepted by [filepath.SplitList]. +// Each directory is probed for a src/pkg subdirectory. +// +// It returns the first match, with symlinks resolved, +// or an empty string when the package is not found in any of the directories. func FindInSearchPath(searchPath, pkg string) string { pathsList := filepath.SplitList(searchPath) for _, path := range pathsList { @@ -26,7 +33,9 @@ func FindInSearchPath(searchPath, pkg string) string { return "" } -// FindInGoSearchPath finds a package in the $GOPATH:$GOROOT +// FindInGoSearchPath finds a package in $GOPATH and $GOROOT. +// +// It returns an empty string when the package is not found. // // Deprecated: this function is no longer relevant with modern go. // It uses [runtime.GOROOT] under the hood, which is deprecated as of go1.24. @@ -34,7 +43,10 @@ func FindInGoSearchPath(pkg string) string { return FindInSearchPath(FullGoSearchPath(), pkg) } -// FullGoSearchPath gets the search paths for finding packages +// FullGoSearchPath returns the search paths in which a package may be found. +// +// It joins $GOPATH, which defaults to $HOME/go when unset, with [runtime.GOROOT]. +// The two are separated by a colon, so the result is not usable on windows. // // Deprecated: this function is no longer relevant with modern go. // It uses [runtime.GOROOT] under the hood, which is deprecated as of go1.24. diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go index f114f1f1a..cfcd42685 100644 --- a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go @@ -10,6 +10,11 @@ package json // It mirrors the limit enforced by the standard library's [encoding/json] decoder // (see encoding/json's internal maxNestingDepth), which this adapter would otherwise // not benefit from since it drives [encoding/json.Decoder.Token] directly. +// +// With encoding/json v2 (GOEXPERIMENT=jsonv2, the default from go1.27), Token applies +// that same limit itself and reports "exceeded max depth" before this counter fires. +// Set a lower limit with [WithMaxNestingDepth] to be rejected earlier than the stdlib; +// a higher one does not lift the stdlib's own 10,000-level ceiling on the decode path. const defaultMaxNestingDepth = 10000 // Option selects options for the stdlib adapter. diff --git a/vendor/github.com/go-openapi/validate/.golangci.yml b/vendor/github.com/go-openapi/validate/.golangci.yml index b8875d7ab..c05f38e9d 100644 --- a/vendor/github.com/go-openapi/validate/.golangci.yml +++ b/vendor/github.com/go-openapi/validate/.golangci.yml @@ -10,6 +10,7 @@ linters: - gomodguard - gomodguard_v2 - exhaustruct + - exhaustruct_v5 - ireturn - nlreturn - nestif diff --git a/vendor/github.com/go-openapi/validate/BENCHMARK.md b/vendor/github.com/go-openapi/validate/BENCHMARK.md deleted file mode 100644 index 0353eae5b..000000000 --- a/vendor/github.com/go-openapi/validate/BENCHMARK.md +++ /dev/null @@ -1,34 +0,0 @@ -# Benchmark - -Validating the Kubernetes Swagger API - -## v0.22.6: 60,000,000 allocs - -``` -goos: linux -goarch: amd64 -pkg: github.com/go-openapi/validate -cpu: AMD Ryzen 7 5800X 8-Core Processor -Benchmark_KubernetesSpec/validating_kubernetes_API-16 1 8549863982 ns/op 7067424936 B/op 59583275 allocs/op -``` - -## After refact PR: minor but noticeable improvements: 25,000,000 allocs - -``` -go test -bench Spec -goos: linux -goarch: amd64 -pkg: github.com/go-openapi/validate -cpu: AMD Ryzen 7 5800X 8-Core Processor -Benchmark_KubernetesSpec/validating_kubernetes_API-16 1 4064535557 ns/op 3379715592 B/op 25320330 allocs/op -``` - -## After reduce GC pressure PR: 17,000,000 allocs - -``` -goos: linux -goarch: amd64 -pkg: github.com/go-openapi/validate -cpu: AMD Ryzen 7 5800X 8-Core Processor -Benchmark_KubernetesSpec/validating_kubernetes_API-16 1 3758414145 ns/op 2593881496 B/op 17111373 allocs/op -``` diff --git a/vendor/github.com/go-openapi/validate/README.md b/vendor/github.com/go-openapi/validate/README.md index b814a2ef1..aa8eea563 100644 --- a/vendor/github.com/go-openapi/validate/README.md +++ b/vendor/github.com/go-openapi/validate/README.md @@ -5,7 +5,7 @@ -[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] +[![Release][release-badge]][release-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] [![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] @@ -98,8 +98,6 @@ Maintainers can cut a new release by either: [release-badge]: https://badge.fury.io/gh/go-openapi%2Fvalidate.svg [release-url]: https://badge.fury.io/gh/go-openapi%2Fvalidate -[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/validate -[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/validate [codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/validate [codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/validate diff --git a/vendor/github.com/go-openapi/validate/collection_format.go b/vendor/github.com/go-openapi/validate/collection_format.go new file mode 100644 index 000000000..a77ba564d --- /dev/null +++ b/vendor/github.com/go-openapi/validate/collection_format.go @@ -0,0 +1,131 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package validate + +import ( + "fmt" + "strconv" + + "github.com/go-openapi/spec" +) + +// validateCollectionFormats warns about a collectionFormat that has no effect. +// +// collectionFormat says how to join the members of an array into one value on the wire — csv, ssv, +// tsv, pipes, or multi for a parameter repeated once per member: +// +// parameters: +// - name: tags +// in: query +// type: array +// items: { type: string } +// collectionFormat: pipes +// +// There is nothing to join when the type is not array, so a collectionFormat written on a string or +// an integer does nothing. Swagger 2.0 says the member "determines the format of the array if type +// array is used" and stops there — it never forbids writing it elsewhere, so this is a warning and +// the specification stays valid. +// +// The meta-schema already covers the rest of the collectionFormat rules, and covers them at every +// location: the value must be one of csv, ssv, tsv or pipes, widened with multi for a query or +// formData parameter, where repeating the parameter is possible. A body parameter cannot carry the +// member at all. None of that needs a rule here. +// +// Only a parameter, a header and an items carry a collectionFormat — [spec.SimpleSchema] holds it, +// and [spec.Schema] has no such member. So this walks what the operations of the document declare, +// the way [SpecValidator.validateItems] does, and never looks at a schema. A JSON schema validated +// on its own is untouched by this rule. +func (s *SpecValidator) validateCollectionFormats() *Result { + res := validatorPools.results.Borrow() + + operations := s.analyzer.Operations() + for _, method := range sortedKeys(operations) { + byPath := operations[method] + for _, path := range sortedKeys(byPath) { + op := byPath[path] + + for _, param := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) { + if param.In == swaggerBody { + // a body parameter describes itself with a schema, and the meta-schema + // forbids it a collectionFormat outright + continue + } + + at := s.parameterPath(path, method, param.In, param.Name) + in := fmt.Sprintf("parameter %q", param.Name) + checkCollectionFormat(at, param.CollectionFormat, param.Type, in, res) + checkItemsCollectionFormats(at, param.Items, in, res) + } + + for _, response := range responsesOf(op) { + at := responsePath(path, method, response.code) + for _, name := range sortedKeys(response.resp.Headers) { + header := response.resp.Headers[name] + headerAt := at.children(swaggerHeaders, name) + in := fmt.Sprintf("header %q", name) + checkCollectionFormat(headerAt, header.CollectionFormat, header.Type, in, res) + checkItemsCollectionFormats(headerAt, header.Items, in, res) + } + } + } + } + + return res +} + +// codedResponse is a response together with the code the operation files it under, "default" +// included. +type codedResponse struct { + code string + resp spec.Response +} + +// responsesOf lists the responses an operation declares, in a settled order: the default response +// first, then the status codes in ascending order. +func responsesOf(op *spec.Operation) []codedResponse { + if op == nil || op.Responses == nil { + return nil + } + + var responses []codedResponse + if op.Responses.Default != nil { + responses = append(responses, codedResponse{code: jsonDefault, resp: *op.Responses.Default}) + } + + for _, code := range sortedKeys(op.Responses.StatusCodeResponses) { + responses = append(responses, codedResponse{ + code: strconv.Itoa(code), + resp: op.Responses.StatusCodeResponses[code], + }) + } + + return responses +} + +// checkItemsCollectionFormats checks the items of a parameter or header, then the items of those +// items, as deep as the document nests them. +// +// Every level is named the same way in a message: an array of arrays that writes a pointless +// collectionFormat twice is one thing to fix, and the deeper location is reported only when the +// shallower one is sound. +func checkItemsCollectionFormats(at pathSegments, items *spec.Items, in string, res *Result) { + for items != nil { + at = at.child(jsonItems) + checkCollectionFormat(at, items.CollectionFormat, items.Type, "items of "+in, res) + items = items.Items + } +} + +// checkCollectionFormat warns when a collectionFormat is written on something that is not an array. +// +// A missing collectionFormat has nothing to answer for, and neither has a missing type: a document +// that leaves the type out is already reported by the meta-schema, and guessing what it meant here +// would only add noise. +func checkCollectionFormat(at pathSegments, collectionFormat, typ, in string, res *Result) { + if collectionFormat == "" || typ == "" || typ == arrayType { + return + } + + res.addWarningsAt(at.child(swaggerCollectionFormat), collectionFormatIgnoredMsg(collectionFormat, in, typ)) +} diff --git a/vendor/github.com/go-openapi/validate/discriminator.go b/vendor/github.com/go-openapi/validate/discriminator.go new file mode 100644 index 000000000..7a4ab4167 --- /dev/null +++ b/vendor/github.com/go-openapi/validate/discriminator.go @@ -0,0 +1,156 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package validate + +import ( + "slices" + + "github.com/go-openapi/spec" +) + +// validateDiscriminators checks the discriminator of every definition, and of every schema a +// definition holds inline. +// +// A discriminator names the property that tells subtypes apart: +// +// Pet: +// discriminator: petType +// required: [ petType ] +// properties: +// petType: { type: string } +// +// Swagger 2.0 asks two things of that property: the schema must define it, and must list it as +// required. Both matter for the same reason — an instance carries its subtype in that property, +// so a subtype cannot be resolved from an instance that has nowhere to put the value, or that is +// free to leave it out. +// +// The JSON meta-schema types discriminator as a plain string and never compares it against +// properties or required, so it can express neither check. +// +// A property contributed by an allOf member counts as defined, and one that member requires counts +// as required: [SpecValidator.declaresProperty] already reads a composed definition that way for +// the required rule, and a discriminator resolves against the instance the whole composition +// describes. +// +// The third clause of the rule — the value must name this schema or one that inherits it — +// constrains the data, not the document, so it belongs to schema validation rather than here. +func (s *SpecValidator) validateDiscriminators() *Result { + res := validatorPools.results.Borrow() + definitions := s.spec.Spec().Definitions + + for _, name := range sortedKeys(definitions) { + schema := definitions[name] + s.walkDiscriminators(newPathSegments(swaggerDefinitions, name), &schema, res) + } + + return res +} + +// walkDiscriminators checks the discriminator of a schema, then of every schema it holds inline. +// +// A schema written as a $ref is left alone: it is checked where it is defined, and following it +// here would report the same fault twice and, for a recursive definition, would not terminate. +// This mirrors [SpecValidator.walkRequired]. +func (s *SpecValidator) walkDiscriminators(at pathSegments, v *spec.Schema, res *Result) { + if v == nil || v.Ref.String() != "" { + return + } + + s.checkDiscriminator(at, v, res) + + for _, name := range sortedKeys(v.Properties) { + held := v.Properties[name] + s.walkDiscriminators(at.structuralChild(jsonProperties).child(name), &held, res) + } + + for _, pattern := range sortedKeys(v.PatternProperties) { + held := v.PatternProperties[pattern] + s.walkDiscriminators(at.structuralChild(jsonPatternProperties).child(pattern), &held, res) + } + + if v.Items != nil { + if v.Items.Schema != nil { + s.walkDiscriminators(at.child(jsonItems), v.Items.Schema, res) + } + for i := range v.Items.Schemas { + s.walkDiscriminators(at.child(jsonItems).item(i), &v.Items.Schemas[i], res) + } + } + + if v.AdditionalProperties != nil && v.AdditionalProperties.Schema != nil { + s.walkDiscriminators(at.child(jsonAdditionalProperties), v.AdditionalProperties.Schema, res) + } + + for _, composition := range []struct { + keyword string + members []spec.Schema + }{ + {jsonAllOf, v.AllOf}, + {jsonAnyOf, v.AnyOf}, + {jsonOneOf, v.OneOf}, + } { + for i := range composition.members { + s.walkDiscriminators(at.child(composition.keyword).item(i), &composition.members[i], res) + } + } + + if v.Not != nil { + s.walkDiscriminators(at.child(jsonNot), v.Not, res) + } +} + +// checkDiscriminator checks the discriminator a single schema declares. A schema without one has +// nothing to answer for. +// +// Both findings are reported against the discriminator itself, which is the entry a reader has to +// go and amend, and both are reported when they apply: a discriminator naming a property that is +// neither defined nor required is two separate slips to fix. +func (s *SpecValidator) checkDiscriminator(at pathSegments, v *spec.Schema, res *Result) { + if v.Discriminator == "" { + return + } + + of := identify(at).name + discriminatorAt := at.child(jsonDiscriminator) + + if _, declared := s.declaresProperty(v, v.Discriminator, maxCompositionHops); !declared { + res.addErrorsAt(discriminatorAt, discriminatorNotDefinedMsg(v.Discriminator, of)) + } + + if !s.requiresProperty(v, v.Discriminator, maxCompositionHops) { + res.addErrorsAt(discriminatorAt, discriminatorNotRequiredMsg(v.Discriminator, of)) + } +} + +// requiresProperty reports whether a schema, or any schema composed into it by allOf, lists the +// named property as required. +// +// It is the required-list counterpart of [SpecValidator.declaresProperty], and follows allOf the +// same way, including the local $ref an allOf member may be written as. +func (s *SpecValidator) requiresProperty(v *spec.Schema, name string, hops int) bool { + if v == nil || hops <= 0 { + return false + } + + if slices.Contains(v.Required, name) { + return true + } + + for i := range v.AllOf { + member := &v.AllOf[i] + if member.Ref.String() != "" { + resolved, err := s.resolveRef(&member.Ref) + if err != nil { + continue + } + member = resolved + } + + if s.requiresProperty(member, name, hops-1) { + return true + } + } + + return false +} diff --git a/vendor/github.com/go-openapi/validate/doc.go b/vendor/github.com/go-openapi/validate/doc.go index 5218ec85c..f2d02d1a3 100644 --- a/vendor/github.com/go-openapi/validate/doc.go +++ b/vendor/github.com/go-openapi/validate/doc.go @@ -12,6 +12,11 @@ // Validates a spec document (from JSON or YAML) against the JSON schema for swagger, // then checks a number of extra rules that can't be expressed in JSON schema. // +// The lists below hold the extra rules only. The meta-schema already settles a great deal on its +// own, and where it does, no rule is repeated here: collectionFormat, say, must be one of csv, ssv, +// tsv or pipes, widened with multi for a query or formData parameter, and a body parameter may not +// carry one at all — all of that comes out of the meta-schema, at every location it applies to. +// // Entry points: // // - Spec() @@ -25,6 +30,9 @@ // [x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method. Validation can be laxed by disabling StrictPathParamUniqueness. // [x] each security reference should contain only unique scopes // [x] each security scope in a security definition should be unique +// [x] a discriminator must name a property the schema defines and lists as required +// [x] each security requirement must name a scheme declared in securityDefinitions +// [x] only an oauth2 security requirement may list scopes: every other scheme type must list none // [x] parameters in path must be unique // [x] each path parameter must correspond to a parameter placeholder and vice versa // [x] each referenceable definition must have references @@ -47,6 +55,8 @@ // [x] unsupported validation of examples on non-JSON media types // [x] examples in response without schema // [x] readOnly properties should not be required +// [x] an oauth2 security requirement names a scope its security scheme does not declare +// [x] collectionFormat is written on a parameter, header or items whose type is not array // // # Validating a schema // @@ -69,8 +79,11 @@ // [ ] errors and warnings are not reported with key/line number in spec // [ ] default values and examples on responses only support application/json producer type // [ ] invalid numeric constraints (such as Minimum, etc..) are not checked except for default and example values -// [ ] rules for collectionFormat are not implemented -// [ ] no validation rule for polymorphism support (discriminator) [not done here] // [ ] valid js ECMA regexp not supported by Go regexp engine are considered invalid // [ ] arbitrary large numbers are not supported: max is math.MaxFloat64 +// +// Left out by design, rather than pending: a discriminator value is not checked against the schema +// names it may take. That clause of the swagger rule constrains an instance rather than the +// document, so there is nothing in a specification for [SpecValidator] to read, and checking it +// would mean resolving polymorphic payloads, which this package does not do. package validate diff --git a/vendor/github.com/go-openapi/validate/helpers.go b/vendor/github.com/go-openapi/validate/helpers.go index 62deb97d0..ea7143607 100644 --- a/vendor/github.com/go-openapi/validate/helpers.go +++ b/vendor/github.com/go-openapi/validate/helpers.go @@ -42,6 +42,7 @@ const ( jsonRequired = "required" jsonRef = "$ref" jsonDefault = "default" + jsonDiscriminator = "discriminator" jsonAllOf = "allOf" jsonAnyOf = "anyOf" @@ -50,12 +51,17 @@ const ( jsonAdditionalItems = "additionalItems" jsonAdditionalProperties = "additionalProperties" - swaggerPaths = "paths" - swaggerDefinitions = "definitions" - swaggerResponses = "responses" - swaggerParameters = "parameters" - swaggerHeaders = "headers" - swaggerOperationID = "operationId" + swaggerPaths = "paths" + swaggerDefinitions = "definitions" + swaggerResponses = "responses" + swaggerParameters = "parameters" + swaggerHeaders = "headers" + swaggerOperationID = "operationId" + swaggerSecurity = "security" + swaggerCollectionFormat = "collectionFormat" + + // securitySchemeOAuth2 is the only security scheme type whose requirements carry scopes. + securitySchemeOAuth2 = "oauth2" jsonMimeApplicationJSON = "application/json" ) diff --git a/vendor/github.com/go-openapi/validate/object_validator.go b/vendor/github.com/go-openapi/validate/object_validator.go index 4f1dd15a2..cac243ece 100644 --- a/vendor/github.com/go-openapi/validate/object_validator.go +++ b/vendor/github.com/go-openapi/validate/object_validator.go @@ -375,7 +375,7 @@ func (o *objectValidator) validatePropertiesSchema(val map[string]any, res *Resu } // located on the object that lacks the property: the property itself - // has no node to point at, and the object is what has to be amended + // has no node to point at, and the object has to be amended res.addErrorsAt(o.Path, errors.Required(o.Path.child(k).dotted(), o.In, v)) } } diff --git a/vendor/github.com/go-openapi/validate/path.go b/vendor/github.com/go-openapi/validate/path.go index 940fc4be5..4b2da2535 100644 --- a/vendor/github.com/go-openapi/validate/path.go +++ b/vendor/github.com/go-openapi/validate/path.go @@ -16,7 +16,7 @@ import ( // // Validators build a location by appending tokens as they descend into // properties and array items, then render it only when they report an error. -// Keeping the tokens apart until then is what makes it possible to produce a +// Keeping the tokens apart until then makes it possible to produce a // valid [RFC 6901] JSON pointer: a token is escaped when it is rendered, and // the separator can never be confused with a token that contains one. // diff --git a/vendor/github.com/go-openapi/validate/pools.go b/vendor/github.com/go-openapi/validate/pools.go index 0bc95d1aa..24fde6e9c 100644 --- a/vendor/github.com/go-openapi/validate/pools.go +++ b/vendor/github.com/go-openapi/validate/pools.go @@ -12,7 +12,7 @@ import ( // // Validation allocates a validator per schema node and a result per check, so // the same handful of types are built and thrown away constantly. Recycling -// them is what keeps validating a large specification affordable. +// them keeps validating a large specification affordable. // // Build with the "poolsdebug" tag to have every borrow and redeem tracked: // misuse then panics where it happens rather than corrupting a pool, and diff --git a/vendor/github.com/go-openapi/validate/schema.go b/vendor/github.com/go-openapi/validate/schema.go index e7af892c7..9b49007b5 100644 --- a/vendor/github.com/go-openapi/validate/schema.go +++ b/vendor/github.com/go-openapi/validate/schema.go @@ -61,6 +61,22 @@ func NewSchemaValidator(schema *spec.Schema, rootSchema any, root string, format o(opts) } + // the caller still owns this schema, and validation expands what it walks: work on a copy, + // once, here - every validator below this one is then free to expand in place + if !opts.ownSchemata && schema != nil { + cloned, err := deepCloneSchema(*schema) + if err != nil { + panic(invalidSchemaProvidedMsg(err).Error()) + } + + if rootSchema == schema { + rootSchema = &cloned + } + + schema = &cloned + opts.ownSchemata = true + } + return newSchemaValidator(schema, rootSchema, rootPathFromString(root), formats, opts) } diff --git a/vendor/github.com/go-openapi/validate/schema_option.go b/vendor/github.com/go-openapi/validate/schema_option.go index 3ca489c0f..09a03eba1 100644 --- a/vendor/github.com/go-openapi/validate/schema_option.go +++ b/vendor/github.com/go-openapi/validate/schema_option.go @@ -18,6 +18,15 @@ type SchemaValidatorOptions struct { recycleResult bool skipSchemataResult bool pathLoaderWithOptions func(string, ...loading.Option) (json.RawMessage, error) + + // ownSchemata tells the validators that the schemata they walk are theirs to rewrite. + // + // Validation expands every schema carrying a $ref or an id, and expansion rewrites what it is + // given. The copy that makes this safe is taken once, at the entry point - the whole document + // in [SpecValidator.Validate], the single schema in [NewSchemaValidator] - because a copy per + // schema multiplies with the recursion, and because parameters, path items and responses + // expand too, not only schemata. + ownSchemata bool } // Option sets optional rules for schema validation. diff --git a/vendor/github.com/go-openapi/validate/security_requirements.go b/vendor/github.com/go-openapi/validate/security_requirements.go new file mode 100644 index 000000000..b6c10f3b2 --- /dev/null +++ b/vendor/github.com/go-openapi/validate/security_requirements.go @@ -0,0 +1,99 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package validate + +import ( + "strings" + + "github.com/go-openapi/spec" +) + +// validateSecurityRequirements checks the security requirements declared by the document and by +// each of its operations against the security definitions. +// +// A requirement names a security scheme and lists the scopes an operation needs from it: +// +// security: +// - petstore_auth: [ "write:pets" ] +// - api_key: [] +// +// Three rules apply: +// +// - the name must be declared in securityDefinitions (error) +// - only an oauth2 requirement carries scopes; every other scheme type must list none (error) +// - an oauth2 requirement should only name scopes its scheme declares (warning) +// +// The JSON meta-schema types a requirement as an object of string arrays and never reads +// securityDefinitions, so it can express none of the three. +// +// An empty requirement object ({}) names no scheme and passes. So does an empty security array, +// which an operation uses to drop the requirements the document sets for every operation. +func (s *SpecValidator) validateSecurityRequirements() *Result { + res := validatorPools.results.Borrow() + definitions := s.spec.Spec().SecurityDefinitions + + res.Merge(checkSecurityRequirements( + newPathSegments(swaggerSecurity), + s.spec.Spec().Security, + definitions, + )) + + operations := s.expandedAnalyzer().Operations() + for _, method := range sortedKeys(operations) { + byPath := operations[method] + for _, path := range sortedKeys(byPath) { + op := byPath[path] + if op == nil { + continue + } + + res.Merge(checkSecurityRequirements( + operationPath(path, method).child(swaggerSecurity), + op.Security, + definitions, + )) + } + } + + return res +} + +// checkSecurityRequirements checks the list of security requirements held at the given location. +// +// Requirements are checked in the order the document lists them, and the schemes one requirement +// names in sorted order: a requirement is a map, so the document's own order is lost (see +// [sortedKeys]). +func checkSecurityRequirements(at pathSegments, requirements []map[string][]string, definitions spec.SecurityDefinitions) *Result { + res := validatorPools.results.Borrow() + + for i, requirement := range requirements { + for _, name := range sortedKeys(requirement) { + scopes := requirement[name] + schemeAt := at.item(i).child(name) + + scheme, isDeclared := definitions[name] + if !isDeclared || scheme == nil { + res.addErrorsAt(schemeAt, securitySchemeNotDeclaredMsg(name)) + + continue + } + + if scheme.Type != securitySchemeOAuth2 { + if len(scopes) > 0 { + res.addErrorsAt(schemeAt, securityScopesNotEmptyMsg(name, strings.Join(scopes, ", "), scheme.Type)) + } + + continue + } + + for _, scope := range scopes { + if _, isKnown := scheme.Scopes[scope]; !isKnown { + res.addWarningsAt(schemeAt, securityScopeNotDeclaredMsg(name, scope)) + } + } + } + } + + return res +} diff --git a/vendor/github.com/go-openapi/validate/spec.go b/vendor/github.com/go-openapi/validate/spec.go index e5d16b679..133752345 100644 --- a/vendor/github.com/go-openapi/validate/spec.go +++ b/vendor/github.com/go-openapi/validate/spec.go @@ -4,13 +4,10 @@ package validate import ( - "bytes" - "encoding/gob" "encoding/json" "fmt" "slices" "sort" - "strconv" "strings" "github.com/go-openapi/analysis" @@ -31,7 +28,6 @@ import ( // // - Proposal for enhancement: $ref should not have siblings // - Proposal for enhancement: make sure documentation reflects all checks and warnings -// - Proposal for enhancement: check on discriminators // - Proposal for enhancement: explicit message on unsupported keywords (better than "forbidden property"...) // - Proposal for enhancement: full list of unresolved refs // - Proposal for enhancement: validate numeric constraints (issue#581): this should be handled like defaults and examples @@ -101,6 +97,17 @@ func (s *SpecValidator) Validate(data any) (*Result, *Result) { errs.AddErrors(invalidDocumentMsg()) return errs, warnings // no point in continuing } + + // Validation expands what it walks - schemata, but also parameters, path items and responses - + // and expansion rewrites what it is given. Take one copy of the whole document here and work + // on that, so the caller gets back the document it handed over. Raw() still reads the bytes as + // they were authored, so the checks below that go through them are unaffected. + // + // Cloning here rather than per schema is what keeps the cost flat: a copy taken inside + // newSchemaValidator is paid again at every level of a recursive document. + raw := sd.Raw() + sd = sd.Pristine() + s.schemaOptions.ownSchemata = true s.spec = sd s.analyzer = analysis.New(sd.Spec()) // where each $ref sits, as authored: refs are reported against the @@ -115,7 +122,7 @@ func (s *SpecValidator) Validate(data any) (*Result, *Result) { // Raw spec unmarshalling errors var obj any - if err := json.Unmarshal(sd.Raw(), &obj); err != nil { + if err := json.Unmarshal(raw, &obj); err != nil { // NOTE: under normal conditions, the *load.Document has been already unmarshalled // So this one is just a paranoid check on the behavior of the spec package panic(InvalidDocumentError) @@ -153,6 +160,9 @@ func (s *SpecValidator) Validate(data any) (*Result, *Result) { errs.Merge(s.validateDuplicatePropertyNames()) // error - errs.Merge(s.validateParameters()) // error - errs.Merge(s.validateItems()) // error - + errs.Merge(s.validateSecurityRequirements()) // error and warning + errs.Merge(s.validateDiscriminators()) // error - + errs.Merge(s.validateCollectionFormats()) // warning only // Properties in required definition MUST validate their schema // Properties SHOULD NOT be declared as both required and readOnly (warning) @@ -190,7 +200,7 @@ func (s *SpecValidator) SetContinueOnErrors(c bool) { func (s *SpecValidator) validateNonEmptyPathParamNames() *Result { res := validatorPools.results.Borrow() if s.spec.Spec().Paths == nil { - // There is no Paths object: the document itself is what lacks it, so + // There is no Paths object: the document itself lacks it, so // there is no node below it to point at res.addErrorsAt(rootPath(), noValidPathMsg()) @@ -458,26 +468,7 @@ func (s *SpecValidator) validateItems() *Result { } } - type codedResponse struct { - code string - resp spec.Response - } - var responses []codedResponse - if op.Responses != nil { - if op.Responses.Default != nil { - responses = append(responses, codedResponse{code: jsonDefault, resp: *op.Responses.Default}) - } - if op.Responses.StatusCodeResponses != nil { - for _, code := range sortedKeys(op.Responses.StatusCodeResponses) { - responses = append(responses, codedResponse{ - code: strconv.Itoa(code), - resp: op.Responses.StatusCodeResponses[code], - }) - } - } - } - - for _, resp := range responses { + for _, resp := range responsesOf(op) { at := responsePath(path, method, resp.code) // Response headers with array for _, hn := range sortedKeys(resp.resp.Headers) { @@ -969,14 +960,15 @@ func (s *SpecValidator) expandedAnalyzer() *analysis.Spec { return s.analyzer } +// deepCloneSchema returns a copy of src that shares nothing with it. +// +// The copy goes through JSON, which is the form [spec.Schema] is defined by. gob drops any field +// holding its zero value and flattens a pointer to what it points at, so a *float64 pointing at +// 0 - "minimum": 0, which the JSON Schema meta-schema spells for every positiveInteger - came +// back nil and the bound was lost. JSON is also the faster of the two on this model. func deepCloneSchema(src spec.Schema) (spec.Schema, error) { - var b bytes.Buffer - if err := gob.NewEncoder(&b).Encode(src); err != nil { - return spec.Schema{}, err - } - var dst spec.Schema - if err := gob.NewDecoder(&b).Decode(&dst); err != nil { + if err := jsonutils.FromDynamicJSON(src, &dst); err != nil { return spec.Schema{}, err } diff --git a/vendor/github.com/go-openapi/validate/spec_messages.go b/vendor/github.com/go-openapi/validate/spec_messages.go index 0a0739a75..541af4d91 100644 --- a/vendor/github.com/go-openapi/validate/spec_messages.go +++ b/vendor/github.com/go-openapi/validate/spec_messages.go @@ -44,6 +44,15 @@ const ( // DefaultValueInDoesNotValidateError ... DefaultValueInDoesNotValidateError = "in operation %q, default value in %s does not validate its schema" + // DiscriminatorNotDefinedError indicates a schema whose discriminator names a property the + // schema does not declare. A discriminator tells subtypes apart by the value of that property, + // so an instance has nowhere to carry the value when the property is not declared. + DiscriminatorNotDefinedError = "discriminator %q of %q is not defined as a property of that schema" + + // DiscriminatorNotRequiredError indicates a schema whose discriminator property is declared but + // left optional. An instance that omits it cannot be resolved to a subtype. + DiscriminatorNotRequiredError = "discriminator %q of %q is not in the required property list" + // DuplicateParamNameError ... DuplicateParamNameError = "duplicate parameter name %q for %q in operation %q" @@ -136,6 +145,14 @@ const ( // in the definition itself. RequiredButNotDefinedInSchemaError = "%q is present in required but not defined as property in schema %q" + // SecuritySchemeNotDeclaredError indicates a security requirement naming a scheme that + // securityDefinitions does not declare. + SecuritySchemeNotDeclaredError = "security requirement %q is not declared in securityDefinitions" + + // SecurityScopesNotEmptyError indicates a security requirement listing scopes on a scheme that is + // not oauth2. Only an oauth2 requirement carries scopes; every other type must list none. + SecurityScopesNotEmptyError = "security requirement %q lists scopes (%s), but the security scheme it names is of type %q: only oauth2 requirements carry scopes" + // SomeParametersBrokenError indicates that some parameters could not be resolved, which might result in partial checks to be carried on. SomeParametersBrokenError = "some parameters definitions are broken in %q.%s. Cannot carry on full checks on parameters for operation %s" @@ -171,6 +188,11 @@ const ( // RequiredHasDefaultWarning indicates that a required parameter property should not have a default. RequiredHasDefaultWarning = "%s in %s has a default value and is required as parameter" + // SecurityScopeNotDeclaredWarning flags an oauth2 security requirement asking for a scope that the + // scheme does not list in its scopes. Swagger 2.0 does not spell out that the two must agree, so + // this is reported as a warning: a specification that names an undeclared scope stays valid. + SecurityScopeNotDeclaredWarning = "security requirement %q requires scope %q, which the security scheme does not declare" + // UnusedDefinitionWarning ... UnusedDefinitionWarning = "definition %q is not used anywhere" @@ -180,6 +202,12 @@ const ( // UnusedResponseWarning ... UnusedResponseWarning = "response %q is not used anywhere" + // CollectionFormatIgnoredWarning flags a collectionFormat on a parameter, header or items whose + // type is not array. collectionFormat says how to join the members of an array into one value, so + // it does nothing anywhere else. It is a warning, not an error: Swagger 2.0 defines the member as + // applying when the type is array, and does not forbid writing it elsewhere. + CollectionFormatIgnoredWarning = "collectionFormat %q is ignored in %s: it joins the members of an array, and the type is %q" + // DubiousAbsoluteRefWarning flags a $ref pointing to an absolute local file location that escapes the // spec's base path. Absolute local references are legitimate when they stay beneath the base path // (flattening/expansion introduces such anchors for cyclical $refs), but an absolute reference that @@ -416,6 +444,31 @@ func invalidObjectMsg(path, in string) errors.Error { // func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error { // return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method) // } + +func collectionFormatIgnoredMsg(collectionFormat, in, typ string) errors.Error { + return errors.New(errors.CompositeErrorCode, CollectionFormatIgnoredWarning, collectionFormat, in, typ) +} + +func discriminatorNotDefinedMsg(discriminator, in string) errors.Error { + return errors.New(errors.CompositeErrorCode, DiscriminatorNotDefinedError, discriminator, in) +} + +func discriminatorNotRequiredMsg(discriminator, in string) errors.Error { + return errors.New(errors.CompositeErrorCode, DiscriminatorNotRequiredError, discriminator, in) +} + +func securitySchemeNotDeclaredMsg(name string) errors.Error { + return errors.New(errors.CompositeErrorCode, SecuritySchemeNotDeclaredError, name) +} + +func securityScopesNotEmptyMsg(name, scopes, schemeType string) errors.Error { + return errors.New(errors.CompositeErrorCode, SecurityScopesNotEmptyError, name, scopes, schemeType) +} + +func securityScopeNotDeclaredMsg(name, scope string) errors.Error { + return errors.New(errors.CompositeErrorCode, SecurityScopeNotDeclaredWarning, name, scope) +} + func someParametersBrokenMsg(path, method, operationID string) errors.Error { return errors.New(errors.CompositeErrorCode, SomeParametersBrokenError, path, method, operationID) } diff --git a/vendor/github.com/go-openapi/validate/update-fixtures.sh b/vendor/github.com/go-openapi/validate/update-fixtures.sh deleted file mode 100644 index 8ee55ca3b..000000000 --- a/vendor/github.com/go-openapi/validate/update-fixtures.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers -# SPDX-License-Identifier: Apache-2.0 - -set -eu -o pipefail -dir=$(git rev-parse --show-toplevel) -scratch=$(mktemp -d -t tmp.XXXXXXXXXX) - -function finish { - rm -rf "$scratch" -} -trap finish EXIT SIGHUP SIGINT SIGTERM - -cd "$scratch" -git clone https://github.com/json-schema-org/JSON-Schema-Test-Suite Suite -cp -r Suite/tests/draft4/* "$dir/fixtures/jsonschema_suite" -cp -a Suite/remotes "$dir/fixtures/jsonschema_suite" diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md index 3e6675633..683cec908 100644 --- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md +++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## 1.10.2 + +Changed: + + * Update `github.com/stretchr/testify` to v1.12.1, removing the legacy + `gopkg.in/yaml.v3` dependency. + ## 1.10.1 Fixes: diff --git a/vendor/go.opentelemetry.io/contrib/bridges/otelslog/version.go b/vendor/go.opentelemetry.io/contrib/bridges/otelslog/version.go index 627f0b766..53b2713bc 100644 --- a/vendor/go.opentelemetry.io/contrib/bridges/otelslog/version.go +++ b/vendor/go.opentelemetry.io/contrib/bridges/otelslog/version.go @@ -4,4 +4,4 @@ package otelslog // Version is the current release version of the otelslog bridge. -const Version = "0.20.0" +const Version = "0.20.1" diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml index 8a7f1ec5d..a0ba70805 100644 --- a/vendor/go.opentelemetry.io/otel/.golangci.yml +++ b/vendor/go.opentelemetry.io/otel/.golangci.yml @@ -143,8 +143,7 @@ linters: - name: constant-logical-expr - name: context-as-argument arguments: - - allow-types-before: '*testing.T' - disabled: true + - allow-types-before: '*testing.T,*testing.B' - name: context-keys-type - name: deep-exit - name: defer diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md index 2db588ea2..4d473a1e8 100644 --- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md +++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md @@ -11,6 +11,34 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm +## [1.46.0/0.68.0/0.22.0/0.0.19] - 2026-08-25 + +This release is the last to support [Go 1.25]. +The next release will require at least [Go 1.26]. + +### Added + +- Support testing of [Go 1.27]. (#8811) +- Support `http/json` protocol in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#8273, #8775, #8831) +- Add `Hasher` struct and methods in `go.opentelemetry.io/otel/attribute` to compute authoritative `Distinct` hashes incrementally for attribute filtering and deduplication. (#8598) + +### Changed + +- Lazily evaluate filtered and dropped attributes on measurement hot paths in `go.opentelemetry.io/otel/sdk/metric` to avoid unnecessary attribute set allocations. (#8598) +- Add `ErrExporterShutdown` to `go.opentelemetry.io/otel/sdk/log` and return it from the `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`, `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`, and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` exporters when `Export` is called after `Shutdown`. (#8773) +- Clarify in `go.opentelemetry.io/otel/log` that calling `Logger.Enabled` is optional and that cached results can become stale. (#8764) + +### Fixed + +- Export dropped attribute counts in OTLP log records from `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8829) +- Name span events created from OpenTracing logs after the `event` log field, falling back to `log`, instead of always using an empty name in `go.opentelemetry.io/otel/bridge/opentracing`. (#8648) +- Count exception attributes omitted due to the attribute count limit as dropped in `go.opentelemetry.io/otel/sdk/log`. (#8796) +- Prevent log record and instrumentation scope attributes with empty keys from reaching processors and exporters in `go.opentelemetry.io/otel/sdk/log`. (#8797) +- Fix a data race when span attributes are read concurrently in `go.opentelemetry.io/otel/sdk/trace`. (#8706) +- Prevent a panic in `(*Set).Filter` when called on a nil receiver in `go.opentelemetry.io/otel/attribute`. (#8792) +- The simple span and log processors record `otel.sdk.processor.{span,log}.processed` when the record is submitted to the exporter instead of after the export completes, and no longer set `error.type` from the export outcome, in `go.opentelemetry.io/otel/sdk/trace` and `go.opentelemetry.io/otel/sdk/log`. (#8705) +- Prevent `Resource.MarshalLog` from panicking on nil resources in `go.opentelemetry.io/otel/sdk/resource`. (#8758) + ## [1.45.0/0.67.0/0.21.0/0.0.18] - 2026-08-03 ### Added @@ -3782,7 +3810,8 @@ It contains api and sdk for trace and meter. - CircleCI build CI manifest files. - CODEOWNERS file to track owners of this project. -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.45.0...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.46.0...HEAD +[1.46.0/0.68.0/0.22.0/0.0.19]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.46.0 [1.45.0/0.67.0/0.21.0/0.0.18]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.45.0 [1.44.0/0.66.0/0.20.0/0.0.17]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.44.0 [1.43.0/0.65.0/0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.43.0 @@ -3887,6 +3916,7 @@ It contains api and sdk for trace and meter. +[Go 1.27]: https://go.dev/doc/go1.27 [Go 1.26]: https://go.dev/doc/go1.26 [Go 1.25]: https://go.dev/doc/go1.25 [Go 1.24]: https://go.dev/doc/go1.24 diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile index d4711257d..c674ef8a1 100644 --- a/vendor/go.opentelemetry.io/otel/Makefile +++ b/vendor/go.opentelemetry.io/otel/Makefile @@ -69,8 +69,13 @@ $(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease GOVULNCHECK = $(TOOLS)/govulncheck $(TOOLS)/govulncheck: PACKAGE=golang.org/x/vuln/cmd/govulncheck +AFFECTEDMODS = $(TOOLS)/affectedmods +AFFECTEDMODS_FILES := $(sort $(shell find $(TOOLS_MOD_DIR)/affectedmods -type f)) +$(TOOLS)/affectedmods: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/affectedmods +$(TOOLS)/affectedmods: $(AFFECTEDMODS_FILES) + .PHONY: tools -tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(VERIFYREADMES) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) +tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(VERIFYREADMES) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) $(AFFECTEDMODS) # Virtualized python tools via docker @@ -125,9 +130,11 @@ go-work: $(CROSSLINK) # Build -.PHONY: build +.PHONY: build cross-build build: $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%) +# Cross-platform builds cannot execute the binaries produced by build-tests (go test), so use a compile-only target. +cross-build: $(OTEL_GO_MOD_DIRS:%=build/%) build/%: DIR=$* build/%: @echo "$(GO) build $(DIR)/..." \ @@ -163,6 +170,9 @@ test/%: | grep -v third_party \ | xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS) +.PHONY: test-tools +test-tools: test/$(TOOLS_MOD_DIR) + COVERAGE_MODE = atomic COVERAGE_PROFILE = coverage.out .PHONY: test-coverage @@ -187,15 +197,23 @@ benchmark/%: # sdk/metric is split into two shards to work around CodSpeed limitations. # See https://github.com/CodSpeedHQ/codspeed-go/issues/56 -BENCHMARK_SHARDS := $(filter-out ./sdk/metric,$(OTEL_GO_MOD_DIRS)) ./sdk/metric/root ./sdk/metric/internal -benchmark/./sdk/metric/root: +BENCHMARK_SHARDS := $(filter-out ./sdk/metric,$(OTEL_GO_MOD_DIRS)) ./sdk/metric/. ./sdk/metric/internal +benchmark/./sdk/metric/.: cd ./sdk/metric && $(GO) test -run='^$$' -bench=. $(ARGS) . ./exemplar/... -benchmark/./sdk/metric/internal: - cd ./sdk/metric && $(GO) test -run='^$$' -bench=. $(ARGS) ./internal/... print-sharded-benchmarks: @echo $(BENCHMARK_SHARDS) | jq -cR 'split(" ")' +# Print the JSON list of benchmark shards whose code changed since +# BASE_REF (default: main). Filters print-sharded-benchmarks +# down to shards whose underlying module contains a changed *.go file. +# Non-Go changes (docs, workflows, Makefile, go.mod/go.sum, tooling) emit []. +# Override the diff base via BASE_REF, or pass ARGS=-all to emit the full list. +BASE_REF ?= main +.PHONY: print-affected-benchmarks +print-affected-benchmarks: + @$(MAKE) -s print-sharded-benchmarks | $(GO) -C $(TOOLS_MOD_DIR) run ./affectedmods $(if $(strip $(BASE_REF)),-base=$(BASE_REF),) $(ARGS) + .PHONY: golangci-lint golangci-lint-fix golangci-lint-fix: ARGS=--fix golangci-lint-fix: golangci-lint diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md index ce97e9a25..9291d1470 100644 --- a/vendor/go.opentelemetry.io/otel/README.md +++ b/vendor/go.opentelemetry.io/otel/README.md @@ -53,18 +53,25 @@ Currently, this project supports the following environments. | OS | Go Version | Architecture | |----------|------------|--------------| +| Ubuntu | 1.27 | amd64 | | Ubuntu | 1.26 | amd64 | | Ubuntu | 1.25 | amd64 | +| Ubuntu | 1.27 | 386 | | Ubuntu | 1.26 | 386 | | Ubuntu | 1.25 | 386 | +| Ubuntu | 1.27 | arm64 | | Ubuntu | 1.26 | arm64 | | Ubuntu | 1.25 | arm64 | +| macOS | 1.27 | amd64 | | macOS | 1.26 | amd64 | | macOS | 1.25 | amd64 | +| macOS | 1.27 | arm64 | | macOS | 1.26 | arm64 | | macOS | 1.25 | arm64 | +| Windows | 1.27 | amd64 | | Windows | 1.26 | amd64 | | Windows | 1.25 | amd64 | +| Windows | 1.27 | 386 | | Windows | 1.26 | 386 | | Windows | 1.25 | 386 | diff --git a/vendor/go.opentelemetry.io/otel/VERSIONING.md b/vendor/go.opentelemetry.io/otel/VERSIONING.md index b27c9e84f..56eaa7d22 100644 --- a/vendor/go.opentelemetry.io/otel/VERSIONING.md +++ b/vendor/go.opentelemetry.io/otel/VERSIONING.md @@ -12,6 +12,12 @@ is designed so the following goals can be achieved. * [Semantic import versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning) will be used. + * Stable module compatibility is understood in terms of the [Go 1 + compatibility guidelines](https://go.dev/doc/go1compat). Code that + compiled against an older version of a package should continue to compile + against newer versions of that package, subject to the exceptions in the + Go 1 compatibility guidelines and any additional exceptions documented + below. * Versions will comply with [semver 2.0](https://semver.org/spec/v2.0.0.html) with the following exceptions. * New methods may be added to exported API interfaces. All exported diff --git a/vendor/go.opentelemetry.io/otel/attribute/hash.go b/vendor/go.opentelemetry.io/otel/attribute/hash.go index f651eb13d..54c26e67a 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/hash.go +++ b/vendor/go.opentelemetry.io/otel/attribute/hash.go @@ -33,19 +33,71 @@ const ( emptyID uint64 = 7305809155345288421 // "__empty_" (little endian) ) +// Hasher computes a Distinct value from KeyValue attributes supplied with +// Write. +// +// A Hasher must be obtained from [NewHasher]. The zero value is not usable and +// its methods will panic. +type Hasher struct { + h xxhash.Hash +} + +// NewHasher returns a new Hasher. +func NewHasher() *Hasher { + return &Hasher{h: xxhash.New()} +} + +// Reset resets h to its initial state so it can be reused. +func (h *Hasher) Reset() { + h.h.Reset() +} + +// Write adds kv to the hash. +// +// Write requires attributes to be supplied in ascending key order with no +// duplicate keys. To produce the same Distinct as Set.Equivalent, write +// attributes in ascending key order, with no more than one value for each key. +// If the source contains duplicate keys, retain the last value for each key +// before calling Write. +func (h *Hasher) Write(kv KeyValue) { + // hashKV mutates the digest h.h refers to in place and returns the same + // Hash value it was passed. Discarding the result keeps the digest pointer + // from flowing back into h, which would force the digest to be heap + // allocated for every Hasher. Keeping Write this small also keeps it within + // the inlining budget, which matters because hashKVs calls it per attribute. + _ = hashKV(h.h, kv) +} + +// Distinct returns the identifier for the attributes written to h. When Write +// is called as described above, it returns the same value as [Set.Equivalent]. +func (h *Hasher) Distinct() Distinct { + // No count of written attributes is needed to detect the empty case. The + // sum of a digest with nothing written to it is emptyHash, which is + // non-zero (0xef46db3751d8e999), so it passes through remapZeroHash + // unchanged and matches emptySet.Equivalent. + return Distinct{hash: remapZeroHash(h.h.Sum64())} +} + +// remapZeroHash remaps a 0 sum to a non-zero value, because hash == 0 is a +// reserved sentinel (treated as empty/invalid). +func remapZeroHash(sum uint64) uint64 { + if sum == 0 { + return 1 + } + return sum +} + // hashKVs returns a new xxHash64 hash of kvs. +// +// This routes through [Hasher] so that Set hashing and Hasher cannot disagree: +// there is exactly one implementation of how attributes are mixed and how the +// final sum is framed. func hashKVs(kvs []KeyValue) uint64 { - h := xxhash.New() + h := NewHasher() for _, kv := range kvs { - h = hashKV(h, kv) + h.Write(kv) } - sum := h.Sum64() - // Remap 0 to a non-zero value for non-empty input because hash == 0 is a reserved sentinel (treated as empty/invalid). - const remappedZeroHash uint64 = 1 - if sum == 0 && len(kvs) > 0 { - return remappedZeroHash - } - return sum + return h.Distinct().hash } // hashKV returns the xxHash64 hash of kv with h as the base. diff --git a/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go b/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go index c851179cc..4fcdd2dbe 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go +++ b/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go @@ -62,3 +62,8 @@ func (h Hash) String(val string) Hash { func (h Hash) Sum64() uint64 { return h.d.Sum64() } + +// Reset resets the hash to its initial state. +func (h Hash) Reset() { + h.d.Reset() +} diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go index 87d6f9620..56a70a9f6 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/set.go +++ b/vendor/go.opentelemetry.io/otel/attribute/set.go @@ -313,6 +313,9 @@ func filteredToFront(slice []KeyValue, keep Filter) int { // Filter returns a filtered copy of this Set. See the documentation for // NewSetWithSortableFiltered for more details. func (l *Set) Filter(re Filter) (Set, []KeyValue) { + if l == nil { + return emptySet, nil + } if re == nil { return *l, nil } diff --git a/vendor/go.opentelemetry.io/otel/log/doc.go b/vendor/go.opentelemetry.io/otel/log/doc.go index c6f956269..211de35f5 100644 --- a/vendor/go.opentelemetry.io/otel/log/doc.go +++ b/vendor/go.opentelemetry.io/otel/log/doc.go @@ -4,8 +4,8 @@ /* Package log provides the OpenTelemetry Logs API. -This API is separate from its implementation so the instrumentation built from -it is reusable. See [go.opentelemetry.io/otel/sdk/log] for the official +This API is separate from its implementation, so the instrumentation built +from it is reusable. See [go.opentelemetry.io/otel/sdk/log] for the official OpenTelemetry implementation of this API. The log package provides the OpenTelemetry Logs API, which serves as a standard @@ -15,16 +15,16 @@ that can be easily integrated with observability tools. It ensures that log data in a way that is consistent with OpenTelemetry's data model. This package can be used to create bridges between existing logging libraries and OpenTelemetry. -Log bridges allow integrating the existing logging setups with OpenTelemetry. +Log bridges allow existing logging setups to be integrated with OpenTelemetry. Log bridges can be found in the [registry]. # API Implementations -This package does not conform to the standard Go versioning policy, all of its +This package does not conform to the standard Go versioning policy; all of its interfaces may have methods added to them without a package major version bump. This non-standard API evolution could surprise an uninformed implementation author. They could unknowingly build their implementation in a way that would -result in a runtime panic for their users that update to the new API. +result in a runtime panic for their users who update to the new API. The API is designed to help inform an instrumentation author about this non-standard API evolution. It requires them to choose a default behavior for @@ -38,7 +38,7 @@ make: All interfaces in this API embed a corresponding interface from [go.opentelemetry.io/otel/log/embedded]. If an author wants the default behavior of their implementations to be a compilation failure, signaling to -their users they need to update to the latest version of that implementation, +their users that they need to update to the latest version of that implementation, they need to embed the corresponding interface from [go.opentelemetry.io/otel/log/embedded] in their implementation. For example, @@ -49,7 +49,7 @@ they need to embed the corresponding interface from // ... } -If an author wants the default behavior of their implementations to a panic, +If an author wants the default behavior of their implementations to panic, they need to embed the API interface directly. import "go.opentelemetry.io/otel/log" @@ -60,7 +60,7 @@ they need to embed the API interface directly. } This is not a recommended behavior as it could lead to publishing packages that -contain runtime panics when users update other package that use newer versions +contain runtime panics when users update other packages that use newer versions of [go.opentelemetry.io/otel/log]. Finally, an author can embed another implementation in theirs. The embedded diff --git a/vendor/go.opentelemetry.io/otel/log/embedded/embedded.go b/vendor/go.opentelemetry.io/otel/log/embedded/embedded.go index 70bab2312..3b97fcddc 100644 --- a/vendor/go.opentelemetry.io/otel/log/embedded/embedded.go +++ b/vendor/go.opentelemetry.io/otel/log/embedded/embedded.go @@ -16,21 +16,21 @@ package embedded // LoggerProvider is embedded in the [Logs API LoggerProvider]. // // Embed this interface in your implementation of the [Logs API -// LoggerProvider] if you want users to experience a compilation error, -// signaling they need to update to your latest implementation, when the [Logs -// Bridge API LoggerProvider] interface is extended (which is something that -// can happen without a major version bump of the API package). +// LoggerProvider] if you want users to experience a compilation error when the +// [Logs Bridge API LoggerProvider] interface is extended (which is something +// that can happen without a major version bump of the API package). This error +// signals that they need to update to your latest implementation. // // [Logs API LoggerProvider]: https://pkg.go.dev/go.opentelemetry.io/otel/log#LoggerProvider type LoggerProvider interface{ loggerProvider() } -// Logger is embedded in [Logs API Logger]. +// Logger is embedded in the [Logs API Logger]. // // Embed this interface in your implementation of the [Logs API Logger] -// if you want users to experience a compilation error, signaling they need to -// update to your latest implementation, when the [Logs API Logger] -// interface is extended (which is something that can happen without a major -// version bump of the API package). +// if you want users to experience a compilation error when the [Logs API +// Logger] interface is extended (which is something that can happen without a +// major version bump of the API package). This error signals that they need to +// update to your latest implementation. // // [Logs API Logger]: https://pkg.go.dev/go.opentelemetry.io/otel/log#Logger type Logger interface{ logger() } diff --git a/vendor/go.opentelemetry.io/otel/log/global/log.go b/vendor/go.opentelemetry.io/otel/log/global/log.go index ac9957c3f..c827de906 100644 --- a/vendor/go.opentelemetry.io/otel/log/global/log.go +++ b/vendor/go.opentelemetry.io/otel/log/global/log.go @@ -22,7 +22,7 @@ import ( // If this is called before a global LoggerProvider is configured, the returned // Logger will be a No-Op implementation of a Logger. When a global // LoggerProvider is registered for the first time, the returned Logger is -// updated in-place to report to this new LoggerProvider. There is no need to +// updated in place to report to this new LoggerProvider. There is no need to // call this function again for an updated instance. // // This is a convenience function. It is equivalent to: @@ -35,9 +35,9 @@ func Logger(name string, options ...log.LoggerOption) log.Logger { // GetLoggerProvider returns the globally configured [log.LoggerProvider]. // // If a global LoggerProvider has not been configured with [SetLoggerProvider], -// the returned Logger will be a No-Op implementation of a LoggerProvider. When +// the returned LoggerProvider will be a No-Op implementation. When // a global LoggerProvider is registered for the first time, the returned -// LoggerProvider and all of its created Loggers are updated in-place. There is +// LoggerProvider and all Loggers it has created are updated in place. There is // no need to call this function again for an updated instance. func GetLoggerProvider() log.LoggerProvider { return global.GetLoggerProvider() diff --git a/vendor/go.opentelemetry.io/otel/log/internal/global/log.go b/vendor/go.opentelemetry.io/otel/log/internal/global/log.go index 14eadf2e3..d2c5403ca 100644 --- a/vendor/go.opentelemetry.io/otel/log/internal/global/log.go +++ b/vendor/go.opentelemetry.io/otel/log/internal/global/log.go @@ -17,7 +17,7 @@ import ( // instLib defines the instrumentation library a logger is created for. // -// Do not use sdk/instrumentation (API cannot depend on the SDK). +// Do not use sdk/instrumentation (the API cannot depend on the SDK). type instLib struct { name string version string @@ -33,7 +33,7 @@ type loggerProvider struct { delegate log.LoggerProvider } -// Compile-time guarantee loggerProvider implements LoggerProvider. +// This is a compile-time guarantee that loggerProvider implements LoggerProvider. var _ log.LoggerProvider = (*loggerProvider)(nil) func (p *loggerProvider) Logger(name string, options ...log.LoggerOption) log.Logger { @@ -87,7 +87,7 @@ type logger struct { delegate atomic.Value // log.Logger } -// Compile-time guarantee logger implements Logger. +// This is a compile-time guarantee that logger implements Logger. var _ log.Logger = (*logger)(nil) func (l *logger) Emit(ctx context.Context, r log.Record) { diff --git a/vendor/go.opentelemetry.io/otel/log/logger.go b/vendor/go.opentelemetry.io/otel/log/logger.go index 178e6be26..c0e4ca7ae 100644 --- a/vendor/go.opentelemetry.io/otel/log/logger.go +++ b/vendor/go.opentelemetry.io/otel/log/logger.go @@ -15,7 +15,7 @@ import ( // // Warning: Methods may be added to this interface in minor releases. See // package documentation on API implementation for information on how to set -// default behavior for unimplemented methods. +// the default behavior for unimplemented methods. type Logger interface { // Users of the interface can ignore this. This embedded type is only used // by implementations of this interface. See the "API Implementations" @@ -25,7 +25,7 @@ type Logger interface { // Emit emits a log record. // // The record may be held by the implementation. Callers should not mutate - // the record after passed. + // the record after it is passed. // // Implementations of this method need to be safe for a user to call // concurrently. @@ -34,22 +34,28 @@ type Logger interface { // Enabled reports whether the Logger emits for the given context and // param. // - // This is useful for users that want to know if a [Record] - // will be processed or dropped before they perform complex operations to - // construct the [Record]. Callers should invoke Enabled before each call - // to [Logger.Emit] because the enabled state may change over time. + // Calling Enabled is optional. It is not required before calling + // [Logger.Emit]. // - // The passed param is likely to be a partial record information being - // provided (e.g a param with only the Severity set). + // Enabled is useful when constructing a [Record] is expensive. A caller can + // call Enabled first and skip record construction when it returns false. + // When constructing the Record is inexpensive, a caller can emit it + // directly. + // + // The returned value is not static and may change over time. A cached value + // can become stale. + // + // The passed param is likely to contain only partial information about a + // record (e.g., a param with only the Severity set). // If a Logger needs more information than is provided, it // is said to be in an indeterminate state (see below). // - // The returned value will be true when the Logger will emit for the - // provided context and param, and will be false if the Logger will not - // emit. The returned value may be true or false in an indeterminate state. + // The returned value is true if the Logger emits for the provided context + // and param, and false if the Logger does not emit. The returned value may be + // true or false in an indeterminate state. // An implementation should default to returning true for an indeterminate - // state, but may return false if valid reasons in particular circumstances - // exist (e.g. performance, correctness). + // state, but may return false if there are valid reasons to do so in + // particular circumstances (e.g., performance or correctness). // // The param should not be held by the implementation. A copy should be // made if the param needs to be held after the call returns. @@ -61,7 +67,7 @@ type Logger interface { // LoggerOption applies configuration options to a [Logger]. type LoggerOption interface { - // applyLogger is used to set a LoggerOption value of a LoggerConfig. + // applyLogger applies a LoggerOption to a LoggerConfig. applyLogger(LoggerConfig) LoggerConfig } @@ -123,8 +129,8 @@ func WithInstrumentationVersion(version string) LoggerOption { }) } -// mergeSets returns the union of keys between a and b. Any duplicate keys will -// use the value associated with b. +// mergeSets returns the union of the keys in a and b. For duplicate keys, the +// value associated with b is used. func mergeSets(a, b attribute.Set) attribute.Set { // NewMergeIterator uses the first value for any duplicates. iter := attribute.NewMergeIterator(&b, &a) @@ -144,18 +150,20 @@ func mergeSets(a, b attribute.Set) attribute.Set { // // If multiple [WithInstrumentationAttributes] or [WithInstrumentationAttributeSet] // options are passed, the attributes will be merged together in the order -// they are passed. Attributes with duplicate keys will use the last value passed. +// they are passed. For attributes with duplicate keys, the last value passed +// will be used. func WithInstrumentationAttributes(attr ...attribute.KeyValue) LoggerOption { set := attribute.NewSet(slices.Clone(attr)...) return WithInstrumentationAttributeSet(set) } -// WithInstrumentationAttributeSet returns a [LoggerOption] that adds the -// instrumentation attributes of a [Logger]. +// WithInstrumentationAttributeSet returns a [LoggerOption] that adds +// instrumentation attributes to a [Logger]. // // If multiple [WithInstrumentationAttributes] or [WithInstrumentationAttributeSet] // options are passed, the attributes will be merged together in the order -// they are passed. Attributes with duplicate keys will use the last value passed. +// they are passed. For attributes with duplicate keys, the last value passed +// will be used. func WithInstrumentationAttributeSet(set attribute.Set) LoggerOption { if set.Len() == 0 { return loggerOptionFunc(func(config LoggerConfig) LoggerConfig { @@ -182,7 +190,7 @@ func WithSchemaURL(schemaURL string) LoggerOption { }) } -// EnabledParameters represents payload for [Logger]'s Enabled method. +// EnabledParameters represents the payload for [Logger.Enabled]. type EnabledParameters struct { Severity Severity EventName string diff --git a/vendor/go.opentelemetry.io/otel/log/noop/noop.go b/vendor/go.opentelemetry.io/otel/log/noop/noop.go index 082eb887b..0bb1de4ab 100644 --- a/vendor/go.opentelemetry.io/otel/log/noop/noop.go +++ b/vendor/go.opentelemetry.io/otel/log/noop/noop.go @@ -2,14 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 // Package noop provides an implementation of the [OpenTelemetry Logs Bridge -// API] that produces no telemetry and minimizes used computation resources. +// API] that produces no telemetry and minimizes computational resource usage. // // Using this package to implement the [OpenTelemetry Logs API] will // effectively disable OpenTelemetry. // // This implementation can be embedded in other implementations of the -// [OpenTelemetry Logs API]. Doing so will mean the implementation -// defaults to no operation for methods it does not implement. +// [OpenTelemetry Logs API]. Doing so means that the implementation defaults to +// performing no operation for methods it does not implement. // // [OpenTelemetry Logs API]: https://pkg.go.dev/go.opentelemetry.io/otel/log package noop @@ -22,7 +22,8 @@ import ( ) var ( - // Compile-time check this implements the OpenTelemetry API. + // These compile-time checks ensure that the implementations satisfy the + // OpenTelemetry API. _ log.LoggerProvider = LoggerProvider{} _ log.Logger = Logger{} ) diff --git a/vendor/go.opentelemetry.io/otel/log/provider.go b/vendor/go.opentelemetry.io/otel/log/provider.go index 62b7d73fc..10969b415 100644 --- a/vendor/go.opentelemetry.io/otel/log/provider.go +++ b/vendor/go.opentelemetry.io/otel/log/provider.go @@ -9,7 +9,7 @@ import "go.opentelemetry.io/otel/log/embedded" // // Warning: Methods may be added to this interface in minor releases. See // package documentation on API implementation for information on how to set -// default behavior for unimplemented methods. +// the default behavior for unimplemented methods. type LoggerProvider interface { // Users of the interface can ignore this. This embedded type is only used // by implementations of this interface. See the "API Implementations" @@ -19,7 +19,7 @@ type LoggerProvider interface { // Logger returns a new [Logger] with the provided name and configuration. // // The name needs to uniquely identify the source of logged code. It is - // recommended that name is the Go package name of the library using a log + // recommended that name be the Go package name of the library using a log // bridge (note: this is not the name of the bridge package). Most // commonly, this means a bridge will need to accept this value from its // users. @@ -27,7 +27,7 @@ type LoggerProvider interface { // An empty name is invalid. Implementations should retain the empty value as the // instrumentation scope name, return a working Logger, and report the invalid value. // - // The version of the packages using a bridge can be critical information + // The version of the package using a bridge can be critical information // to include when logging. The bridge should accept this version // information and use the [WithInstrumentationVersion] option to configure // the Logger appropriately. diff --git a/vendor/go.opentelemetry.io/otel/log/record.go b/vendor/go.opentelemetry.io/otel/log/record.go index 9e4e4d80b..351657e95 100644 --- a/vendor/go.opentelemetry.io/otel/log/record.go +++ b/vendor/go.opentelemetry.io/otel/log/record.go @@ -11,13 +11,13 @@ import ( ) // attributesInlineCount is the number of attributes that are efficiently -// stored in an array within a Record. This value is borrowed from slog which -// performed a quantitative survey of log library use and found this value to -// cover 95% of all use-cases (https://go.dev/blog/slog#performance). +// stored in an array within a Record. This value is borrowed from slog, which +// performed a quantitative survey of log library use and found that this value +// covers 95% of all use cases (https://go.dev/blog/slog#performance). const attributesInlineCount = 5 // Record represents a log record. -// A log record with non-empty event name is interpreted as an event record. +// A log record with a non-empty event name is interpreted as an event record. type Record struct { // Ensure forward compatibility by explicitly making this not comparable. noCmp [0]func() //nolint: unused // This is indeed used. @@ -45,19 +45,20 @@ type Record struct { // The list of attributes except for those in front. // Invariants: // - len(back) > 0 if nFront == len(front) - // - Unused array elements are zero-ed. Used to detect mistakes. + // - Unused array elements are zeroed to detect mistakes. back []attribute.KeyValue } // EventName returns the event name. -// A log record with non-empty event name is interpreted as an event record. +// A log record with a non-empty event name is interpreted as an event record. func (r *Record) EventName() string { return r.eventName } // SetEventName sets the event name. -// A log record with non-empty event name is interpreted as an event record. -// Event names should uniquely identify the event's attribute and body structure. +// A log record with a non-empty event name is interpreted as an event record. +// Event names should uniquely identify the structure of the event's attributes +// and body. func (r *Record) SetEventName(s string) { r.eventName = s } @@ -92,14 +93,14 @@ func (r *Record) SetSeverity(level Severity) { r.severity = level } -// SeverityText returns severity (also known as log level) text. This is the -// original string representation of the severity as it is known at the source. +// SeverityText returns the text of the severity (also known as the log level) +// as originally known at the source. func (r *Record) SeverityText() string { return r.severityText } -// SetSeverityText sets severity (also known as log level) text. This is the -// original string representation of the severity as it is known at the source. +// SetSeverityText sets the text of the severity (also known as the log level) +// as originally known at the source. func (r *Record) SetSeverityText(text string) { r.severityText = text } @@ -124,8 +125,8 @@ func (r *Record) SetErr(err error) { r.err = err } -// WalkAttributes walks all attributes the log record holds by calling f for -// each on each [attribute.KeyValue] in the [Record]. Iteration stops if f returns false. +// WalkAttributes walks all attributes in the log record by calling f for each +// [attribute.KeyValue] in the [Record]. Iteration stops if f returns false. func (r *Record) WalkAttributes(f func(attribute.KeyValue) bool) { for i := 0; i < r.nFront; i++ { if !f(r.front[i]) { @@ -158,7 +159,8 @@ func (r *Record) AttributesLen() int { } // Clone returns a copy of the record with no shared state. -// The original record and the clone can both be modified without interfering with each other. +// The original record and the clone can both be modified without interfering +// with each other. func (r *Record) Clone() Record { res := *r res.back = slices.Clone(r.back) diff --git a/vendor/go.opentelemetry.io/otel/log/severity.go b/vendor/go.opentelemetry.io/otel/log/severity.go index 29aed675d..4f305be36 100644 --- a/vendor/go.opentelemetry.io/otel/log/severity.go +++ b/vendor/go.opentelemetry.io/otel/log/severity.go @@ -5,56 +5,61 @@ package log -// Severity represents a log record severity (also known as log level). Smaller -// numerical values correspond to less severe log records (such as debug -// events), larger numerical values correspond to more severe log records (such -// as errors and critical events). +// Severity represents a log record's severity (also known as its log level). +// Smaller numerical values correspond to less severe log records (such as +// debug events); larger numerical values correspond to more severe log records +// (such as errors and critical events). type Severity int -// Severity values defined by OpenTelemetry. +// The following Severity values are defined by OpenTelemetry. const ( // SeverityUndefined represents an unset Severity. SeverityUndefined Severity = 0 // UNDEFINED - // A fine-grained debugging log record. Typically disabled in default - // configurations. + // The following are severity values for fine-grained debugging log records. + // They are typically disabled in default configurations. SeverityTrace1 Severity = 1 // TRACE SeverityTrace2 Severity = 2 // TRACE2 SeverityTrace3 Severity = 3 // TRACE3 SeverityTrace4 Severity = 4 // TRACE4 - // A debugging log record. + // The following are severity values for debugging log records. SeverityDebug1 Severity = 5 // DEBUG SeverityDebug2 Severity = 6 // DEBUG2 SeverityDebug3 Severity = 7 // DEBUG3 SeverityDebug4 Severity = 8 // DEBUG4 - // An informational log record. Indicates that an event happened. + // The following are severity values for informational log records indicating + // that an event happened. SeverityInfo1 Severity = 9 // INFO SeverityInfo2 Severity = 10 // INFO2 SeverityInfo3 Severity = 11 // INFO3 SeverityInfo4 Severity = 12 // INFO4 - // A warning log record. Not an error but is likely more important than an - // informational event. + // The following are severity values for warning log records. These records + // are not errors, but they are likely more important than informational + // events. SeverityWarn1 Severity = 13 // WARN SeverityWarn2 Severity = 14 // WARN2 SeverityWarn3 Severity = 15 // WARN3 SeverityWarn4 Severity = 16 // WARN4 - // An error log record. Something went wrong. + // The following are severity values for error log records indicating that + // something went wrong. SeverityError1 Severity = 17 // ERROR SeverityError2 Severity = 18 // ERROR2 SeverityError3 Severity = 19 // ERROR3 SeverityError4 Severity = 20 // ERROR4 - // A fatal log record such as application or system crash. + // The following are severity values for fatal log records, such as those + // associated with an application or system crash. SeverityFatal1 Severity = 21 // FATAL SeverityFatal2 Severity = 22 // FATAL2 SeverityFatal3 Severity = 23 // FATAL3 SeverityFatal4 Severity = 24 // FATAL4 - // Convenience definitions for the base severity of each level. + // The following are convenience definitions for the base severity of each + // level. SeverityTrace = SeverityTrace1 SeverityDebug = SeverityDebug1 SeverityInfo = SeverityInfo1 diff --git a/vendor/go.opentelemetry.io/otel/renovate.json b/vendor/go.opentelemetry.io/otel/renovate.json index fa5acf2d3..5008ab2bf 100644 --- a/vendor/go.opentelemetry.io/otel/renovate.json +++ b/vendor/go.opentelemetry.io/otel/renovate.json @@ -15,6 +15,13 @@ "matchDepTypes": ["indirect"], "enabled": true }, + { + "description": "Disable Go module major updates to v2+", + "matchManagers": ["gomod"], + "matchUpdateTypes": ["major"], + "matchNewValue": "/^v?([2-9]|[1-9][0-9]+)\\./", + "enabled": false + }, { "matchPackageNames": ["go.opentelemetry.io/build-tools/**"], "groupName": "build-tools" diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go index ea7903096..f599bf285 100644 --- a/vendor/go.opentelemetry.io/otel/version.go +++ b/vendor/go.opentelemetry.io/otel/version.go @@ -5,5 +5,5 @@ package otel // Version is the current release version of OpenTelemetry in use. func Version() string { - return "1.45.0" + return "1.46.0" } diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml index 3b1ad7301..f329d171d 100644 --- a/vendor/go.opentelemetry.io/otel/versions.yaml +++ b/vendor/go.opentelemetry.io/otel/versions.yaml @@ -3,7 +3,7 @@ module-sets: stable-v1: - version: v1.45.0 + version: v1.46.0 modules: - go.opentelemetry.io/otel - go.opentelemetry.io/otel/bridge/opencensus @@ -22,12 +22,12 @@ module-sets: - go.opentelemetry.io/otel/sdk/metric - go.opentelemetry.io/otel/trace experimental-metrics: - version: v0.67.0 + version: v0.68.0 modules: - go.opentelemetry.io/otel/exporters/prometheus - go.opentelemetry.io/otel/metric/x experimental-logs: - version: v0.21.0 + version: v0.22.0 modules: - go.opentelemetry.io/otel/log - go.opentelemetry.io/otel/log/logtest @@ -37,7 +37,7 @@ module-sets: - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp - go.opentelemetry.io/otel/exporters/stdout/stdoutlog experimental-schema: - version: v0.0.18 + version: v0.0.19 modules: - go.opentelemetry.io/otel/schema excluded-modules: diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 29d332e7b..333448127 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -150,8 +150,18 @@ var ( // throttling limit if unforeseen issues arise, and it will be removed in a // future release. // - // TODO: Remove this env var once v1.83.0 is release. + // TODO: Remove this env var once v1.83.0 is released. ControlBufferThrottleLimit = uint64FromEnv("GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT", 100, 1, 10000) + + // EnableReceiveBufferCompaction enables the compaction of data buffers + // to reduce the number of buffers in the receive buffer. + // + // This environment variable serves as an escape hatch to disable the + // feature if unforeseen issues arise, and it will be removed in a future + // release. + // + // TODO: Remove this env var once v1.85.0 is released. + EnableReceiveBufferCompaction = boolFromEnv("GRPC_GO_EXPERIMENTAL_ENABLE_RECEIVE_BUFFER_COMPACTION", true) ) func boolFromEnv(envVar string, def bool) bool { diff --git a/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go b/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go index 2d83b2ece..00aeca419 100644 --- a/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go +++ b/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go @@ -26,12 +26,26 @@ import ( "slices" "sort" "sync" + + "google.golang.org/grpc/internal" ) const ( goPageSize = 4 * 1024 // 4KiB. N.B. this must be a power of 2. ) +var ( + // BufferPoolingThreshold is the minimum size of a buffer that can be pooled. + // This is used to determine whether to pool buffers or allocate them directly. + BufferPoolingThreshold = 1 << 10 +) + +func init() { + internal.SetBufferPoolingThresholdForTesting = func(threshold int) { + BufferPoolingThreshold = threshold + } +} + var uintSize = bits.UintSize // use a variable for mocking during tests. // bufferPool is a copy of the public bufferPool interface used to avoid diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index a8356c9ad..9cd8d28d3 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -424,7 +424,7 @@ func (ht *serverHandlerTransport) HandleStreams(ctx context.Context, startStream st: ht, headerWireLength: 0, // won't have access to header wire length until golang/go#18997. } - s.Stream.buf.init() + s.Stream.buf.init(ht.bufferPool) s.readRequester = s s.trReader = transportReader{ reader: recvBufferReader{ctx: s.ctx, ctxDone: s.ctx.Done(), recv: &s.buf}, diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index c19b45080..10d197741 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -500,7 +500,7 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr, handler s headerChan: make(chan struct{}), statsHandler: handler, } - s.Stream.buf.init() + s.Stream.buf.init(t.bufferPool) s.Stream.wq.init(defaultWriteQuota, s.done) s.readRequester = s // The client side stream context should have exactly the same life cycle with the user provided context. diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index be8ae9f9c..82e13e64a 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -407,7 +407,7 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade st: t, headerWireLength: int(frame.Header().Length), } - s.Stream.buf.init() + s.Stream.buf.init(t.bufferPool) var ( // if false, content-type was missing or invalid isGRPC = false @@ -522,6 +522,12 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade delete(mdata, "host") } + // If :authority is still missing, i.e. no host or :authority header is + // present, reject the request as invalid. + if len(mdata[":authority"]) == 0 { + t.writeEarlyAbort(streamID, s.contentSubtype, status.New(codes.Internal, "no host or :authority header present"), http.StatusBadRequest, !frame.StreamEnded()) + return nil + } if frame.StreamEnded() { // s is just created by the caller. No lock needed. s.state = streamReadDone diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index d2e49538f..5fc901e5c 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -30,11 +30,14 @@ import ( "sync" "sync/atomic" "time" + "unsafe" "golang.org/x/net/http2" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/envconfig" + imem "google.golang.org/grpc/internal/mem" "google.golang.org/grpc/internal/transport/internal" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/mem" @@ -45,7 +48,30 @@ import ( "google.golang.org/grpc/tap" ) -const logLevel = 2 +const ( + logLevel = 2 + // recvMsgSize estimates the memory overhead of a recvMsg in the backlog. + // It accounts for the recvMsg struct itself and the slice header of the + // underlying buffer's data. + recvMsgSize = int(unsafe.Sizeof(recvMsg{}) + unsafe.Sizeof([]byte{})) + + // utilizationFactor controls when we consider memory utilization acceptable. + // When backlogHeapSize / payloadSize <= utilizationFactor (meaning at least + // 50% of the heap memory is actual payload data), compaction is skipped. + utilizationFactor = 2 +) + +var ( + // compactionThreshold is approx 57KB (on 64-bit systems). It allows + // accumulating up to 1024 1-byte payloads before triggering compaction. + // + // Because individual payloads <= 1024 bytes are allocated on the heap + // outside mem.BufferPool, waiting for at least 1024 bytes to accumulate + // ensures that compaction coalesces those small heap allocations into a + // single large buffer from mem.BufferPool, enabling buffer reuse while + // avoiding frequent copying for small bursts of frames. + compactionThreshold = imem.BufferPoolingThreshold * (recvMsgSize + 1) +) func init() { internal.TimeNowFunc = func() int64 { return time.Now().UnixNano() } @@ -71,23 +97,31 @@ type recvBuffer struct { c chan recvMsg mu sync.Mutex backlog []recvMsg - err error + // uncompactedSuffixLen tracks the number of consecutive data messages at + // the tail of backlog that have not been compacted. + uncompactedSuffixLen int + // uncompactedBytes tracks the total payload bytes across the trailing + // uncompactedSuffixLen messages. + uncompactedBytes int + err error + bufPool mem.BufferPool } // init allows a recvBuffer to be initialized in-place, which is useful // for resetting a buffer or for avoiding a heap allocation when the buffer // is embedded in another struct. -func (b *recvBuffer) init() { +func (b *recvBuffer) init(pool mem.BufferPool) { b.c = make(chan recvMsg, 1) + b.bufPool = pool } func (b *recvBuffer) put(r recvMsg) { b.mu.Lock() + defer b.mu.Unlock() if b.err != nil { // drop the buffer on the floor. Since b.err is not nil, any subsequent reads // will always return an error, making this buffer inaccessible. r.buffer.Free() - b.mu.Unlock() // An error had occurred earlier, don't accept more // data or errors. return @@ -96,13 +130,70 @@ func (b *recvBuffer) put(r recvMsg) { if len(b.backlog) == 0 { select { case b.c <- r: - b.mu.Unlock() return default: } } b.backlog = append(b.backlog, r) - b.mu.Unlock() + b.compactBacklogLocked(r) +} + +func (b *recvBuffer) compactBacklogLocked(r recvMsg) { + if !envconfig.EnableReceiveBufferCompaction { + return + } + if r.buffer == nil { + b.uncompactedBytes = 0 + b.uncompactedSuffixLen = 0 + return + } + + b.uncompactedSuffixLen++ + b.uncompactedBytes += r.buffer.Len() + backlogHeapSize := b.uncompactedSuffixLen*recvMsgSize + b.uncompactedBytes + + // If the memory overhead is less than 50% of the heap usage (e.g., because + // a large DATA frame arrived), the average message size in the suffix is + // large enough that memory bloat is not a concern. Reset suffix tracking. + if backlogHeapSize <= utilizationFactor*b.uncompactedBytes { + b.uncompactedBytes = 0 + b.uncompactedSuffixLen = 0 + return + } + // Avoid compacting too frequently for short bursts of small frames. + // Wait until we have accumulated at least ~1024 small messages (~57 KB). + if backlogHeapSize <= compactionThreshold { + // Still can accumulate more payloads. + return + } + + // Since the memory utilization is less than 50%, the average payload size + // of each recvMsg must be less than recvMsgSize (approx 56 bytes). + // In the worst case for bytes copied (where the average payload is just + // below recvMsgSize), compaction will occur once every: + // compactionThreshold / (recvMsgSize + avg_payload) = ~520 messages, + // copying ~29KB of data. + + start := 0 + newBuf := b.bufPool.Get(b.uncompactedBytes) + startIdx := len(b.backlog) - b.uncompactedSuffixLen + + for i := startIdx; i < len(b.backlog); i++ { + m := b.backlog[i] + b.backlog[i] = recvMsg{} + start += copy((*newBuf)[start:], m.buffer.ReadOnlyData()) + m.buffer.Free() + } + b.backlog[startIdx] = recvMsg{ + buffer: mem.NewBuffer(newBuf, b.bufPool), + } + b.backlog = b.backlog[:startIdx+1] + // After compaction, the suffix is replaced with a single message containing + // the combined payload. The new utilization is close to 1.0 (overhead of + // one recvMsg relative to the large compacted payload), which is well + // below the utilization factor of 2. + b.uncompactedBytes = 0 + b.uncompactedSuffixLen = 0 } func (b *recvBuffer) load() { @@ -110,6 +201,13 @@ func (b *recvBuffer) load() { if len(b.backlog) > 0 { select { case b.c <- b.backlog[0]: + // backlog[0] is only part of the tracked uncompacted suffix if the + // entire backlog currently consists of the suffix. If an earlier + // compaction or reset occurred, backlog[0] is already compacted. + if envconfig.EnableReceiveBufferCompaction && b.uncompactedSuffixLen == len(b.backlog) { + b.uncompactedSuffixLen-- + b.uncompactedBytes -= b.backlog[0].buffer.Len() + } b.backlog[0] = recvMsg{} b.backlog = b.backlog[1:] default: diff --git a/vendor/google.golang.org/grpc/mem/buffer_pool.go b/vendor/google.golang.org/grpc/mem/buffer_pool.go index 3b02b9091..aa121379f 100644 --- a/vendor/google.golang.org/grpc/mem/buffer_pool.go +++ b/vendor/google.golang.org/grpc/mem/buffer_pool.go @@ -59,10 +59,6 @@ func init() { internal.SetDefaultBufferPool = func(pool BufferPool) { defaultBufferPool = pool } - - internal.SetBufferPoolingThresholdForTesting = func(threshold int) { - bufferPoolingThreshold = threshold - } } // DefaultBufferPool returns the current default buffer pool. It is a BufferPool diff --git a/vendor/google.golang.org/grpc/mem/buffers.go b/vendor/google.golang.org/grpc/mem/buffers.go index 2b410b16e..9b355d446 100644 --- a/vendor/google.golang.org/grpc/mem/buffers.go +++ b/vendor/google.golang.org/grpc/mem/buffers.go @@ -29,6 +29,8 @@ import ( "fmt" "sync" "sync/atomic" + + "google.golang.org/grpc/internal/mem" ) // A Buffer represents a reference counted piece of data (in bytes) that can be @@ -63,8 +65,6 @@ type Buffer interface { } var ( - bufferPoolingThreshold = 1 << 10 - bufferObjectPool = sync.Pool{New: func() any { return new(buffer) }} ) @@ -72,7 +72,7 @@ var ( // equal to the threshold for buffer pooling. This is used to determine whether // to pool buffers or allocate them directly. func IsBelowBufferPoolingThreshold(size int) bool { - return size <= bufferPoolingThreshold + return size <= mem.BufferPoolingThreshold } type buffer struct { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 4083c0390..835dc07fd 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.83.0" +const Version = "1.83.2" diff --git a/vendor/modules.txt b/vendor/modules.txt index 7148953d2..72e9616e2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,7 +1,7 @@ # dario.cat/mergo v1.0.2 ## explicit; go 1.13 dario.cat/mergo -# github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.0 +# github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.1 ## explicit; go 1.25.0 github.com/Azure/azure-sdk-for-go/sdk/azcore github.com/Azure/azure-sdk-for-go/sdk/azcore/arm @@ -25,7 +25,7 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming github.com/Azure/azure-sdk-for-go/sdk/azcore/to github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing -# github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0 +# github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.1 ## explicit; go 1.25.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal @@ -264,7 +264,7 @@ github.com/aws/aws-sdk-go-v2/internal/shareddefaults github.com/aws/aws-sdk-go-v2/internal/strings github.com/aws/aws-sdk-go-v2/internal/sync/singleflight github.com/aws/aws-sdk-go-v2/internal/timeconv -# github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18 +# github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/eventstreamapi @@ -314,7 +314,7 @@ github.com/aws/aws-sdk-go-v2/service/ecs/types github.com/aws/aws-sdk-go-v2/service/iam github.com/aws/aws-sdk-go-v2/service/iam/internal/endpoints github.com/aws/aws-sdk-go-v2/service/iam/types -# github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.17 +# github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding # github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.30 @@ -360,7 +360,7 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc/types github.com/aws/aws-sdk-go-v2/service/sts github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints github.com/aws/aws-sdk-go-v2/service/sts/types -# github.com/aws/smithy-go v1.27.8 +# github.com/aws/smithy-go v1.28.1 ## explicit; go 1.24 github.com/aws/smithy-go github.com/aws/smithy-go/auth @@ -441,7 +441,7 @@ github.com/charmbracelet/x/cellbuf # github.com/charmbracelet/x/term v0.2.2 ## explicit; go 1.24.0 github.com/charmbracelet/x/term -# github.com/cheggaaa/pb v1.0.29 +# github.com/cheggaaa/pb v1.0.30 ## explicit; go 1.12 github.com/cheggaaa/pb # github.com/clipperhouse/displaywidth v0.11.0 @@ -600,7 +600,7 @@ github.com/go-logr/logr/funcr # github.com/go-logr/stdr v1.2.2 ## explicit; go 1.16 github.com/go-logr/stdr -# github.com/go-openapi/analysis v0.26.0 +# github.com/go-openapi/analysis v0.26.2 ## explicit; go 1.25.0 github.com/go-openapi/analysis github.com/go-openapi/analysis/internal/debug @@ -616,14 +616,14 @@ github.com/go-openapi/errors ## explicit; go 1.25.0 github.com/go-openapi/jsonpointer github.com/go-openapi/jsonpointer/jsonname -# github.com/go-openapi/jsonreference v1.0.0 +# github.com/go-openapi/jsonreference v1.0.1 ## explicit; go 1.25.0 github.com/go-openapi/jsonreference github.com/go-openapi/jsonreference/internal -# github.com/go-openapi/loads v0.25.1 +# github.com/go-openapi/loads v0.25.2 ## explicit; go 1.25.0 github.com/go-openapi/loads -# github.com/go-openapi/runtime v0.33.0 +# github.com/go-openapi/runtime v0.33.1 ## explicit; go 1.25.0 github.com/go-openapi/runtime github.com/go-openapi/runtime/client @@ -634,13 +634,13 @@ github.com/go-openapi/runtime/middleware/denco github.com/go-openapi/runtime/middleware/untyped github.com/go-openapi/runtime/security github.com/go-openapi/runtime/yamlpc -# github.com/go-openapi/runtime/server-middleware v0.33.0 +# github.com/go-openapi/runtime/server-middleware v0.33.1 ## explicit; go 1.25.0 github.com/go-openapi/runtime/server-middleware/docui github.com/go-openapi/runtime/server-middleware/mediatype github.com/go-openapi/runtime/server-middleware/negotiate github.com/go-openapi/runtime/server-middleware/negotiate/header -# github.com/go-openapi/spec v0.22.9 +# github.com/go-openapi/spec v0.22.11 ## explicit; go 1.25.0 github.com/go-openapi/spec # github.com/go-openapi/strfmt v0.27.0 @@ -654,40 +654,40 @@ github.com/go-openapi/swag # github.com/go-openapi/swag/cmdutils v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/cmdutils -# github.com/go-openapi/swag/conv v0.28.0 +# github.com/go-openapi/swag/conv v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/conv -# github.com/go-openapi/swag/fileutils v0.28.0 +# github.com/go-openapi/swag/fileutils v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/fileutils -# github.com/go-openapi/swag/jsonutils v0.28.0 +# github.com/go-openapi/swag/jsonutils v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/jsonutils github.com/go-openapi/swag/jsonutils/adapters github.com/go-openapi/swag/jsonutils/adapters/ifaces github.com/go-openapi/swag/jsonutils/adapters/stdlib/json -# github.com/go-openapi/swag/loading v0.28.0 +# github.com/go-openapi/swag/loading v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/loading -# github.com/go-openapi/swag/mangling v0.28.0 +# github.com/go-openapi/swag/mangling v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/mangling # github.com/go-openapi/swag/netutils v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/netutils -# github.com/go-openapi/swag/pools v0.28.0 +# github.com/go-openapi/swag/pools v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/pools -# github.com/go-openapi/swag/stringutils v0.28.0 +# github.com/go-openapi/swag/stringutils v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/stringutils -# github.com/go-openapi/swag/typeutils v0.28.0 +# github.com/go-openapi/swag/typeutils v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/typeutils -# github.com/go-openapi/swag/yamlutils v0.28.0 +# github.com/go-openapi/swag/yamlutils v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/yamlutils -# github.com/go-openapi/validate v0.26.3 +# github.com/go-openapi/validate v0.26.5 ## explicit; go 1.25.0 github.com/go-openapi/validate # github.com/go-playground/locales v0.14.1 @@ -1154,7 +1154,7 @@ github.com/santhosh-tekuri/jsonschema/v5 # github.com/sergi/go-diff v1.4.0 ## explicit; go 1.13 github.com/sergi/go-diff/diffmatchpatch -# github.com/sirupsen/logrus v1.10.1 +# github.com/sirupsen/logrus v1.10.2 ## explicit; go 1.23 github.com/sirupsen/logrus # github.com/spf13/afero v1.15.0 @@ -1243,10 +1243,10 @@ go.opentelemetry.io/collector/pdata/internal/proto go.opentelemetry.io/collector/pdata/pcommon go.opentelemetry.io/collector/pdata/plog go.opentelemetry.io/collector/pdata/ptrace -# go.opentelemetry.io/contrib/bridges/otelslog v0.20.0 +# go.opentelemetry.io/contrib/bridges/otelslog v0.20.1 ## explicit; go 1.25.0 go.opentelemetry.io/contrib/bridges/otelslog -# go.opentelemetry.io/otel v1.45.0 +# go.opentelemetry.io/otel v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute @@ -1286,14 +1286,14 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x -# go.opentelemetry.io/otel/log v0.21.0 +# go.opentelemetry.io/otel/log v0.22.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/log go.opentelemetry.io/otel/log/embedded go.opentelemetry.io/otel/log/global go.opentelemetry.io/otel/log/internal/global go.opentelemetry.io/otel/log/noop -# go.opentelemetry.io/otel/metric v1.45.0 +# go.opentelemetry.io/otel/metric v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/metric go.opentelemetry.io/otel/metric/embedded @@ -1315,7 +1315,7 @@ go.opentelemetry.io/otel/sdk/log/internal/attrnorm go.opentelemetry.io/otel/sdk/log/internal/counter go.opentelemetry.io/otel/sdk/log/internal/observ go.opentelemetry.io/otel/sdk/log/internal/x -# go.opentelemetry.io/otel/trace v1.45.0 +# go.opentelemetry.io/otel/trace v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded @@ -1451,7 +1451,7 @@ google.golang.org/genproto/googleapis/api/httpbody ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.83.0 +# google.golang.org/grpc v1.83.2 ## explicit; go 1.25.0 google.golang.org/grpc google.golang.org/grpc/attributes @@ -1685,5 +1685,5 @@ sigs.k8s.io/structured-merge-diff/v6/value sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 # github.com/charmbracelet/bubbles/v2 => charm.land/bubbles/v2 v2.1.1 -# github.com/charmbracelet/bubbletea/v2 => charm.land/bubbletea/v2 v2.0.8 +# github.com/charmbracelet/bubbletea/v2 => charm.land/bubbletea/v2 v2.0.9 # github.com/charmbracelet/lipgloss/v2 => charm.land/lipgloss/v2 v2.0.6