Upgrade dependencies
This commit is contained in:
parent
b042574e45
commit
8a4e5363ac
33
go.mod
33
go.mod
@ -3,7 +3,7 @@ module github.com/datarhei/core/v16
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.17.12
|
||||
github.com/99designs/gqlgen v0.17.15
|
||||
github.com/atrox/haikunatorgo/v2 v2.0.1
|
||||
github.com/datarhei/gosrt v0.2.1-0.20220817080252-d44df04a3845
|
||||
github.com/datarhei/joy4 v0.0.0-20220728180719-f752080f4a36
|
||||
@ -13,20 +13,21 @@ require (
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/invopop/jsonschema v0.4.0
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/labstack/echo/v4 v4.7.2
|
||||
github.com/labstack/echo/v4 v4.8.0
|
||||
github.com/lithammer/shortuuid/v4 v4.0.0
|
||||
github.com/mattn/go-isatty v0.0.14
|
||||
github.com/mattn/go-isatty v0.0.16
|
||||
github.com/minio/minio-go/v7 v7.0.34
|
||||
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
|
||||
github.com/prometheus/client_golang v1.12.2
|
||||
github.com/shirou/gopsutil/v3 v3.22.6
|
||||
github.com/stretchr/testify v1.7.5
|
||||
github.com/swaggo/echo-swagger v1.3.3
|
||||
github.com/swaggo/swag v1.8.3
|
||||
github.com/vektah/gqlparser/v2 v2.4.6
|
||||
github.com/prometheus/client_golang v1.13.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.7
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/swaggo/echo-swagger v1.3.4
|
||||
github.com/swaggo/swag v1.8.4
|
||||
github.com/vektah/gqlparser/v2 v2.4.8
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
|
||||
golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c
|
||||
)
|
||||
|
||||
require (
|
||||
@ -41,8 +42,8 @@ require (
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/spec v0.20.6 // indirect
|
||||
github.com/go-openapi/swag v0.21.1 // indirect
|
||||
github.com/go-openapi/spec v0.20.7 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
@ -58,8 +59,7 @@ require (
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/matryer/moq v0.2.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
@ -84,13 +84,12 @@ require (
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
|
||||
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/ini.v1 v1.66.6 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
63
go.sum
63
go.sum
@ -31,8 +31,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/99designs/gqlgen v0.17.12 h1:lH/H5dTYCY5eLNRKXeq22l0wFMavpOnN6v9GAIw+fxY=
|
||||
github.com/99designs/gqlgen v0.17.12/go.mod h1:w1brbeOdqVyNJI553BGwtwdVcYu1LKeYE1opLWN9RgQ=
|
||||
github.com/99designs/gqlgen v0.17.15 h1:5YgNFd46NhO/VltM4ENc6m26mj8GJxQg2ZKOy5s83tA=
|
||||
github.com/99designs/gqlgen v0.17.15/go.mod h1:IXeS/mdPf7JPkmqvbRKjCAV+CLxMKe6vXw6yD9vamB8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@ -110,12 +110,12 @@ github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/a
|
||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||
github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ=
|
||||
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI=
|
||||
github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
|
||||
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
@ -236,8 +236,9 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
|
||||
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/echo/v4 v4.8.0 h1:wdc6yKVaHxkNOEdz4cRZs1pQkwSXPiRjq69yWP4QQS8=
|
||||
github.com/labstack/echo/v4 v4.8.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
@ -253,13 +254,14 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matryer/moq v0.2.7 h1:RtpiPUM8L7ZSCbSwK+QcZH/E9tgqAkFjKQxsRs25b4w=
|
||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
@ -303,8 +305,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34=
|
||||
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
|
||||
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@ -334,8 +336,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shirou/gopsutil/v3 v3.22.6 h1:FnHOFOh+cYAM0C30P+zysPISzlknLC5Z1G4EAElznfQ=
|
||||
github.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs=
|
||||
github.com/shirou/gopsutil/v3 v3.22.7 h1:flKnuCMfUUrO+oAvwAd6GKZgnPzr098VA/UJ14nhJd4=
|
||||
github.com/shirou/gopsutil/v3 v3.22.7/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
@ -355,16 +357,15 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q=
|
||||
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/swaggo/echo-swagger v1.3.3 h1:Fx8kQ8IcIIEL3ZE20wzvcT8gFnPo/4U+fsnS3I1wvCw=
|
||||
github.com/swaggo/echo-swagger v1.3.3/go.mod h1:vbKcEBeJgOexLuPcsdZhrRAV508fsE79xaKIqmvse98=
|
||||
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/swaggo/echo-swagger v1.3.4 h1:8B+yVqjVm7cMy4QBLRUuRaOzrTVAqZahcrgrOSdpC5I=
|
||||
github.com/swaggo/echo-swagger v1.3.4/go.mod h1:vh8QAdbHtTXwTSaWzc1Nby7zMYJd/g0FwQyArmrFHA8=
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a h1:kAe4YSu0O0UFn1DowNo2MY5p6xzqtJ/wQ7LZynSvGaY=
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
||||
github.com/swaggo/swag v1.8.3 h1:3pZSSCQ//gAH88lfmxM3Cd1+JCsxV8Md6f36b9hrZ5s=
|
||||
github.com/swaggo/swag v1.8.3/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
|
||||
github.com/swaggo/swag v1.8.4 h1:oGB351qH1JqUqK1tsMYEE5qTBbPk394BhsZxmUfebcI=
|
||||
github.com/swaggo/swag v1.8.4/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
|
||||
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
@ -377,8 +378,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vektah/gqlparser/v2 v2.4.6 h1:Yjzp66g6oVq93Jihbi0qhGnf/6zIWjcm8H6gA27zstE=
|
||||
github.com/vektah/gqlparser/v2 v2.4.6/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
||||
github.com/vektah/gqlparser/v2 v2.4.8 h1:O0G2I4xEi7J0/b/qRCWGNXEiU9EQ+hGBmlIU1LXLUfY=
|
||||
github.com/vektah/gqlparser/v2 v2.4.8/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@ -410,8 +411,9 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c=
|
||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -484,8 +486,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c h1:JVAXQ10yGGVbSyoer5VILysz6YKjdNT2bsvlayjqhes=
|
||||
golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -556,8 +558,9 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24 h1:TyKJRhyo17yWxOMCTHKWrc5rddHORMlnZ/j57umaUd8=
|
||||
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -710,8 +713,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI=
|
||||
gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/.gitignore
generated
vendored
1
vendor/github.com/99designs/gqlgen/.gitignore
generated
vendored
@ -15,3 +15,4 @@
|
||||
*.test
|
||||
*.out
|
||||
gqlgen
|
||||
*.exe
|
||||
|
||||
152
vendor/github.com/99designs/gqlgen/CHANGELOG.md
generated
vendored
152
vendor/github.com/99designs/gqlgen/CHANGELOG.md
generated
vendored
@ -5,10 +5,160 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
<a name="unreleased"></a>
|
||||
## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.11...HEAD)
|
||||
## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.14...HEAD)
|
||||
|
||||
<!-- end of if -->
|
||||
<!-- end of CommitGroups -->
|
||||
<a name="v0.17.14"></a>
|
||||
## [v0.17.14](https://github.com/99designs/gqlgen/compare/v0.17.13...v0.17.14) - 2022-08-18
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/581bf6eb063a0d6a3cec3b6bc7a16ca10e310a97"><tt>581bf6eb</tt></a> release v0.17.14
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/d3384377aefb4b7d34ba52f8def6c0a6a3dec27f"><tt>d3384377</tt></a> Update gqlparser
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/c2d02d352f8d531fa0bd9b246fc152eeb6dbf10a"><tt>c2d02d35</tt></a> More descriptive `not implemented` stubs (<a href="https://github.com/99designs/gqlgen/pull/2328">#2328</a>) (closes <a href="https://github.com/99designs/gqlgen/issues/2327"> #2327</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/9f919d2cee464acdaf4a490aeb42d63369dbd572"><tt>9f919d2c</tt></a> Avoid GraphQL to Go Naming Collision with "ToGoModelName" func (<a href="https://github.com/99designs/gqlgen/pull/2322">#2322</a>) (closes <a href="https://github.com/99designs/gqlgen/issues/2321"> #2321</a>)</summary>
|
||||
|
||||
* using ReplaceAllStringLiteral
|
||||
|
||||
* fixing wordInfo template test
|
||||
|
||||
* bumping linter timeout to 5m
|
||||
|
||||
* comment cleanup
|
||||
|
||||
* some cleanup, adding "ToGoPrivateModelName" func
|
||||
|
||||
* adding "ToGoPrivateModelName" func
|
||||
|
||||
* refactoring word walker impl and tests
|
||||
|
||||
* hopefully making linter happy
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/2304c104fc8d26487f50e80e9c5eaee113005a30"><tt>2304c104</tt></a> Include docstrings on interface getters (<a href="https://github.com/99designs/gqlgen/pull/2317">#2317</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/f5d603269502b50e19d0ed966e2dfe3ecd74049f"><tt>f5d60326</tt></a> Leverage (*Imports).LookupType when generating interface field getters (<a href="https://github.com/99designs/gqlgen/pull/2315">#2315</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/242c3ba217ee740e37445ce4b14e0808554263f5"><tt>242c3ba2</tt></a> Generate getters for interface fields (<a href="https://github.com/99designs/gqlgen/pull/2314">#2314</a>)</summary>
|
||||
|
||||
* Generate getters for interface fields
|
||||
|
||||
* Changes to make models_test.go pass
|
||||
|
||||
* Use text/template, not html/template
|
||||
|
||||
* Re-run go generate ./...
|
||||
|
||||
* gofmt a few files that were failing lint checks
|
||||
|
||||
* Another gofmt straggler
|
||||
|
||||
* Try making the "generated" match the exact whitespace github is disliking
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/0d91c893e285cc14330c80643b663cd2bebeb911"><tt>0d91c893</tt></a> Add hackernews graphql api tutorial to other resources (<a href="https://github.com/99designs/gqlgen/pull/2305">#2305</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/c2526ba50ff3a69b5eca88a62a571c47f3c245ed"><tt>c2526ba5</tt></a> Update gqlparser to v2.4.7 (<a href="https://github.com/99designs/gqlgen/pull/2300">#2300</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/f283124d1cea309e054afb197d16012364b88097"><tt>f283124d</tt></a> <a href="https://github.com/99designs/gqlgen/pull/2298">#2298</a>: fix gqlgen extracting module name from comment line (<a href="https://github.com/99designs/gqlgen/pull/2299">#2299</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/779d7cdd4991e3cf4bf1ecbdea1f02664a56ac8d"><tt>779d7cdd</tt></a> Add support for KeepAlive message in websocket client (<a href="https://github.com/99designs/gqlgen/pull/2293">#2293</a>)</summary>
|
||||
|
||||
* Add support for KeepAlive message in websocket client
|
||||
|
||||
* rewrite if-else to switch statement
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/5a37d1dc079f5212b6e043b0f6889cae7b08dea9"><tt>5a37d1dc</tt></a> v0.17.13 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.13"></a>
|
||||
## [v0.17.13](https://github.com/99designs/gqlgen/compare/v0.17.12...v0.17.13) - 2022-07-15
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/e82b6bf1cf311d6af2e280127f47b15ae35ca6ac"><tt>e82b6bf1</tt></a> release v0.17.13
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/f0e9047df5f86efbfbceea9c04593bb1f52e06de"><tt>f0e9047d</tt></a> Hide dependencies in `tools.go` from importers (<a href="https://github.com/99designs/gqlgen/pull/2287">#2287</a>)</summary>
|
||||
|
||||
Projects that use `go mod vendor` will vendor `github.com/matryer/moq`
|
||||
despite it not being required at runtime.
|
||||
|
||||
Moving `tools.go` to `internal` hides this import from downstream
|
||||
users and avoids `github.com/matryer/moq` being vendored.
|
||||
|
||||
`go generate` of the mocks still works as expected.
|
||||
|
||||
The assumption behind the import test broke, so I've pointed it at a
|
||||
different path that has no Go code. This seems to match the intent
|
||||
behind the original test for the `internal/code/..` path.
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/6310e6a736ccbf3bb8caea981553ee7549aea748"><tt>6310e6a7</tt></a> support named interface to Field.CallArgs (<a href="https://github.com/99designs/gqlgen/pull/2289">#2289</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/30493696aacf79090bb5e144a304a5a7df488c67"><tt>30493696</tt></a> fix: return the original error (<a href="https://github.com/99designs/gqlgen/pull/2288">#2288</a>)</summary>
|
||||
|
||||
* fix: return the original error
|
||||
|
||||
close https://github.com/99designs/gqlgen/issues/2286
|
||||
|
||||
* Update error.go
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/fb13091df76b47b936224336fe19b15fe310b41d"><tt>fb13091d</tt></a> updated WebSocker InitFunc recipe (<a href="https://github.com/99designs/gqlgen/pull/2275">#2275</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/770c09fb9db0485943590b9986afe36818c2a70e"><tt>770c09fb</tt></a> Update changelog for v0.17.12
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/b4c186a7142c0a151b6a21b40914fe317e13819d"><tt>b4c186a7</tt></a> v0.17.12 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.12"></a>
|
||||
## [v0.17.12](https://github.com/99designs/gqlgen/compare/v0.17.11...v0.17.12) - 2022-07-04
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/94c02b0de6d483d87453fc18a7f7625ae4adaa6c"><tt>94c02b0d</tt></a> release v0.17.12
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/7eb8ba93daacef77ca7266fdfb9e5abc8a720eb7"><tt>7eb8ba93</tt></a> Fix CreateTodo (<a href="https://github.com/99designs/gqlgen/pull/2256">#2256</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/0b0e5ce4afc5b503217304f89914b2e903c05fa5"><tt>0b0e5ce4</tt></a> Replace use of strings.Title with cases.Title (<a href="https://github.com/99designs/gqlgen/pull/2268">#2268</a>)</summary>
|
||||
|
||||
* github: Test more go versions
|
||||
|
||||
* github: Fix ci tests
|
||||
|
||||
* github: Increase verbosity, sleep
|
||||
|
||||
* github: Drop bash
|
||||
|
||||
* github: Test go 1.18 and newer node verisons
|
||||
|
||||
* github: Pull out node 16 for now
|
||||
|
||||
* github: Only lint 1.16 for now
|
||||
|
||||
* cases: Use cases.Title over strings.Title which is deprecated
|
||||
|
||||
* gqlgen: Remove use of deprecated strings.Title
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/0c11e5fdd8ec4fd7612b857c4c554e1ef463d194"><tt>0c11e5fd</tt></a> parse at beginning of do function (<a href="https://github.com/99designs/gqlgen/pull/2269">#2269</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/edb1c585c1c49102dc962e0ac3bd271688e51ecf"><tt>edb1c585</tt></a> Update Changelog for v0.17.11
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/5e6b52fddab835611513e3572f23716666ebae58"><tt>5e6b52fd</tt></a> v0.17.11 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.11"></a>
|
||||
## [v0.17.11](https://github.com/99designs/gqlgen/compare/v0.17.10...v0.17.11) - 2022-07-03
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/ea294c4ea344186c3b41b82d5f1c60138f6ce05e"><tt>ea294c4e</tt></a> release v0.17.11
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/README.md
generated
vendored
1
vendor/github.com/99designs/gqlgen/README.md
generated
vendored
@ -148,3 +148,4 @@ There isn't any way around this, gqlgen has no way to know what you want in a gi
|
||||
- [Introducing gqlgen: a GraphQL Server Generator for Go](https://99designs.com.au/blog/engineering/gqlgen-a-graphql-server-generator-for-go/)
|
||||
- [Dive into GraphQL by Iván Corrales Solera](https://medium.com/@ivan.corrales.solera/dive-into-graphql-9bfedf22e1a)
|
||||
- [Sample Project built on gqlgen with Postgres by Oleg Shalygin](https://github.com/oshalygin/gqlgen-pg-todo-example)
|
||||
- [Hackernews GraphQL Server with gqlgen by Shayegan Hooshyari](https://www.howtographql.com/graphql-go/0-introduction/)
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/codegen/config/binder.go
generated
vendored
1
vendor/github.com/99designs/gqlgen/codegen/config/binder.go
generated
vendored
@ -216,7 +216,6 @@ func (t *TypeReference) IsPtr() bool {
|
||||
}
|
||||
|
||||
// fix for https://github.com/golang/go/issues/31103 may make it possible to remove this (may still be useful)
|
||||
//
|
||||
func (t *TypeReference) IsPtrToPtr() bool {
|
||||
if p, isPtr := t.GO.(*types.Pointer); isPtr {
|
||||
_, isPtr := p.Elem().(*types.Pointer)
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/codegen/field.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/codegen/field.go
generated
vendored
@ -562,7 +562,7 @@ func (f *Field) CallArgs() string {
|
||||
for _, arg := range f.Args {
|
||||
tmp := "fc.Args[" + strconv.Quote(arg.Name) + "].(" + templates.CurrentImports.LookupType(arg.TypeReference.GO) + ")"
|
||||
|
||||
if types.IsInterface(arg.TypeReference.GO) {
|
||||
if iface, ok := arg.TypeReference.GO.(*types.Interface); ok && iface.Empty() {
|
||||
tmp = fmt.Sprintf(`
|
||||
func () interface{} {
|
||||
if fc.Args["%s"] == nil {
|
||||
|
||||
219
vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
generated
vendored
219
vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
generated
vendored
@ -8,10 +8,12 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
"unicode"
|
||||
|
||||
@ -58,6 +60,12 @@ type Options struct {
|
||||
Packages *code.Packages
|
||||
}
|
||||
|
||||
var (
|
||||
modelNamesMu sync.Mutex
|
||||
modelNames = make(map[string]string, 0)
|
||||
goNameRe = regexp.MustCompile("[^a-zA-Z0-9_]")
|
||||
)
|
||||
|
||||
// Render renders a gql plugin template from the given Options. Render is an
|
||||
// abstraction of the text/template package that makes it easier to write gqlgen
|
||||
// plugins. If Options.Template is empty, the Render function will look for `.gotpl`
|
||||
@ -188,20 +196,22 @@ func center(width int, pad string, s string) string {
|
||||
|
||||
func Funcs() template.FuncMap {
|
||||
return template.FuncMap{
|
||||
"ucFirst": UcFirst,
|
||||
"lcFirst": LcFirst,
|
||||
"quote": strconv.Quote,
|
||||
"rawQuote": rawQuote,
|
||||
"dump": Dump,
|
||||
"ref": ref,
|
||||
"ts": TypeIdentifier,
|
||||
"call": Call,
|
||||
"prefixLines": prefixLines,
|
||||
"notNil": notNil,
|
||||
"reserveImport": CurrentImports.Reserve,
|
||||
"lookupImport": CurrentImports.Lookup,
|
||||
"go": ToGo,
|
||||
"goPrivate": ToGoPrivate,
|
||||
"ucFirst": UcFirst,
|
||||
"lcFirst": LcFirst,
|
||||
"quote": strconv.Quote,
|
||||
"rawQuote": rawQuote,
|
||||
"dump": Dump,
|
||||
"ref": ref,
|
||||
"ts": TypeIdentifier,
|
||||
"call": Call,
|
||||
"prefixLines": prefixLines,
|
||||
"notNil": notNil,
|
||||
"reserveImport": CurrentImports.Reserve,
|
||||
"lookupImport": CurrentImports.Lookup,
|
||||
"go": ToGo,
|
||||
"goPrivate": ToGoPrivate,
|
||||
"goModelName": ToGoModelName,
|
||||
"goPrivateModelName": ToGoPrivateModelName,
|
||||
"add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
@ -291,25 +301,154 @@ func Call(p *types.Func) string {
|
||||
return pkg + p.Name()
|
||||
}
|
||||
|
||||
func resetModelNames() {
|
||||
modelNamesMu.Lock()
|
||||
defer modelNamesMu.Unlock()
|
||||
modelNames = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
func buildGoModelNameKey(parts []string) string {
|
||||
const sep = ":"
|
||||
return strings.Join(parts, sep)
|
||||
}
|
||||
|
||||
func goModelName(primaryToGoFunc func(string) string, parts []string) string {
|
||||
modelNamesMu.Lock()
|
||||
defer modelNamesMu.Unlock()
|
||||
|
||||
var (
|
||||
goNameKey string
|
||||
partLen int
|
||||
|
||||
nameExists = func(n string) bool {
|
||||
for _, v := range modelNames {
|
||||
if n == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
applyToGoFunc = func(parts []string) string {
|
||||
var out string
|
||||
switch len(parts) {
|
||||
case 0:
|
||||
return ""
|
||||
case 1:
|
||||
return primaryToGoFunc(parts[0])
|
||||
default:
|
||||
out = primaryToGoFunc(parts[0])
|
||||
}
|
||||
for _, p := range parts[1:] {
|
||||
out = fmt.Sprintf("%s%s", out, ToGo(p))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
applyValidGoName = func(parts []string) string {
|
||||
var out string
|
||||
for _, p := range parts {
|
||||
out = fmt.Sprintf("%s%s", out, replaceInvalidCharacters(p))
|
||||
}
|
||||
return out
|
||||
}
|
||||
)
|
||||
|
||||
// build key for this entity
|
||||
goNameKey = buildGoModelNameKey(parts)
|
||||
|
||||
// determine if we've seen this entity before, and reuse if so
|
||||
if goName, ok := modelNames[goNameKey]; ok {
|
||||
return goName
|
||||
}
|
||||
|
||||
// attempt first pass
|
||||
if goName := applyToGoFunc(parts); !nameExists(goName) {
|
||||
modelNames[goNameKey] = goName
|
||||
return goName
|
||||
}
|
||||
|
||||
// determine number of parts
|
||||
partLen = len(parts)
|
||||
|
||||
// if there is only 1 part, append incrementing number until no conflict
|
||||
if partLen == 1 {
|
||||
base := applyToGoFunc(parts)
|
||||
for i := 0; ; i++ {
|
||||
tmp := fmt.Sprintf("%s%d", base, i)
|
||||
if !nameExists(tmp) {
|
||||
modelNames[goNameKey] = tmp
|
||||
return tmp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// best effort "pretty" name
|
||||
for i := partLen - 1; i >= 1; i-- {
|
||||
tmp := fmt.Sprintf("%s%s", applyToGoFunc(parts[0:i]), applyValidGoName(parts[i:]))
|
||||
if !nameExists(tmp) {
|
||||
modelNames[goNameKey] = tmp
|
||||
return tmp
|
||||
}
|
||||
}
|
||||
|
||||
// finally, fallback to just adding an incrementing number
|
||||
base := applyToGoFunc(parts)
|
||||
for i := 0; ; i++ {
|
||||
tmp := fmt.Sprintf("%s%d", base, i)
|
||||
if !nameExists(tmp) {
|
||||
modelNames[goNameKey] = tmp
|
||||
return tmp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ToGoModelName(parts ...string) string {
|
||||
return goModelName(ToGo, parts)
|
||||
}
|
||||
|
||||
func ToGoPrivateModelName(parts ...string) string {
|
||||
return goModelName(ToGoPrivate, parts)
|
||||
}
|
||||
|
||||
func replaceInvalidCharacters(in string) string {
|
||||
return goNameRe.ReplaceAllLiteralString(in, "_")
|
||||
}
|
||||
|
||||
func wordWalkerFunc(private bool, nameRunes *[]rune) func(*wordInfo) {
|
||||
return func(info *wordInfo) {
|
||||
word := info.Word
|
||||
|
||||
switch {
|
||||
case private && info.WordOffset == 0:
|
||||
if strings.ToUpper(word) == word || strings.ToLower(word) == word {
|
||||
// ID → id, CAMEL → camel
|
||||
word = strings.ToLower(info.Word)
|
||||
} else {
|
||||
// ITicket → iTicket
|
||||
word = LcFirst(info.Word)
|
||||
}
|
||||
|
||||
case info.MatchCommonInitial:
|
||||
word = strings.ToUpper(word)
|
||||
|
||||
case !info.HasCommonInitial && (strings.ToUpper(word) == word || strings.ToLower(word) == word):
|
||||
// FOO or foo → Foo
|
||||
// FOo → FOo
|
||||
word = UcFirst(strings.ToLower(word))
|
||||
}
|
||||
|
||||
*nameRunes = append(*nameRunes, []rune(word)...)
|
||||
}
|
||||
}
|
||||
|
||||
func ToGo(name string) string {
|
||||
if name == "_" {
|
||||
return "_"
|
||||
}
|
||||
runes := make([]rune, 0, len(name))
|
||||
|
||||
wordWalker(name, func(info *wordInfo) {
|
||||
word := info.Word
|
||||
if info.MatchCommonInitial {
|
||||
word = strings.ToUpper(word)
|
||||
} else if !info.HasCommonInitial {
|
||||
if strings.ToUpper(word) == word || strings.ToLower(word) == word {
|
||||
// FOO or foo → Foo
|
||||
// FOo → FOo
|
||||
word = UcFirst(strings.ToLower(word))
|
||||
}
|
||||
}
|
||||
runes = append(runes, []rune(word)...)
|
||||
})
|
||||
wordWalker(name, wordWalkerFunc(false, &runes))
|
||||
|
||||
return string(runes)
|
||||
}
|
||||
@ -320,31 +459,13 @@ func ToGoPrivate(name string) string {
|
||||
}
|
||||
runes := make([]rune, 0, len(name))
|
||||
|
||||
first := true
|
||||
wordWalker(name, func(info *wordInfo) {
|
||||
word := info.Word
|
||||
switch {
|
||||
case first:
|
||||
if strings.ToUpper(word) == word || strings.ToLower(word) == word {
|
||||
// ID → id, CAMEL → camel
|
||||
word = strings.ToLower(info.Word)
|
||||
} else {
|
||||
// ITicket → iTicket
|
||||
word = LcFirst(info.Word)
|
||||
}
|
||||
first = false
|
||||
case info.MatchCommonInitial:
|
||||
word = strings.ToUpper(word)
|
||||
case !info.HasCommonInitial:
|
||||
word = UcFirst(strings.ToLower(word))
|
||||
}
|
||||
runes = append(runes, []rune(word)...)
|
||||
})
|
||||
wordWalker(name, wordWalkerFunc(true, &runes))
|
||||
|
||||
return sanitizeKeywords(string(runes))
|
||||
}
|
||||
|
||||
type wordInfo struct {
|
||||
WordOffset int
|
||||
Word string
|
||||
MatchCommonInitial bool
|
||||
HasCommonInitial bool
|
||||
@ -354,7 +475,7 @@ type wordInfo struct {
|
||||
// https://github.com/golang/lint/blob/06c8688daad7faa9da5a0c2f163a3d14aac986ca/lint.go#L679
|
||||
func wordWalker(str string, f func(*wordInfo)) {
|
||||
runes := []rune(strings.TrimFunc(str, isDelimiter))
|
||||
w, i := 0, 0 // index of start of word, scan
|
||||
w, i, wo := 0, 0, 0 // index of start of word, scan, word offset
|
||||
hasCommonInitial := false
|
||||
for i+1 <= len(runes) {
|
||||
eow := false // whether we hit the end of a word
|
||||
@ -402,12 +523,14 @@ func wordWalker(str string, f func(*wordInfo)) {
|
||||
}
|
||||
|
||||
f(&wordInfo{
|
||||
WordOffset: wo,
|
||||
Word: word,
|
||||
MatchCommonInitial: matchCommonInitial,
|
||||
HasCommonInitial: hasCommonInitial,
|
||||
})
|
||||
hasCommonInitial = false
|
||||
w = i
|
||||
wo++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
vendor/github.com/99designs/gqlgen/graphql/error.go
generated
vendored
3
vendor/github.com/99designs/gqlgen/graphql/error.go
generated
vendored
@ -26,7 +26,8 @@ func ErrorOnPath(ctx context.Context, err error) error {
|
||||
if gqlErr.Path == nil {
|
||||
gqlErr.Path = GetPath(ctx)
|
||||
}
|
||||
return gqlErr
|
||||
// Return the original error to avoid losing any attached annotation
|
||||
return err
|
||||
}
|
||||
return gqlerror.WrapPath(GetPath(ctx), err)
|
||||
}
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
@ -1,3 +1,3 @@
|
||||
package graphql
|
||||
|
||||
const Version = "v0.17.12"
|
||||
const Version = "v0.17.15"
|
||||
|
||||
25
vendor/github.com/99designs/gqlgen/internal/code/imports.go
generated
vendored
25
vendor/github.com/99designs/gqlgen/internal/code/imports.go
generated
vendored
@ -1,6 +1,8 @@
|
||||
package code
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
@ -74,7 +76,7 @@ func goModuleRoot(dir string) (string, bool) {
|
||||
}
|
||||
|
||||
if content, err := os.ReadFile(filepath.Join(modDir, "go.mod")); err == nil {
|
||||
moduleName := string(modregex.FindSubmatch(content)[1])
|
||||
moduleName := extractModuleName(content)
|
||||
result = goModuleSearchResult{
|
||||
path: moduleName,
|
||||
goModPath: modDir,
|
||||
@ -126,6 +128,27 @@ func goModuleRoot(dir string) (string, bool) {
|
||||
return res.path, true
|
||||
}
|
||||
|
||||
func extractModuleName(content []byte) string {
|
||||
for {
|
||||
advance, tkn, err := bufio.ScanLines(content, false)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error parsing mod file: %w", err))
|
||||
}
|
||||
if advance == 0 {
|
||||
break
|
||||
}
|
||||
s := strings.Trim(string(tkn), " \t")
|
||||
if len(s) != 0 && !strings.HasPrefix(s, "//") {
|
||||
break
|
||||
}
|
||||
if advance <= len(content) {
|
||||
content = content[advance:]
|
||||
}
|
||||
}
|
||||
moduleName := string(modregex.FindSubmatch(content)[1])
|
||||
return moduleName
|
||||
}
|
||||
|
||||
// ImportPathForDir takes a path and returns a golang import path for the package
|
||||
func ImportPathForDir(dir string) (res string) {
|
||||
dir, err := filepath.Abs(dir)
|
||||
|
||||
12
vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go
generated
vendored
12
vendor/github.com/99designs/gqlgen/plugin/federation/fieldset/fieldset.go
generated
vendored
@ -11,15 +11,12 @@ import (
|
||||
|
||||
// Set represents a FieldSet that is used in federation directives @key and @requires.
|
||||
// Would be happier to reuse FieldSet parsing from gqlparser, but this suits for now.
|
||||
//
|
||||
type Set []Field
|
||||
|
||||
// Field represents a single field in a FieldSet
|
||||
//
|
||||
type Field []string
|
||||
|
||||
// New parses a FieldSet string into a TinyFieldSet.
|
||||
//
|
||||
func New(raw string, prefix []string) Set {
|
||||
if !strings.Contains(raw, "{") {
|
||||
return parseUnnestedKeyFieldSet(raw, prefix)
|
||||
@ -48,7 +45,6 @@ func New(raw string, prefix []string) Set {
|
||||
}
|
||||
|
||||
// FieldDefinition looks up a field in the type.
|
||||
//
|
||||
func (f Field) FieldDefinition(schemaType *ast.Definition, schema *ast.Schema) *ast.FieldDefinition {
|
||||
objType := schemaType
|
||||
def := objType.Fields.ForName(f[0])
|
||||
@ -74,7 +70,6 @@ func (f Field) FieldDefinition(schemaType *ast.Definition, schema *ast.Schema) *
|
||||
}
|
||||
|
||||
// TypeReference looks up the type of a field.
|
||||
//
|
||||
func (f Field) TypeReference(obj *codegen.Object, objects codegen.Objects) *codegen.Field {
|
||||
var def *codegen.Field
|
||||
|
||||
@ -89,7 +84,6 @@ func (f Field) TypeReference(obj *codegen.Object, objects codegen.Objects) *code
|
||||
}
|
||||
|
||||
// ToGo converts a (possibly nested) field into a proper public Go name.
|
||||
//
|
||||
func (f Field) ToGo() string {
|
||||
var ret string
|
||||
|
||||
@ -100,7 +94,6 @@ func (f Field) ToGo() string {
|
||||
}
|
||||
|
||||
// ToGoPrivate converts a (possibly nested) field into a proper private Go name.
|
||||
//
|
||||
func (f Field) ToGoPrivate() string {
|
||||
var ret string
|
||||
|
||||
@ -115,13 +108,11 @@ func (f Field) ToGoPrivate() string {
|
||||
}
|
||||
|
||||
// Join concatenates the field parts with a string separator between. Useful in templates.
|
||||
//
|
||||
func (f Field) Join(str string) string {
|
||||
return strings.Join(f, str)
|
||||
}
|
||||
|
||||
// JoinGo concatenates the Go name of field parts with a string separator between. Useful in templates.
|
||||
//
|
||||
func (f Field) JoinGo(str string) string {
|
||||
strs := []string{}
|
||||
|
||||
@ -138,7 +129,6 @@ func (f Field) LastIndex() int {
|
||||
// local functions
|
||||
|
||||
// parseUnnestedKeyFieldSet // handles simple case where none of the fields are nested.
|
||||
//
|
||||
func parseUnnestedKeyFieldSet(raw string, prefix []string) Set {
|
||||
ret := Set{}
|
||||
|
||||
@ -150,7 +140,6 @@ func parseUnnestedKeyFieldSet(raw string, prefix []string) Set {
|
||||
}
|
||||
|
||||
// extractSubs splits out and trims sub-expressions from before, inside, and after "{}".
|
||||
//
|
||||
func extractSubs(str string) (string, string, string) {
|
||||
start := strings.Index(str, "{")
|
||||
end := matchingBracketIndex(str, start)
|
||||
@ -162,7 +151,6 @@ func extractSubs(str string) (string, string, string) {
|
||||
}
|
||||
|
||||
// matchingBracketIndex returns the index of the closing bracket, assuming an open bracket at start.
|
||||
//
|
||||
func matchingBracketIndex(str string, start int) int {
|
||||
if start < 0 || len(str) <= start+1 {
|
||||
return -1
|
||||
|
||||
256
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
generated
vendored
256
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
||||
"go/types"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
@ -40,6 +41,7 @@ type ModelBuild struct {
|
||||
type Interface struct {
|
||||
Description string
|
||||
Name string
|
||||
Fields []*Field
|
||||
Implements []string
|
||||
}
|
||||
|
||||
@ -90,7 +92,6 @@ func (m *Plugin) Name() string {
|
||||
}
|
||||
|
||||
func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
binder := cfg.NewBinder()
|
||||
|
||||
b := &ModelBuild{
|
||||
PackageName: cfg.Model.Package,
|
||||
@ -102,10 +103,16 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
}
|
||||
switch schemaType.Kind {
|
||||
case ast.Interface, ast.Union:
|
||||
fields, err := m.generateFields(cfg, schemaType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
it := &Interface{
|
||||
Description: schemaType.Description,
|
||||
Name: schemaType.Name,
|
||||
Implements: schemaType.Interfaces,
|
||||
Fields: fields,
|
||||
}
|
||||
|
||||
b.Interfaces = append(b.Interfaces, it)
|
||||
@ -113,9 +120,16 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
if schemaType == cfg.Schema.Query || schemaType == cfg.Schema.Mutation || schemaType == cfg.Schema.Subscription {
|
||||
continue
|
||||
}
|
||||
|
||||
fields, err := m.generateFields(cfg, schemaType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
it := &Object{
|
||||
Description: schemaType.Description,
|
||||
Name: schemaType.Name,
|
||||
Fields: fields,
|
||||
}
|
||||
|
||||
// If Interface A implements interface B, and Interface C also implements interface B
|
||||
@ -136,87 +150,6 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
for _, field := range schemaType.Fields {
|
||||
var typ types.Type
|
||||
fieldDef := cfg.Schema.Types[field.Type.Name()]
|
||||
|
||||
if cfg.Models.UserDefined(field.Type.Name()) {
|
||||
var err error
|
||||
typ, err = binder.FindTypeFromName(cfg.Models[field.Type.Name()].Model[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
switch fieldDef.Kind {
|
||||
case ast.Scalar:
|
||||
// no user defined model, referencing a default scalar
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), "string", nil),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Interface, ast.Union:
|
||||
// no user defined model, referencing a generated interface type
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
types.NewInterfaceType([]*types.Func{}, []types.Type{}),
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Enum:
|
||||
// no user defined model, must reference a generated enum
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Object, ast.InputObject:
|
||||
// no user defined model, must reference a generated struct
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
types.NewStruct(nil, nil),
|
||||
nil,
|
||||
)
|
||||
|
||||
default:
|
||||
panic(fmt.Errorf("unknown ast type %s", fieldDef.Kind))
|
||||
}
|
||||
}
|
||||
|
||||
name := templates.ToGo(field.Name)
|
||||
if nameOveride := cfg.Models[schemaType.Name].Fields[field.Name].FieldName; nameOveride != "" {
|
||||
name = nameOveride
|
||||
}
|
||||
|
||||
typ = binder.CopyModifiersFromAst(field.Type, typ)
|
||||
|
||||
if cfg.StructFieldsAlwaysPointers {
|
||||
if isStruct(typ) && (fieldDef.Kind == ast.Object || fieldDef.Kind == ast.InputObject) {
|
||||
typ = types.NewPointer(typ)
|
||||
}
|
||||
}
|
||||
|
||||
f := &Field{
|
||||
Name: field.Name,
|
||||
GoName: name,
|
||||
Type: typ,
|
||||
Description: field.Description,
|
||||
Tag: `json:"` + field.Name + `"`,
|
||||
}
|
||||
|
||||
if m.FieldHook != nil {
|
||||
mf, err := m.FieldHook(schemaType, field, f)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generror: field %v.%v: %w", it.Name, field.Name, err)
|
||||
}
|
||||
f = mf
|
||||
}
|
||||
|
||||
it.Fields = append(it.Fields, f)
|
||||
}
|
||||
|
||||
b.Models = append(b.Models, it)
|
||||
case ast.Enum:
|
||||
it := &Enum{
|
||||
@ -267,6 +200,76 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
b = m.MutateHook(b)
|
||||
}
|
||||
|
||||
getInterfaceByName := func(name string) *Interface {
|
||||
// Allow looking up interfaces, so template can generate getters for each field
|
||||
for _, i := range b.Interfaces {
|
||||
if i.Name == name {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
gettersGenerated := make(map[string]map[string]struct{})
|
||||
generateGetter := func(model *Object, field *Field) string {
|
||||
if model == nil || field == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Let templates check if a given getter has been generated already
|
||||
typeGetters, exists := gettersGenerated[model.Name]
|
||||
if !exists {
|
||||
typeGetters = make(map[string]struct{})
|
||||
gettersGenerated[model.Name] = typeGetters
|
||||
}
|
||||
|
||||
_, exists = typeGetters[field.GoName]
|
||||
typeGetters[field.GoName] = struct{}{}
|
||||
if exists {
|
||||
return ""
|
||||
}
|
||||
|
||||
_, interfaceFieldTypeIsPointer := field.Type.(*types.Pointer)
|
||||
var structFieldTypeIsPointer bool
|
||||
for _, f := range model.Fields {
|
||||
if f.GoName == field.GoName {
|
||||
_, structFieldTypeIsPointer = f.Type.(*types.Pointer)
|
||||
break
|
||||
}
|
||||
}
|
||||
goType := templates.CurrentImports.LookupType(field.Type)
|
||||
if strings.HasPrefix(goType, "[]") {
|
||||
getter := fmt.Sprintf("func (this %s) Get%s() %s {\n", templates.ToGo(model.Name), field.GoName, goType)
|
||||
getter += fmt.Sprintf("\tif this.%s == nil { return nil }\n", field.GoName)
|
||||
getter += fmt.Sprintf("\tinterfaceSlice := make(%s, 0, len(this.%s))\n", goType, field.GoName)
|
||||
getter += fmt.Sprintf("\tfor _, concrete := range this.%s { interfaceSlice = append(interfaceSlice, ", field.GoName)
|
||||
if interfaceFieldTypeIsPointer && !structFieldTypeIsPointer {
|
||||
getter += "&"
|
||||
} else if !interfaceFieldTypeIsPointer && structFieldTypeIsPointer {
|
||||
getter += "*"
|
||||
}
|
||||
getter += "concrete) }\n"
|
||||
getter += "\treturn interfaceSlice\n"
|
||||
getter += "}"
|
||||
return getter
|
||||
} else {
|
||||
getter := fmt.Sprintf("func (this %s) Get%s() %s { return ", templates.ToGo(model.Name), field.GoName, goType)
|
||||
|
||||
if interfaceFieldTypeIsPointer && !structFieldTypeIsPointer {
|
||||
getter += "&"
|
||||
} else if !interfaceFieldTypeIsPointer && structFieldTypeIsPointer {
|
||||
getter += "*"
|
||||
}
|
||||
|
||||
getter += fmt.Sprintf("this.%s }", field.GoName)
|
||||
return getter
|
||||
}
|
||||
}
|
||||
funcMap := template.FuncMap{
|
||||
"getInterfaceByName": getInterfaceByName,
|
||||
"generateGetter": generateGetter,
|
||||
}
|
||||
|
||||
err := templates.Render(templates.Options{
|
||||
PackageName: cfg.Model.Package,
|
||||
Filename: cfg.Model.Filename,
|
||||
@ -274,6 +277,7 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
GeneratedHeader: true,
|
||||
Packages: cfg.Packages,
|
||||
Template: modelTemplate,
|
||||
Funcs: funcMap,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -286,6 +290,94 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Plugin) generateFields(cfg *config.Config, schemaType *ast.Definition) ([]*Field, error) {
|
||||
binder := cfg.NewBinder()
|
||||
fields := make([]*Field, 0)
|
||||
|
||||
for _, field := range schemaType.Fields {
|
||||
var typ types.Type
|
||||
fieldDef := cfg.Schema.Types[field.Type.Name()]
|
||||
|
||||
if cfg.Models.UserDefined(field.Type.Name()) {
|
||||
var err error
|
||||
typ, err = binder.FindTypeFromName(cfg.Models[field.Type.Name()].Model[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
switch fieldDef.Kind {
|
||||
case ast.Scalar:
|
||||
// no user defined model, referencing a default scalar
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), "string", nil),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Interface, ast.Union:
|
||||
// no user defined model, referencing a generated interface type
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
types.NewInterfaceType([]*types.Func{}, []types.Type{}),
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Enum:
|
||||
// no user defined model, must reference a generated enum
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Object, ast.InputObject:
|
||||
// no user defined model, must reference a generated struct
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
types.NewStruct(nil, nil),
|
||||
nil,
|
||||
)
|
||||
|
||||
default:
|
||||
panic(fmt.Errorf("unknown ast type %s", fieldDef.Kind))
|
||||
}
|
||||
}
|
||||
|
||||
name := templates.ToGo(field.Name)
|
||||
if nameOveride := cfg.Models[schemaType.Name].Fields[field.Name].FieldName; nameOveride != "" {
|
||||
name = nameOveride
|
||||
}
|
||||
|
||||
typ = binder.CopyModifiersFromAst(field.Type, typ)
|
||||
|
||||
if cfg.StructFieldsAlwaysPointers {
|
||||
if isStruct(typ) && (fieldDef.Kind == ast.Object || fieldDef.Kind == ast.InputObject) {
|
||||
typ = types.NewPointer(typ)
|
||||
}
|
||||
}
|
||||
|
||||
f := &Field{
|
||||
Name: field.Name,
|
||||
GoName: name,
|
||||
Type: typ,
|
||||
Description: field.Description,
|
||||
Tag: `json:"` + field.Name + `"`,
|
||||
}
|
||||
|
||||
if m.FieldHook != nil {
|
||||
mf, err := m.FieldHook(schemaType, field, f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generror: field %v.%v: %w", schemaType.Name, field.Name, err)
|
||||
}
|
||||
f = mf
|
||||
}
|
||||
|
||||
fields = append(fields, f)
|
||||
}
|
||||
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
// GoTagFieldHook applies the goTag directive to the generated Field f. When applying the Tag to the field, the field
|
||||
// name is used when no value argument is present.
|
||||
func GoTagFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) {
|
||||
|
||||
48
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl
generated
vendored
48
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl
generated
vendored
@ -14,17 +14,23 @@
|
||||
|
||||
{{- range $model := .Interfaces }}
|
||||
{{ with .Description }} {{.|prefixLines "// "}} {{ end }}
|
||||
type {{.Name|go }} interface {
|
||||
type {{ goModelName .Name }} interface {
|
||||
{{- range $impl := .Implements }}
|
||||
{{ $impl|go }}
|
||||
Is{{ goModelName $impl }}()
|
||||
{{- end }}
|
||||
Is{{ goModelName .Name }}()
|
||||
{{- range $field := .Fields }}
|
||||
{{- with .Description }}
|
||||
{{.|prefixLines "// "}}
|
||||
{{- end}}
|
||||
Get{{ $field.GoName }}() {{ $field.Type | ref }}
|
||||
{{- end }}
|
||||
Is{{.Name|go }}()
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{ range $model := .Models }}
|
||||
{{with .Description }} {{.|prefixLines "// "}} {{end}}
|
||||
type {{ .Name|go }} struct {
|
||||
type {{ goModelName .Name }} struct {
|
||||
{{- range $field := .Fields }}
|
||||
{{- with .Description }}
|
||||
{{.|prefixLines "// "}}
|
||||
@ -33,55 +39,63 @@
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
{{- range $iface := .Implements }}
|
||||
func ({{ $model.Name|go }}) Is{{ $iface|go }}() {}
|
||||
{{- end }}
|
||||
{{ range .Implements }}
|
||||
func ({{ goModelName $model.Name }}) Is{{ goModelName . }}() {}
|
||||
{{- with getInterfaceByName . }}
|
||||
{{- range .Fields }}
|
||||
{{- with .Description }}
|
||||
{{.|prefixLines "// "}}
|
||||
{{- end}}
|
||||
{{ generateGetter $model . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{- end}}
|
||||
|
||||
{{ range $enum := .Enums }}
|
||||
{{ with .Description }} {{.|prefixLines "// "}} {{end}}
|
||||
type {{.Name|go }} string
|
||||
type {{ goModelName .Name }} string
|
||||
const (
|
||||
{{- range $value := .Values}}
|
||||
{{- with .Description}}
|
||||
{{.|prefixLines "// "}}
|
||||
{{- end}}
|
||||
{{ $enum.Name|go }}{{ .Name|go }} {{$enum.Name|go }} = {{.Name|quote}}
|
||||
{{ goModelName $enum.Name .Name }} {{ goModelName $enum.Name }} = {{ .Name|quote }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
var All{{.Name|go }} = []{{ .Name|go }}{
|
||||
var All{{ goModelName .Name }} = []{{ goModelName .Name }}{
|
||||
{{- range $value := .Values}}
|
||||
{{$enum.Name|go }}{{ .Name|go }},
|
||||
{{ goModelName $enum.Name .Name }},
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func (e {{.Name|go }}) IsValid() bool {
|
||||
func (e {{ goModelName .Name }}) IsValid() bool {
|
||||
switch e {
|
||||
case {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.Name|go }}{{ $element.Name|go }}{{end}}:
|
||||
case {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ goModelName $enum.Name $element.Name }}{{end}}:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (e {{.Name|go }}) String() string {
|
||||
func (e {{ goModelName .Name }}) String() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func (e *{{.Name|go }}) UnmarshalGQL(v interface{}) error {
|
||||
func (e *{{ goModelName .Name }}) UnmarshalGQL(v interface{}) error {
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("enums must be strings")
|
||||
}
|
||||
|
||||
*e = {{ .Name|go }}(str)
|
||||
*e = {{ goModelName .Name }}(str)
|
||||
if !e.IsValid() {
|
||||
return fmt.Errorf("%s is not a valid {{ .Name }}", str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e {{.Name|go }}) MarshalGQL(w io.Writer) {
|
||||
func (e {{ goModelName .Name }}) MarshalGQL(w io.Writer) {
|
||||
fmt.Fprint(w, strconv.Quote(e.String()))
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
generated
vendored
@ -120,7 +120,7 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error {
|
||||
implementation := strings.TrimSpace(rewriter.GetMethodBody(structName, f.GoFieldName))
|
||||
comment := strings.TrimSpace(strings.TrimLeft(rewriter.GetMethodComment(structName, f.GoFieldName), `\`))
|
||||
if implementation == "" {
|
||||
implementation = `panic(fmt.Errorf("not implemented"))`
|
||||
implementation = fmt.Sprintf("panic(fmt.Errorf(\"not implemented: %v - %v\"))", f.GoFieldName, f.Name)
|
||||
}
|
||||
if comment == "" {
|
||||
comment = fmt.Sprintf("%v is the resolver for the %v field.", f.GoFieldName, f.Name)
|
||||
|
||||
8
vendor/github.com/99designs/gqlgen/tools.go
generated
vendored
8
vendor/github.com/99designs/gqlgen/tools.go
generated
vendored
@ -1,8 +0,0 @@
|
||||
//go:build tools
|
||||
// +build tools
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "github.com/matryer/moq"
|
||||
)
|
||||
31
vendor/github.com/go-openapi/spec/.travis.yml
generated
vendored
31
vendor/github.com/go-openapi/spec/.travis.yml
generated
vendored
@ -1,31 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.16.x
|
||||
- 1.x
|
||||
arch:
|
||||
- amd64
|
||||
jobs:
|
||||
include:
|
||||
# only run fast tests on ppc64le
|
||||
- go: 1.x
|
||||
arch: ppc64le
|
||||
script:
|
||||
- gotestsum -f short-verbose -- ./...
|
||||
|
||||
# include linting job, but only for latest go version and amd64 arch
|
||||
- go: 1.x
|
||||
arch: amd64
|
||||
install:
|
||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
script:
|
||||
- golangci-lint run --new-from-rev master
|
||||
|
||||
install:
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
11
vendor/github.com/go-openapi/spec/normalizer.go
generated
vendored
11
vendor/github.com/go-openapi/spec/normalizer.go
generated
vendored
@ -40,7 +40,7 @@ const fileScheme = "file"
|
||||
//
|
||||
// The base path argument is assumed to be canonicalized (e.g. using normalizeBase()).
|
||||
func normalizeURI(refPath, base string) string {
|
||||
refURL, err := url.Parse(refPath)
|
||||
refURL, err := parseURL(refPath)
|
||||
if err != nil {
|
||||
specLogger.Printf("warning: invalid URI in $ref %q: %v", refPath, err)
|
||||
refURL, refPath = repairURI(refPath)
|
||||
@ -58,7 +58,7 @@ func normalizeURI(refPath, base string) string {
|
||||
return refURL.String()
|
||||
}
|
||||
|
||||
baseURL, _ := url.Parse(base)
|
||||
baseURL, _ := parseURL(base)
|
||||
if path.IsAbs(refURL.Path) {
|
||||
baseURL.Path = refURL.Path
|
||||
} else if refURL.Path != "" {
|
||||
@ -84,7 +84,6 @@ func normalizeURI(refPath, base string) string {
|
||||
// There is a special case for schemas that are anchored with an "id":
|
||||
// in that case, the rebasing is performed // against the id only if this is an anchor for the initial root document.
|
||||
// All other intermediate "id"'s found along the way are ignored for the purpose of rebasing.
|
||||
//
|
||||
func denormalizeRef(ref *Ref, originalRelativeBase, id string) Ref {
|
||||
debugLog("denormalizeRef called:\n$ref: %q\noriginal: %s\nroot ID:%s", ref.String(), originalRelativeBase, id)
|
||||
|
||||
@ -94,7 +93,7 @@ func denormalizeRef(ref *Ref, originalRelativeBase, id string) Ref {
|
||||
}
|
||||
|
||||
if id != "" {
|
||||
idBaseURL, err := url.Parse(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 unchaged (do not want $ref: "")
|
||||
// $ref relative to the ID of the schema in the root document
|
||||
@ -103,7 +102,7 @@ func denormalizeRef(ref *Ref, originalRelativeBase, id string) Ref {
|
||||
}
|
||||
}
|
||||
|
||||
originalRelativeBaseURL, _ := url.Parse(originalRelativeBase)
|
||||
originalRelativeBaseURL, _ := parseURL(originalRelativeBase)
|
||||
|
||||
r, _ := rebase(ref, originalRelativeBaseURL, false)
|
||||
|
||||
@ -168,7 +167,7 @@ func normalizeRef(ref *Ref, relativeBase string) *Ref {
|
||||
//
|
||||
// See also: https://en.wikipedia.org/wiki/File_URI_scheme
|
||||
func normalizeBase(in string) string {
|
||||
u, err := url.Parse(in)
|
||||
u, err := parseURL(in)
|
||||
if err != nil {
|
||||
specLogger.Printf("warning: invalid URI in RelativeBase %q: %v", in, err)
|
||||
u, in = repairURI(in)
|
||||
|
||||
3
vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
generated
vendored
3
vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
@ -34,7 +35,7 @@ func absPath(in string) string {
|
||||
}
|
||||
|
||||
func repairURI(in string) (*url.URL, string) {
|
||||
u, _ := url.Parse("")
|
||||
u, _ := parseURL("")
|
||||
debugLog("repaired URI: original: %q, repaired: %q", in, "")
|
||||
return u, ""
|
||||
}
|
||||
|
||||
4
vendor/github.com/go-openapi/spec/normalizer_windows.go
generated
vendored
4
vendor/github.com/go-openapi/spec/normalizer_windows.go
generated
vendored
@ -60,13 +60,13 @@ func repairURI(in string) (*url.URL, string) {
|
||||
const prefix = fileScheme + "://"
|
||||
if !strings.HasPrefix(in, prefix) {
|
||||
// giving up: resolve to empty path
|
||||
u, _ := url.Parse("")
|
||||
u, _ := parseURL("")
|
||||
|
||||
return u, ""
|
||||
}
|
||||
|
||||
// attempt the repair, stripping the scheme should be sufficient
|
||||
u, _ := url.Parse(strings.TrimPrefix(in, prefix))
|
||||
u, _ := parseURL(strings.TrimPrefix(in, prefix))
|
||||
debugLog("repaired URI: original: %q, repaired: %q", in, u.String())
|
||||
|
||||
return u, u.String()
|
||||
|
||||
3
vendor/github.com/go-openapi/spec/schema.go
generated
vendored
3
vendor/github.com/go-openapi/spec/schema.go
generated
vendored
@ -17,7 +17,6 @@ package spec
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
@ -145,7 +144,7 @@ func (r *SchemaURL) fromMap(v map[string]interface{}) error {
|
||||
}
|
||||
if vv, ok := v["$schema"]; ok {
|
||||
if str, ok := vv.(string); ok {
|
||||
u, err := url.Parse(str)
|
||||
u, err := parseURL(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
8
vendor/github.com/go-openapi/spec/url_go18.go
generated
vendored
Normal file
8
vendor/github.com/go-openapi/spec/url_go18.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
//go:build !go1.19
|
||||
// +build !go1.19
|
||||
|
||||
package spec
|
||||
|
||||
import "net/url"
|
||||
|
||||
var parseURL = url.Parse
|
||||
14
vendor/github.com/go-openapi/spec/url_go19.go
generated
vendored
Normal file
14
vendor/github.com/go-openapi/spec/url_go19.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
//go:build go1.19
|
||||
// +build go1.19
|
||||
|
||||
package spec
|
||||
|
||||
import "net/url"
|
||||
|
||||
func parseURL(s string) (*url.URL, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err == nil {
|
||||
u.OmitHost = false
|
||||
}
|
||||
return u, err
|
||||
}
|
||||
4
vendor/github.com/go-openapi/swag/.golangci.yml
generated
vendored
4
vendor/github.com/go-openapi/swag/.golangci.yml
generated
vendored
@ -48,3 +48,7 @@ linters:
|
||||
- goimports
|
||||
- tenv
|
||||
- golint
|
||||
- exhaustruct
|
||||
- nilnil
|
||||
- nonamedreturns
|
||||
- nosnakecase
|
||||
|
||||
15
vendor/github.com/go-openapi/swag/doc.go
generated
vendored
15
vendor/github.com/go-openapi/swag/doc.go
generated
vendored
@ -17,16 +17,15 @@ Package swag contains a bunch of helper functions for go-openapi and go-swagger
|
||||
|
||||
You may also use it standalone for your projects.
|
||||
|
||||
* convert between value and pointers for builtin types
|
||||
* convert from string to builtin types (wraps strconv)
|
||||
* fast json concatenation
|
||||
* search in path
|
||||
* load from file or http
|
||||
* name mangling
|
||||
|
||||
- convert between value and pointers for builtin types
|
||||
- convert from string to builtin types (wraps strconv)
|
||||
- fast json concatenation
|
||||
- search in path
|
||||
- load from file or http
|
||||
- name mangling
|
||||
|
||||
This repo has only few dependencies outside of the standard library:
|
||||
|
||||
* YAML utilities depend on gopkg.in/yaml.v2
|
||||
- YAML utilities depend on gopkg.in/yaml.v2
|
||||
*/
|
||||
package swag
|
||||
|
||||
11
vendor/github.com/go-openapi/swag/loading.go
generated
vendored
11
vendor/github.com/go-openapi/swag/loading.go
generated
vendored
@ -16,10 +16,11 @@ package swag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@ -40,13 +41,13 @@ var LoadHTTPCustomHeaders = map[string]string{}
|
||||
|
||||
// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
|
||||
func LoadFromFileOrHTTP(path string) ([]byte, error) {
|
||||
return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
|
||||
return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
|
||||
}
|
||||
|
||||
// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in
|
||||
// timeout arg allows for per request overriding of the request timeout
|
||||
func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) {
|
||||
return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(timeout))(path)
|
||||
return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path)
|
||||
}
|
||||
|
||||
// LoadStrategy returns a loader function for a given path or uri
|
||||
@ -86,7 +87,7 @@ func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(
|
||||
func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) {
|
||||
return func(path string) ([]byte, error) {
|
||||
client := &http.Client{Timeout: timeout}
|
||||
req, err := http.NewRequest("GET", path, nil) // nolint: noctx
|
||||
req, err := http.NewRequest(http.MethodGet, path, nil) //nolint:noctx
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -115,6 +116,6 @@ func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) {
|
||||
return nil, fmt.Errorf("could not access document at %q [%s] ", path, resp.Status)
|
||||
}
|
||||
|
||||
return ioutil.ReadAll(resp.Body)
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
}
|
||||
|
||||
17
vendor/github.com/go-openapi/swag/util.go
generated
vendored
17
vendor/github.com/go-openapi/swag/util.go
generated
vendored
@ -99,10 +99,11 @@ const (
|
||||
)
|
||||
|
||||
// JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute):
|
||||
// ssv: space separated value
|
||||
// tsv: tab separated value
|
||||
// pipes: pipe (|) separated value
|
||||
// csv: comma separated value (default)
|
||||
//
|
||||
// ssv: space separated value
|
||||
// tsv: tab separated value
|
||||
// pipes: pipe (|) separated value
|
||||
// csv: comma separated value (default)
|
||||
func JoinByFormat(data []string, format string) []string {
|
||||
if len(data) == 0 {
|
||||
return data
|
||||
@ -124,11 +125,11 @@ func JoinByFormat(data []string, format string) []string {
|
||||
}
|
||||
|
||||
// SplitByFormat splits a string by a known format:
|
||||
// ssv: space separated value
|
||||
// tsv: tab separated value
|
||||
// pipes: pipe (|) separated value
|
||||
// csv: comma separated value (default)
|
||||
//
|
||||
// ssv: space separated value
|
||||
// tsv: tab separated value
|
||||
// pipes: pipe (|) separated value
|
||||
// csv: comma separated value (default)
|
||||
func SplitByFormat(data, format string) []string {
|
||||
if data == "" {
|
||||
return nil
|
||||
|
||||
254
vendor/github.com/go-openapi/swag/yaml.go
generated
vendored
254
vendor/github.com/go-openapi/swag/yaml.go
generated
vendored
@ -22,7 +22,7 @@ import (
|
||||
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
"github.com/mailru/easyjson/jwriter"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// YAMLMatcher matches yaml
|
||||
@ -43,16 +43,126 @@ func YAMLToJSON(data interface{}) (json.RawMessage, error) {
|
||||
|
||||
// BytesToYAMLDoc converts a byte slice into a YAML document
|
||||
func BytesToYAMLDoc(data []byte) (interface{}, error) {
|
||||
var canary map[interface{}]interface{} // validate this is an object and not a different type
|
||||
if err := yaml.Unmarshal(data, &canary); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var document yaml.MapSlice // preserve order that is present in the document
|
||||
var document yaml.Node // preserve order that is present in the document
|
||||
if err := yaml.Unmarshal(data, &document); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return document, nil
|
||||
if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode {
|
||||
return nil, fmt.Errorf("only YAML documents that are objects are supported")
|
||||
}
|
||||
return &document, nil
|
||||
}
|
||||
|
||||
func yamlNode(root *yaml.Node) (interface{}, error) {
|
||||
switch root.Kind {
|
||||
case yaml.DocumentNode:
|
||||
return yamlDocument(root)
|
||||
case yaml.SequenceNode:
|
||||
return yamlSequence(root)
|
||||
case yaml.MappingNode:
|
||||
return yamlMapping(root)
|
||||
case yaml.ScalarNode:
|
||||
return yamlScalar(root)
|
||||
case yaml.AliasNode:
|
||||
return yamlNode(root.Alias)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported YAML node type: %v", root.Kind)
|
||||
}
|
||||
}
|
||||
|
||||
func yamlDocument(node *yaml.Node) (interface{}, error) {
|
||||
if len(node.Content) != 1 {
|
||||
return nil, fmt.Errorf("unexpected YAML Document node content length: %d", len(node.Content))
|
||||
}
|
||||
return yamlNode(node.Content[0])
|
||||
}
|
||||
|
||||
func yamlMapping(node *yaml.Node) (interface{}, error) {
|
||||
m := make(JSONMapSlice, len(node.Content)/2)
|
||||
|
||||
var j int
|
||||
for i := 0; i < len(node.Content); i += 2 {
|
||||
var nmi JSONMapItem
|
||||
k, err := yamlStringScalarC(node.Content[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to decode YAML map key: %w", err)
|
||||
}
|
||||
nmi.Key = k
|
||||
v, err := yamlNode(node.Content[i+1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to process YAML map value for key %q: %w", k, err)
|
||||
}
|
||||
nmi.Value = v
|
||||
m[j] = nmi
|
||||
j++
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func yamlSequence(node *yaml.Node) (interface{}, error) {
|
||||
s := make([]interface{}, 0)
|
||||
|
||||
for i := 0; i < len(node.Content); i++ {
|
||||
|
||||
v, err := yamlNode(node.Content[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to decode YAML sequence value: %w", err)
|
||||
}
|
||||
s = append(s, v)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
const ( // See https://yaml.org/type/
|
||||
yamlStringScalar = "tag:yaml.org,2002:str"
|
||||
yamlIntScalar = "tag:yaml.org,2002:int"
|
||||
yamlBoolScalar = "tag:yaml.org,2002:bool"
|
||||
yamlFloatScalar = "tag:yaml.org,2002:float"
|
||||
yamlTimestamp = "tag:yaml.org,2002:timestamp"
|
||||
yamlNull = "tag:yaml.org,2002:null"
|
||||
)
|
||||
|
||||
func yamlScalar(node *yaml.Node) (interface{}, error) {
|
||||
switch node.LongTag() {
|
||||
case yamlStringScalar:
|
||||
return node.Value, nil
|
||||
case yamlBoolScalar:
|
||||
b, err := strconv.ParseBool(node.Value)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting bool content: %w", node.Value, err)
|
||||
}
|
||||
return b, nil
|
||||
case yamlIntScalar:
|
||||
i, err := strconv.ParseInt(node.Value, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting integer content: %w", node.Value, err)
|
||||
}
|
||||
return i, nil
|
||||
case yamlFloatScalar:
|
||||
f, err := strconv.ParseFloat(node.Value, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting float content: %w", node.Value, err)
|
||||
}
|
||||
return f, nil
|
||||
case yamlTimestamp:
|
||||
return node.Value, nil
|
||||
case yamlNull:
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag())
|
||||
}
|
||||
}
|
||||
|
||||
func yamlStringScalarC(node *yaml.Node) (string, error) {
|
||||
if node.Kind != yaml.ScalarNode {
|
||||
return "", fmt.Errorf("expecting a string scalar but got %q", node.Kind)
|
||||
}
|
||||
switch node.LongTag() {
|
||||
case yamlStringScalar, yamlIntScalar, yamlFloatScalar:
|
||||
return node.Value, nil
|
||||
default:
|
||||
return "", fmt.Errorf("YAML tag %q is not supported as map key", node.LongTag())
|
||||
}
|
||||
}
|
||||
|
||||
// JSONMapSlice represent a JSON object, with the order of keys maintained
|
||||
@ -105,6 +215,113 @@ func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
||||
*s = result
|
||||
}
|
||||
|
||||
func (s JSONMapSlice) MarshalYAML() (interface{}, error) {
|
||||
var n yaml.Node
|
||||
n.Kind = yaml.DocumentNode
|
||||
var nodes []*yaml.Node
|
||||
for _, item := range s {
|
||||
nn, err := json2yaml(item.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ns := []*yaml.Node{
|
||||
{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: yamlStringScalar,
|
||||
Value: item.Key,
|
||||
},
|
||||
nn,
|
||||
}
|
||||
nodes = append(nodes, ns...)
|
||||
}
|
||||
|
||||
n.Content = []*yaml.Node{
|
||||
{
|
||||
Kind: yaml.MappingNode,
|
||||
Content: nodes,
|
||||
},
|
||||
}
|
||||
|
||||
return yaml.Marshal(&n)
|
||||
}
|
||||
|
||||
func json2yaml(item interface{}) (*yaml.Node, error) {
|
||||
switch val := item.(type) {
|
||||
case JSONMapSlice:
|
||||
var n yaml.Node
|
||||
n.Kind = yaml.MappingNode
|
||||
for i := range val {
|
||||
childNode, err := json2yaml(&val[i].Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.Content = append(n.Content, &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: yamlStringScalar,
|
||||
Value: val[i].Key,
|
||||
}, childNode)
|
||||
}
|
||||
return &n, nil
|
||||
case map[string]interface{}:
|
||||
var n yaml.Node
|
||||
n.Kind = yaml.MappingNode
|
||||
for k, v := range val {
|
||||
childNode, err := json2yaml(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.Content = append(n.Content, &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: yamlStringScalar,
|
||||
Value: k,
|
||||
}, childNode)
|
||||
}
|
||||
return &n, nil
|
||||
case []interface{}:
|
||||
var n yaml.Node
|
||||
n.Kind = yaml.SequenceNode
|
||||
for i := range val {
|
||||
childNode, err := json2yaml(val[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.Content = append(n.Content, childNode)
|
||||
}
|
||||
return &n, nil
|
||||
case string:
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: yamlStringScalar,
|
||||
Value: val,
|
||||
}, nil
|
||||
case float64:
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: yamlFloatScalar,
|
||||
Value: strconv.FormatFloat(val, 'f', -1, 64),
|
||||
}, nil
|
||||
case int64:
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: yamlIntScalar,
|
||||
Value: strconv.FormatInt(val, 10),
|
||||
}, nil
|
||||
case uint64:
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: yamlIntScalar,
|
||||
Value: strconv.FormatUint(val, 10),
|
||||
}, nil
|
||||
case bool:
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: yamlBoolScalar,
|
||||
Value: strconv.FormatBool(val),
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
|
||||
type JSONMapItem struct {
|
||||
Key string
|
||||
@ -173,23 +390,10 @@ func transformData(input interface{}) (out interface{}, err error) {
|
||||
}
|
||||
|
||||
switch in := input.(type) {
|
||||
case yaml.MapSlice:
|
||||
|
||||
o := make(JSONMapSlice, len(in))
|
||||
for i, mi := range in {
|
||||
var nmi JSONMapItem
|
||||
if nmi.Key, err = format(mi.Key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v, ert := transformData(mi.Value)
|
||||
if ert != nil {
|
||||
return nil, ert
|
||||
}
|
||||
nmi.Value = v
|
||||
o[i] = nmi
|
||||
}
|
||||
return o, nil
|
||||
case yaml.Node:
|
||||
return yamlNode(&in)
|
||||
case *yaml.Node:
|
||||
return yamlNode(in)
|
||||
case map[interface{}]interface{}:
|
||||
o := make(JSONMapSlice, 0, len(in))
|
||||
for ke, va := range in {
|
||||
|
||||
31
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
31
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
@ -1,5 +1,36 @@
|
||||
# Changelog
|
||||
|
||||
## v4.8.0 - 2022-08-10
|
||||
|
||||
**Most notable things**
|
||||
|
||||
You can now add any arbitrary HTTP method type as a route [#2237](https://github.com/labstack/echo/pull/2237)
|
||||
```go
|
||||
e.Add("COPY", "/*", func(c echo.Context) error
|
||||
return c.String(http.StatusOK, "OK COPY")
|
||||
})
|
||||
```
|
||||
|
||||
You can add custom 404 handler for specific paths [#2217](https://github.com/labstack/echo/pull/2217)
|
||||
```go
|
||||
e.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })
|
||||
|
||||
g := e.Group("/images")
|
||||
g.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })
|
||||
```
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* Add new value binding methods (UnixTimeMilli,TextUnmarshaler,JSONUnmarshaler) to Valuebinder [#2127](https://github.com/labstack/echo/pull/2127)
|
||||
* Refactor: body_limit middleware unit test [#2145](https://github.com/labstack/echo/pull/2145)
|
||||
* Refactor: Timeout mw: rework how test waits for timeout. [#2187](https://github.com/labstack/echo/pull/2187)
|
||||
* BasicAuth middleware returns 500 InternalServerError on invalid base64 strings but should return 400 [#2191](https://github.com/labstack/echo/pull/2191)
|
||||
* Refactor: duplicated findStaticChild process at findChildWithLabel [#2176](https://github.com/labstack/echo/pull/2176)
|
||||
* Allow different param names in different methods with same path scheme [#2209](https://github.com/labstack/echo/pull/2209)
|
||||
* Add support for registering handlers for different 404 routes [#2217](https://github.com/labstack/echo/pull/2217)
|
||||
* Middlewares should use errors.As() instead of type assertion on HTTPError [#2227](https://github.com/labstack/echo/pull/2227)
|
||||
* Allow arbitrary HTTP method types to be added as routes [#2237](https://github.com/labstack/echo/pull/2237)
|
||||
|
||||
## v4.7.2 - 2022-03-16
|
||||
|
||||
**Fixes**
|
||||
|
||||
6
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
6
vendor/github.com/labstack/echo/v4/Makefile
generated
vendored
@ -9,7 +9,7 @@ tag:
|
||||
check: lint vet race ## Check project
|
||||
|
||||
init:
|
||||
@go get -u golang.org/x/lint/golint
|
||||
@go install golang.org/x/lint/golint@latest
|
||||
|
||||
lint: ## Lint the files
|
||||
@golint -set_exit_status ${PKG_LIST}
|
||||
@ -29,6 +29,6 @@ benchmark: ## Run benchmarks
|
||||
help: ## Display this help screen
|
||||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
goversion ?= "1.15"
|
||||
test_version: ## Run tests inside Docker with given version (defaults to 1.15 oldest supported). Example: make test_version goversion=1.15
|
||||
goversion ?= "1.16"
|
||||
test_version: ## Run tests inside Docker with given version (defaults to 1.15 oldest supported). Example: make test_version goversion=1.16
|
||||
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make init check"
|
||||
|
||||
19
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
19
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
@ -93,15 +93,16 @@ func hello(c echo.Context) error {
|
||||
|
||||
# Third-party middlewares
|
||||
|
||||
| Repository | Description |
|
||||
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | (by Echo team) [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares |
|
||||
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator |
|
||||
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0. |
|
||||
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface. |
|
||||
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface. |
|
||||
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs. |
|
||||
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo.
|
||||
| Repository | Description |
|
||||
|------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | (by Echo team) [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares |
|
||||
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator |
|
||||
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0. |
|
||||
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface. |
|
||||
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface. |
|
||||
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs. |
|
||||
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo. |
|
||||
| [github.com/go-woo/protoc-gen-echo](https://github.com/go-woo/protoc-gen-echo) | ProtoBuf generate Echo server side code |
|
||||
|
||||
Please send a PR to add your own library here.
|
||||
|
||||
|
||||
197
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
197
vendor/github.com/labstack/echo/v4/binder.go
generated
vendored
@ -1,6 +1,8 @@
|
||||
package echo
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -52,8 +54,11 @@ import (
|
||||
* time
|
||||
* duration
|
||||
* BindUnmarshaler() interface
|
||||
* TextUnmarshaler() interface
|
||||
* JSONUnmarshaler() interface
|
||||
* UnixTime() - converts unix time (integer) to time.Time
|
||||
* UnixTimeNano() - converts unix time with nano second precision (integer) to time.Time
|
||||
* UnixTimeMilli() - converts unix time with millisecond precision (integer) to time.Time
|
||||
* UnixTimeNano() - converts unix time with nanosecond precision (integer) to time.Time
|
||||
* CustomFunc() - callback function for your custom conversion logic. Signature `func(values []string) []error`
|
||||
*/
|
||||
|
||||
@ -204,7 +209,7 @@ func (b *ValueBinder) CustomFunc(sourceParam string, customFunc func(values []st
|
||||
return b.customFunc(sourceParam, customFunc, false)
|
||||
}
|
||||
|
||||
// MustCustomFunc requires parameter values to exist to be bind with Func. Returns error when value does not exist.
|
||||
// MustCustomFunc requires parameter values to exist to bind with Func. Returns error when value does not exist.
|
||||
func (b *ValueBinder) MustCustomFunc(sourceParam string, customFunc func(values []string) []error) *ValueBinder {
|
||||
return b.customFunc(sourceParam, customFunc, true)
|
||||
}
|
||||
@ -241,7 +246,7 @@ func (b *ValueBinder) String(sourceParam string, dest *string) *ValueBinder {
|
||||
return b
|
||||
}
|
||||
|
||||
// MustString requires parameter value to exist to be bind to string variable. Returns error when value does not exist
|
||||
// MustString requires parameter value to exist to bind to string variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustString(sourceParam string, dest *string) *ValueBinder {
|
||||
if b.failFast && b.errors != nil {
|
||||
return b
|
||||
@ -270,7 +275,7 @@ func (b *ValueBinder) Strings(sourceParam string, dest *[]string) *ValueBinder {
|
||||
return b
|
||||
}
|
||||
|
||||
// MustStrings requires parameter values to exist to be bind to slice of string variables. Returns error when value does not exist
|
||||
// MustStrings requires parameter values to exist to bind to slice of string variables. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustStrings(sourceParam string, dest *[]string) *ValueBinder {
|
||||
if b.failFast && b.errors != nil {
|
||||
return b
|
||||
@ -302,7 +307,7 @@ func (b *ValueBinder) BindUnmarshaler(sourceParam string, dest BindUnmarshaler)
|
||||
return b
|
||||
}
|
||||
|
||||
// MustBindUnmarshaler requires parameter value to exist to be bind to destination implementing BindUnmarshaler interface.
|
||||
// MustBindUnmarshaler requires parameter value to exist to bind to destination implementing BindUnmarshaler interface.
|
||||
// Returns error when value does not exist
|
||||
func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshaler) *ValueBinder {
|
||||
if b.failFast && b.errors != nil {
|
||||
@ -321,13 +326,85 @@ func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshal
|
||||
return b
|
||||
}
|
||||
|
||||
// JSONUnmarshaler binds parameter to destination implementing json.Unmarshaler interface
|
||||
func (b *ValueBinder) JSONUnmarshaler(sourceParam string, dest json.Unmarshaler) *ValueBinder {
|
||||
if b.failFast && b.errors != nil {
|
||||
return b
|
||||
}
|
||||
|
||||
tmp := b.ValueFunc(sourceParam)
|
||||
if tmp == "" {
|
||||
return b
|
||||
}
|
||||
|
||||
if err := dest.UnmarshalJSON([]byte(tmp)); err != nil {
|
||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to json.Unmarshaler interface", err))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// MustJSONUnmarshaler requires parameter value to exist to bind to destination implementing json.Unmarshaler interface.
|
||||
// Returns error when value does not exist
|
||||
func (b *ValueBinder) MustJSONUnmarshaler(sourceParam string, dest json.Unmarshaler) *ValueBinder {
|
||||
if b.failFast && b.errors != nil {
|
||||
return b
|
||||
}
|
||||
|
||||
tmp := b.ValueFunc(sourceParam)
|
||||
if tmp == "" {
|
||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "required field value is empty", nil))
|
||||
return b
|
||||
}
|
||||
|
||||
if err := dest.UnmarshalJSON([]byte(tmp)); err != nil {
|
||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to json.Unmarshaler interface", err))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// TextUnmarshaler binds parameter to destination implementing encoding.TextUnmarshaler interface
|
||||
func (b *ValueBinder) TextUnmarshaler(sourceParam string, dest encoding.TextUnmarshaler) *ValueBinder {
|
||||
if b.failFast && b.errors != nil {
|
||||
return b
|
||||
}
|
||||
|
||||
tmp := b.ValueFunc(sourceParam)
|
||||
if tmp == "" {
|
||||
return b
|
||||
}
|
||||
|
||||
if err := dest.UnmarshalText([]byte(tmp)); err != nil {
|
||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to encoding.TextUnmarshaler interface", err))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// MustTextUnmarshaler requires parameter value to exist to bind to destination implementing encoding.TextUnmarshaler interface.
|
||||
// Returns error when value does not exist
|
||||
func (b *ValueBinder) MustTextUnmarshaler(sourceParam string, dest encoding.TextUnmarshaler) *ValueBinder {
|
||||
if b.failFast && b.errors != nil {
|
||||
return b
|
||||
}
|
||||
|
||||
tmp := b.ValueFunc(sourceParam)
|
||||
if tmp == "" {
|
||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "required field value is empty", nil))
|
||||
return b
|
||||
}
|
||||
|
||||
if err := dest.UnmarshalText([]byte(tmp)); err != nil {
|
||||
b.setError(b.ErrorFunc(sourceParam, []string{tmp}, "failed to bind field value to encoding.TextUnmarshaler interface", err))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// BindWithDelimiter binds parameter to destination by suitable conversion function.
|
||||
// Delimiter is used before conversion to split parameter value to separate values
|
||||
func (b *ValueBinder) BindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
||||
return b.bindWithDelimiter(sourceParam, dest, delimiter, false)
|
||||
}
|
||||
|
||||
// MustBindWithDelimiter requires parameter value to exist to be bind destination by suitable conversion function.
|
||||
// MustBindWithDelimiter requires parameter value to exist to bind destination by suitable conversion function.
|
||||
// Delimiter is used before conversion to split parameter value to separate values
|
||||
func (b *ValueBinder) MustBindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
|
||||
return b.bindWithDelimiter(sourceParam, dest, delimiter, true)
|
||||
@ -376,7 +453,7 @@ func (b *ValueBinder) Int64(sourceParam string, dest *int64) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 64, false)
|
||||
}
|
||||
|
||||
// MustInt64 requires parameter value to exist to be bind to int64 variable. Returns error when value does not exist
|
||||
// MustInt64 requires parameter value to exist to bind to int64 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt64(sourceParam string, dest *int64) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 64, true)
|
||||
}
|
||||
@ -386,7 +463,7 @@ func (b *ValueBinder) Int32(sourceParam string, dest *int32) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 32, false)
|
||||
}
|
||||
|
||||
// MustInt32 requires parameter value to exist to be bind to int32 variable. Returns error when value does not exist
|
||||
// MustInt32 requires parameter value to exist to bind to int32 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt32(sourceParam string, dest *int32) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 32, true)
|
||||
}
|
||||
@ -396,7 +473,7 @@ func (b *ValueBinder) Int16(sourceParam string, dest *int16) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 16, false)
|
||||
}
|
||||
|
||||
// MustInt16 requires parameter value to exist to be bind to int16 variable. Returns error when value does not exist
|
||||
// MustInt16 requires parameter value to exist to bind to int16 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt16(sourceParam string, dest *int16) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 16, true)
|
||||
}
|
||||
@ -406,7 +483,7 @@ func (b *ValueBinder) Int8(sourceParam string, dest *int8) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 8, false)
|
||||
}
|
||||
|
||||
// MustInt8 requires parameter value to exist to be bind to int8 variable. Returns error when value does not exist
|
||||
// MustInt8 requires parameter value to exist to bind to int8 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt8(sourceParam string, dest *int8) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 8, true)
|
||||
}
|
||||
@ -416,7 +493,7 @@ func (b *ValueBinder) Int(sourceParam string, dest *int) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 0, false)
|
||||
}
|
||||
|
||||
// MustInt requires parameter value to exist to be bind to int variable. Returns error when value does not exist
|
||||
// MustInt requires parameter value to exist to bind to int variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt(sourceParam string, dest *int) *ValueBinder {
|
||||
return b.intValue(sourceParam, dest, 0, true)
|
||||
}
|
||||
@ -544,7 +621,7 @@ func (b *ValueBinder) Int64s(sourceParam string, dest *[]int64) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustInt64s requires parameter value to exist to be bind to int64 slice variable. Returns error when value does not exist
|
||||
// MustInt64s requires parameter value to exist to bind to int64 slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt64s(sourceParam string, dest *[]int64) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -554,7 +631,7 @@ func (b *ValueBinder) Int32s(sourceParam string, dest *[]int32) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustInt32s requires parameter value to exist to be bind to int32 slice variable. Returns error when value does not exist
|
||||
// MustInt32s requires parameter value to exist to bind to int32 slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt32s(sourceParam string, dest *[]int32) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -564,7 +641,7 @@ func (b *ValueBinder) Int16s(sourceParam string, dest *[]int16) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustInt16s requires parameter value to exist to be bind to int16 slice variable. Returns error when value does not exist
|
||||
// MustInt16s requires parameter value to exist to bind to int16 slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt16s(sourceParam string, dest *[]int16) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -574,7 +651,7 @@ func (b *ValueBinder) Int8s(sourceParam string, dest *[]int8) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustInt8s requires parameter value to exist to be bind to int8 slice variable. Returns error when value does not exist
|
||||
// MustInt8s requires parameter value to exist to bind to int8 slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInt8s(sourceParam string, dest *[]int8) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -584,7 +661,7 @@ func (b *ValueBinder) Ints(sourceParam string, dest *[]int) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustInts requires parameter value to exist to be bind to int slice variable. Returns error when value does not exist
|
||||
// MustInts requires parameter value to exist to bind to int slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustInts(sourceParam string, dest *[]int) *ValueBinder {
|
||||
return b.intsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -594,7 +671,7 @@ func (b *ValueBinder) Uint64(sourceParam string, dest *uint64) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 64, false)
|
||||
}
|
||||
|
||||
// MustUint64 requires parameter value to exist to be bind to uint64 variable. Returns error when value does not exist
|
||||
// MustUint64 requires parameter value to exist to bind to uint64 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint64(sourceParam string, dest *uint64) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 64, true)
|
||||
}
|
||||
@ -604,7 +681,7 @@ func (b *ValueBinder) Uint32(sourceParam string, dest *uint32) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 32, false)
|
||||
}
|
||||
|
||||
// MustUint32 requires parameter value to exist to be bind to uint32 variable. Returns error when value does not exist
|
||||
// MustUint32 requires parameter value to exist to bind to uint32 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint32(sourceParam string, dest *uint32) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 32, true)
|
||||
}
|
||||
@ -614,7 +691,7 @@ func (b *ValueBinder) Uint16(sourceParam string, dest *uint16) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 16, false)
|
||||
}
|
||||
|
||||
// MustUint16 requires parameter value to exist to be bind to uint16 variable. Returns error when value does not exist
|
||||
// MustUint16 requires parameter value to exist to bind to uint16 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint16(sourceParam string, dest *uint16) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 16, true)
|
||||
}
|
||||
@ -624,7 +701,7 @@ func (b *ValueBinder) Uint8(sourceParam string, dest *uint8) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 8, false)
|
||||
}
|
||||
|
||||
// MustUint8 requires parameter value to exist to be bind to uint8 variable. Returns error when value does not exist
|
||||
// MustUint8 requires parameter value to exist to bind to uint8 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint8(sourceParam string, dest *uint8) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 8, true)
|
||||
}
|
||||
@ -634,7 +711,7 @@ func (b *ValueBinder) Byte(sourceParam string, dest *byte) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 8, false)
|
||||
}
|
||||
|
||||
// MustByte requires parameter value to exist to be bind to byte variable. Returns error when value does not exist
|
||||
// MustByte requires parameter value to exist to bind to byte variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustByte(sourceParam string, dest *byte) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 8, true)
|
||||
}
|
||||
@ -644,7 +721,7 @@ func (b *ValueBinder) Uint(sourceParam string, dest *uint) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 0, false)
|
||||
}
|
||||
|
||||
// MustUint requires parameter value to exist to be bind to uint variable. Returns error when value does not exist
|
||||
// MustUint requires parameter value to exist to bind to uint variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint(sourceParam string, dest *uint) *ValueBinder {
|
||||
return b.uintValue(sourceParam, dest, 0, true)
|
||||
}
|
||||
@ -772,7 +849,7 @@ func (b *ValueBinder) Uint64s(sourceParam string, dest *[]uint64) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustUint64s requires parameter value to exist to be bind to uint64 slice variable. Returns error when value does not exist
|
||||
// MustUint64s requires parameter value to exist to bind to uint64 slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint64s(sourceParam string, dest *[]uint64) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -782,7 +859,7 @@ func (b *ValueBinder) Uint32s(sourceParam string, dest *[]uint32) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustUint32s requires parameter value to exist to be bind to uint32 slice variable. Returns error when value does not exist
|
||||
// MustUint32s requires parameter value to exist to bind to uint32 slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint32s(sourceParam string, dest *[]uint32) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -792,7 +869,7 @@ func (b *ValueBinder) Uint16s(sourceParam string, dest *[]uint16) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustUint16s requires parameter value to exist to be bind to uint16 slice variable. Returns error when value does not exist
|
||||
// MustUint16s requires parameter value to exist to bind to uint16 slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint16s(sourceParam string, dest *[]uint16) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -802,7 +879,7 @@ func (b *ValueBinder) Uint8s(sourceParam string, dest *[]uint8) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustUint8s requires parameter value to exist to be bind to uint8 slice variable. Returns error when value does not exist
|
||||
// MustUint8s requires parameter value to exist to bind to uint8 slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUint8s(sourceParam string, dest *[]uint8) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -812,7 +889,7 @@ func (b *ValueBinder) Uints(sourceParam string, dest *[]uint) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustUints requires parameter value to exist to be bind to uint slice variable. Returns error when value does not exist
|
||||
// MustUints requires parameter value to exist to bind to uint slice variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustUints(sourceParam string, dest *[]uint) *ValueBinder {
|
||||
return b.uintsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -822,7 +899,7 @@ func (b *ValueBinder) Bool(sourceParam string, dest *bool) *ValueBinder {
|
||||
return b.boolValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustBool requires parameter value to exist to be bind to bool variable. Returns error when value does not exist
|
||||
// MustBool requires parameter value to exist to bind to bool variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustBool(sourceParam string, dest *bool) *ValueBinder {
|
||||
return b.boolValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -887,7 +964,7 @@ func (b *ValueBinder) Bools(sourceParam string, dest *[]bool) *ValueBinder {
|
||||
return b.boolsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustBools requires parameter values to exist to be bind to slice of bool variables. Returns error when values does not exist
|
||||
// MustBools requires parameter values to exist to bind to slice of bool variables. Returns error when values does not exist
|
||||
func (b *ValueBinder) MustBools(sourceParam string, dest *[]bool) *ValueBinder {
|
||||
return b.boolsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -897,7 +974,7 @@ func (b *ValueBinder) Float64(sourceParam string, dest *float64) *ValueBinder {
|
||||
return b.floatValue(sourceParam, dest, 64, false)
|
||||
}
|
||||
|
||||
// MustFloat64 requires parameter value to exist to be bind to float64 variable. Returns error when value does not exist
|
||||
// MustFloat64 requires parameter value to exist to bind to float64 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustFloat64(sourceParam string, dest *float64) *ValueBinder {
|
||||
return b.floatValue(sourceParam, dest, 64, true)
|
||||
}
|
||||
@ -907,7 +984,7 @@ func (b *ValueBinder) Float32(sourceParam string, dest *float32) *ValueBinder {
|
||||
return b.floatValue(sourceParam, dest, 32, false)
|
||||
}
|
||||
|
||||
// MustFloat32 requires parameter value to exist to be bind to float32 variable. Returns error when value does not exist
|
||||
// MustFloat32 requires parameter value to exist to bind to float32 variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustFloat32(sourceParam string, dest *float32) *ValueBinder {
|
||||
return b.floatValue(sourceParam, dest, 32, true)
|
||||
}
|
||||
@ -992,7 +1069,7 @@ func (b *ValueBinder) Float64s(sourceParam string, dest *[]float64) *ValueBinder
|
||||
return b.floatsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustFloat64s requires parameter values to exist to be bind to slice of float64 variables. Returns error when values does not exist
|
||||
// MustFloat64s requires parameter values to exist to bind to slice of float64 variables. Returns error when values does not exist
|
||||
func (b *ValueBinder) MustFloat64s(sourceParam string, dest *[]float64) *ValueBinder {
|
||||
return b.floatsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -1002,7 +1079,7 @@ func (b *ValueBinder) Float32s(sourceParam string, dest *[]float32) *ValueBinder
|
||||
return b.floatsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustFloat32s requires parameter values to exist to be bind to slice of float32 variables. Returns error when values does not exist
|
||||
// MustFloat32s requires parameter values to exist to bind to slice of float32 variables. Returns error when values does not exist
|
||||
func (b *ValueBinder) MustFloat32s(sourceParam string, dest *[]float32) *ValueBinder {
|
||||
return b.floatsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -1012,7 +1089,7 @@ func (b *ValueBinder) Time(sourceParam string, dest *time.Time, layout string) *
|
||||
return b.time(sourceParam, dest, layout, false)
|
||||
}
|
||||
|
||||
// MustTime requires parameter value to exist to be bind to time.Time variable. Returns error when value does not exist
|
||||
// MustTime requires parameter value to exist to bind to time.Time variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustTime(sourceParam string, dest *time.Time, layout string) *ValueBinder {
|
||||
return b.time(sourceParam, dest, layout, true)
|
||||
}
|
||||
@ -1043,7 +1120,7 @@ func (b *ValueBinder) Times(sourceParam string, dest *[]time.Time, layout string
|
||||
return b.times(sourceParam, dest, layout, false)
|
||||
}
|
||||
|
||||
// MustTimes requires parameter values to exist to be bind to slice of time.Time variables. Returns error when values does not exist
|
||||
// MustTimes requires parameter values to exist to bind to slice of time.Time variables. Returns error when values does not exist
|
||||
func (b *ValueBinder) MustTimes(sourceParam string, dest *[]time.Time, layout string) *ValueBinder {
|
||||
return b.times(sourceParam, dest, layout, true)
|
||||
}
|
||||
@ -1084,7 +1161,7 @@ func (b *ValueBinder) Duration(sourceParam string, dest *time.Duration) *ValueBi
|
||||
return b.duration(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustDuration requires parameter value to exist to be bind to time.Duration variable. Returns error when value does not exist
|
||||
// MustDuration requires parameter value to exist to bind to time.Duration variable. Returns error when value does not exist
|
||||
func (b *ValueBinder) MustDuration(sourceParam string, dest *time.Duration) *ValueBinder {
|
||||
return b.duration(sourceParam, dest, true)
|
||||
}
|
||||
@ -1115,7 +1192,7 @@ func (b *ValueBinder) Durations(sourceParam string, dest *[]time.Duration) *Valu
|
||||
return b.durationsValue(sourceParam, dest, false)
|
||||
}
|
||||
|
||||
// MustDurations requires parameter values to exist to be bind to slice of time.Duration variables. Returns error when values does not exist
|
||||
// MustDurations requires parameter values to exist to bind to slice of time.Duration variables. Returns error when values does not exist
|
||||
func (b *ValueBinder) MustDurations(sourceParam string, dest *[]time.Duration) *ValueBinder {
|
||||
return b.durationsValue(sourceParam, dest, true)
|
||||
}
|
||||
@ -1161,10 +1238,10 @@ func (b *ValueBinder) durations(sourceParam string, values []string, dest *[]tim
|
||||
// Note:
|
||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||
func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
||||
return b.unixTime(sourceParam, dest, false, false)
|
||||
return b.unixTime(sourceParam, dest, false, time.Second)
|
||||
}
|
||||
|
||||
// MustUnixTime requires parameter value to exist to be bind to time.Duration variable (in local Time corresponding
|
||||
// MustUnixTime requires parameter value to exist to bind to time.Duration variable (in local time corresponding
|
||||
// to the given Unix time). Returns error when value does not exist.
|
||||
//
|
||||
// Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00
|
||||
@ -1172,10 +1249,31 @@ func (b *ValueBinder) UnixTime(sourceParam string, dest *time.Time) *ValueBinder
|
||||
// Note:
|
||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||
func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBinder {
|
||||
return b.unixTime(sourceParam, dest, true, false)
|
||||
return b.unixTime(sourceParam, dest, true, time.Second)
|
||||
}
|
||||
|
||||
// UnixTimeNano binds parameter to time.Time variable (in local Time corresponding to the given Unix time in nano second precision).
|
||||
// UnixTimeMilli binds parameter to time.Time variable (in local time corresponding to the given Unix time in millisecond precision).
|
||||
//
|
||||
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
||||
//
|
||||
// Note:
|
||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||
func (b *ValueBinder) UnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
||||
return b.unixTime(sourceParam, dest, false, time.Millisecond)
|
||||
}
|
||||
|
||||
// MustUnixTimeMilli requires parameter value to exist to bind to time.Duration variable (in local time corresponding
|
||||
// to the given Unix time in millisecond precision). Returns error when value does not exist.
|
||||
//
|
||||
// Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00
|
||||
//
|
||||
// Note:
|
||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||
func (b *ValueBinder) MustUnixTimeMilli(sourceParam string, dest *time.Time) *ValueBinder {
|
||||
return b.unixTime(sourceParam, dest, true, time.Millisecond)
|
||||
}
|
||||
|
||||
// UnixTimeNano binds parameter to time.Time variable (in local time corresponding to the given Unix time in nanosecond precision).
|
||||
//
|
||||
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
||||
// Example: 1000000000 binds to 1970-01-01T00:00:01.000000000+00:00
|
||||
@ -1185,10 +1283,10 @@ func (b *ValueBinder) MustUnixTime(sourceParam string, dest *time.Time) *ValueBi
|
||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
||||
func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
||||
return b.unixTime(sourceParam, dest, false, true)
|
||||
return b.unixTime(sourceParam, dest, false, time.Nanosecond)
|
||||
}
|
||||
|
||||
// MustUnixTimeNano requires parameter value to exist to be bind to time.Duration variable (in local Time corresponding
|
||||
// MustUnixTimeNano requires parameter value to exist to bind to time.Duration variable (in local Time corresponding
|
||||
// to the given Unix time value in nano second precision). Returns error when value does not exist.
|
||||
//
|
||||
// Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00
|
||||
@ -1199,10 +1297,10 @@ func (b *ValueBinder) UnixTimeNano(sourceParam string, dest *time.Time) *ValueBi
|
||||
// * time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
|
||||
// * Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.
|
||||
func (b *ValueBinder) MustUnixTimeNano(sourceParam string, dest *time.Time) *ValueBinder {
|
||||
return b.unixTime(sourceParam, dest, true, true)
|
||||
return b.unixTime(sourceParam, dest, true, time.Nanosecond)
|
||||
}
|
||||
|
||||
func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExist bool, isNano bool) *ValueBinder {
|
||||
func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExist bool, precision time.Duration) *ValueBinder {
|
||||
if b.failFast && b.errors != nil {
|
||||
return b
|
||||
}
|
||||
@ -1221,10 +1319,13 @@ func (b *ValueBinder) unixTime(sourceParam string, dest *time.Time, valueMustExi
|
||||
return b
|
||||
}
|
||||
|
||||
if isNano {
|
||||
*dest = time.Unix(0, n)
|
||||
} else {
|
||||
switch precision {
|
||||
case time.Second:
|
||||
*dest = time.Unix(n, 0)
|
||||
case time.Millisecond:
|
||||
*dest = time.Unix(n/1e3, (n%1e3)*1e6) // TODO: time.UnixMilli(n) exists since Go1.17 switch to that when min version allows
|
||||
case time.Nanosecond:
|
||||
*dest = time.Unix(0, n)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
20
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
20
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
@ -183,6 +183,8 @@ const (
|
||||
PROPFIND = "PROPFIND"
|
||||
// REPORT Method can be used to get information about a resource, see rfc 3253
|
||||
REPORT = "REPORT"
|
||||
// RouteNotFound is special method type for routes handling "route not found" (404) cases
|
||||
RouteNotFound = "echo_route_not_found"
|
||||
)
|
||||
|
||||
// Headers
|
||||
@ -246,7 +248,7 @@ const (
|
||||
|
||||
const (
|
||||
// Version of Echo
|
||||
Version = "4.7.2"
|
||||
Version = "4.8.0"
|
||||
website = "https://echo.labstack.com"
|
||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||
banner = `
|
||||
@ -480,8 +482,21 @@ func (e *Echo) TRACE(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(http.MethodTrace, path, h, m...)
|
||||
}
|
||||
|
||||
// Any registers a new route for all HTTP methods and path with matching handler
|
||||
// RouteNotFound registers a special-case route which is executed when no other route is found (i.e. HTTP 404 cases)
|
||||
// for current request URL.
|
||||
// Path supports static and named/any parameters just like other http method is defined. Generally path is ended with
|
||||
// wildcard/match-any character (`/*`, `/download/*` etc).
|
||||
//
|
||||
// Example: `e.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })`
|
||||
func (e *Echo) RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return e.Add(RouteNotFound, path, h, m...)
|
||||
}
|
||||
|
||||
// Any registers a new route for all HTTP methods (supported by Echo) and path with matching handler
|
||||
// in the router with optional route-level middleware.
|
||||
//
|
||||
// Note: this method only adds specific set of supported HTTP methods as handler and is not true
|
||||
// "catch-any-arbitrary-method" way of matching requests.
|
||||
func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) []*Route {
|
||||
routes := make([]*Route, len(methods))
|
||||
for i, m := range methods {
|
||||
@ -515,6 +530,7 @@ func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
|
||||
func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||
name := handlerName(handler)
|
||||
router := e.findRouter(host)
|
||||
// FIXME: when handler+middleware are both nil ... make it behave like handler removal
|
||||
router.Add(method, path, func(c Context) error {
|
||||
h := applyMiddleware(handler, middleware...)
|
||||
return h(c)
|
||||
|
||||
7
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
7
vendor/github.com/labstack/echo/v4/group.go
generated
vendored
@ -107,6 +107,13 @@ func (g *Group) File(path, file string) {
|
||||
g.file(path, file, g.GET)
|
||||
}
|
||||
|
||||
// RouteNotFound implements `Echo#RouteNotFound()` for sub-routes within the Group.
|
||||
//
|
||||
// Example: `g.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })`
|
||||
func (g *Group) RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) *Route {
|
||||
return g.Add(RouteNotFound, path, h, m...)
|
||||
}
|
||||
|
||||
// Add implements `Echo#Add()` for sub-routes within the Group.
|
||||
func (g *Group) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
|
||||
// Combine into a new slice to avoid accidentally passing the same slice for
|
||||
|
||||
6
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
6
vendor/github.com/labstack/echo/v4/middleware/basic_auth.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
"encoding/base64"
|
||||
"strconv"
|
||||
"strings"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
@ -74,10 +75,13 @@ func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
||||
l := len(basic)
|
||||
|
||||
if len(auth) > l+1 && strings.EqualFold(auth[:l], basic) {
|
||||
// Invalid base64 shouldn't be treated as error
|
||||
// instead should be treated as invalid client input
|
||||
b, err := base64.StdEncoding.DecodeString(auth[l+1:])
|
||||
if err != nil {
|
||||
return err
|
||||
return echo.NewHTTPError(http.StatusBadRequest).SetInternal(err)
|
||||
}
|
||||
|
||||
cred := string(b)
|
||||
for i := 0; i < len(cred); i++ {
|
||||
if cred[i] == ':' {
|
||||
|
||||
8
vendor/github.com/labstack/echo/v4/middleware/logger.go
generated
vendored
8
vendor/github.com/labstack/echo/v4/middleware/logger.go
generated
vendored
@ -23,6 +23,8 @@ type (
|
||||
// Tags to construct the logger format.
|
||||
//
|
||||
// - time_unix
|
||||
// - time_unix_milli
|
||||
// - time_unix_micro
|
||||
// - time_unix_nano
|
||||
// - time_rfc3339
|
||||
// - time_rfc3339_nano
|
||||
@ -126,6 +128,12 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
|
||||
switch tag {
|
||||
case "time_unix":
|
||||
return buf.WriteString(strconv.FormatInt(time.Now().Unix(), 10))
|
||||
case "time_unix_milli":
|
||||
// go 1.17 or later, it supports time#UnixMilli()
|
||||
return buf.WriteString(strconv.FormatInt(time.Now().UnixNano()/1000000, 10))
|
||||
case "time_unix_micro":
|
||||
// go 1.17 or later, it supports time#UnixMicro()
|
||||
return buf.WriteString(strconv.FormatInt(time.Now().UnixNano()/1000, 10))
|
||||
case "time_unix_nano":
|
||||
return buf.WriteString(strconv.FormatInt(time.Now().UnixNano(), 10))
|
||||
case "time_rfc3339":
|
||||
|
||||
6
vendor/github.com/labstack/echo/v4/middleware/request_logger.go
generated
vendored
6
vendor/github.com/labstack/echo/v4/middleware/request_logger.go
generated
vendored
@ -2,9 +2,10 @@ package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// Example for `fmt.Printf`
|
||||
@ -264,7 +265,8 @@ func (config RequestLoggerConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
|
||||
if config.LogStatus {
|
||||
v.Status = res.Status
|
||||
if err != nil {
|
||||
if httpErr, ok := err.(*echo.HTTPError); ok {
|
||||
var httpErr *echo.HTTPError
|
||||
if errors.As(err, &httpErr) {
|
||||
v.Status = httpErr.Code
|
||||
}
|
||||
}
|
||||
|
||||
5
vendor/github.com/labstack/echo/v4/middleware/static.go
generated
vendored
5
vendor/github.com/labstack/echo/v4/middleware/static.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
@ -196,8 +197,8 @@ func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc {
|
||||
return err
|
||||
}
|
||||
|
||||
he, ok := err.(*echo.HTTPError)
|
||||
if !(ok && config.HTML5 && he.Code == http.StatusNotFound) {
|
||||
var he *echo.HTTPError
|
||||
if !(errors.As(err, &he) && config.HTML5 && he.Code == http.StatusNotFound) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
323
vendor/github.com/labstack/echo/v4/router.go
generated
vendored
323
vendor/github.com/labstack/echo/v4/router.go
generated
vendored
@ -19,30 +19,39 @@ type (
|
||||
prefix string
|
||||
parent *node
|
||||
staticChildren children
|
||||
ppath string
|
||||
pnames []string
|
||||
methodHandler *methodHandler
|
||||
originalPath string
|
||||
methods *routeMethods
|
||||
paramChild *node
|
||||
anyChild *node
|
||||
paramsCount int
|
||||
// isLeaf indicates that node does not have child routes
|
||||
isLeaf bool
|
||||
// isHandler indicates that node has at least one handler registered to it
|
||||
isHandler bool
|
||||
|
||||
// notFoundHandler is handler registered with RouteNotFound method and is executed for 404 cases
|
||||
notFoundHandler *routeMethod
|
||||
}
|
||||
kind uint8
|
||||
children []*node
|
||||
methodHandler struct {
|
||||
connect HandlerFunc
|
||||
delete HandlerFunc
|
||||
get HandlerFunc
|
||||
head HandlerFunc
|
||||
options HandlerFunc
|
||||
patch HandlerFunc
|
||||
post HandlerFunc
|
||||
propfind HandlerFunc
|
||||
put HandlerFunc
|
||||
trace HandlerFunc
|
||||
report HandlerFunc
|
||||
kind uint8
|
||||
children []*node
|
||||
routeMethod struct {
|
||||
ppath string
|
||||
pnames []string
|
||||
handler HandlerFunc
|
||||
}
|
||||
routeMethods struct {
|
||||
connect *routeMethod
|
||||
delete *routeMethod
|
||||
get *routeMethod
|
||||
head *routeMethod
|
||||
options *routeMethod
|
||||
patch *routeMethod
|
||||
post *routeMethod
|
||||
propfind *routeMethod
|
||||
put *routeMethod
|
||||
trace *routeMethod
|
||||
report *routeMethod
|
||||
anyOther map[string]*routeMethod
|
||||
allowHeader string
|
||||
}
|
||||
)
|
||||
@ -56,7 +65,7 @@ const (
|
||||
anyLabel = byte('*')
|
||||
)
|
||||
|
||||
func (m *methodHandler) isHandler() bool {
|
||||
func (m *routeMethods) isHandler() bool {
|
||||
return m.connect != nil ||
|
||||
m.delete != nil ||
|
||||
m.get != nil ||
|
||||
@ -67,10 +76,12 @@ func (m *methodHandler) isHandler() bool {
|
||||
m.propfind != nil ||
|
||||
m.put != nil ||
|
||||
m.trace != nil ||
|
||||
m.report != nil
|
||||
m.report != nil ||
|
||||
len(m.anyOther) != 0
|
||||
// RouteNotFound/404 is not considered as a handler
|
||||
}
|
||||
|
||||
func (m *methodHandler) updateAllowHeader() {
|
||||
func (m *routeMethods) updateAllowHeader() {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.WriteString(http.MethodOptions)
|
||||
|
||||
@ -112,6 +123,10 @@ func (m *methodHandler) updateAllowHeader() {
|
||||
if m.report != nil {
|
||||
buf.WriteString(", REPORT")
|
||||
}
|
||||
for method := range m.anyOther { // for simplicity, we use map and therefore order is not deterministic here
|
||||
buf.WriteString(", ")
|
||||
buf.WriteString(method)
|
||||
}
|
||||
m.allowHeader = buf.String()
|
||||
}
|
||||
|
||||
@ -119,7 +134,7 @@ func (m *methodHandler) updateAllowHeader() {
|
||||
func NewRouter(e *Echo) *Router {
|
||||
return &Router{
|
||||
tree: &node{
|
||||
methodHandler: new(methodHandler),
|
||||
methods: new(routeMethods),
|
||||
},
|
||||
routes: map[string]*Route{},
|
||||
echo: e,
|
||||
@ -153,7 +168,7 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
|
||||
}
|
||||
j := i + 1
|
||||
|
||||
r.insert(method, path[:i], nil, staticKind, "", nil)
|
||||
r.insert(method, path[:i], staticKind, routeMethod{})
|
||||
for ; i < lcpIndex && path[i] != '/'; i++ {
|
||||
}
|
||||
|
||||
@ -163,23 +178,23 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
|
||||
|
||||
if i == lcpIndex {
|
||||
// path node is last fragment of route path. ie. `/users/:id`
|
||||
r.insert(method, path[:i], h, paramKind, ppath, pnames)
|
||||
r.insert(method, path[:i], paramKind, routeMethod{ppath, pnames, h})
|
||||
} else {
|
||||
r.insert(method, path[:i], nil, paramKind, "", nil)
|
||||
r.insert(method, path[:i], paramKind, routeMethod{})
|
||||
}
|
||||
} else if path[i] == '*' {
|
||||
r.insert(method, path[:i], nil, staticKind, "", nil)
|
||||
r.insert(method, path[:i], staticKind, routeMethod{})
|
||||
pnames = append(pnames, "*")
|
||||
r.insert(method, path[:i+1], h, anyKind, ppath, pnames)
|
||||
r.insert(method, path[:i+1], anyKind, routeMethod{ppath, pnames, h})
|
||||
}
|
||||
}
|
||||
|
||||
r.insert(method, path, h, staticKind, ppath, pnames)
|
||||
r.insert(method, path, staticKind, routeMethod{ppath, pnames, h})
|
||||
}
|
||||
|
||||
func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string, pnames []string) {
|
||||
func (r *Router) insert(method, path string, t kind, rm routeMethod) {
|
||||
// Adjust max param
|
||||
paramLen := len(pnames)
|
||||
paramLen := len(rm.pnames)
|
||||
if *r.echo.maxParam < paramLen {
|
||||
*r.echo.maxParam = paramLen
|
||||
}
|
||||
@ -207,25 +222,31 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||
// At root node
|
||||
currentNode.label = search[0]
|
||||
currentNode.prefix = search
|
||||
if h != nil {
|
||||
if rm.handler != nil {
|
||||
currentNode.kind = t
|
||||
currentNode.addHandler(method, h)
|
||||
currentNode.ppath = ppath
|
||||
currentNode.pnames = pnames
|
||||
currentNode.addMethod(method, &rm)
|
||||
currentNode.paramsCount = len(rm.pnames)
|
||||
currentNode.originalPath = rm.ppath
|
||||
}
|
||||
currentNode.isLeaf = currentNode.staticChildren == nil && currentNode.paramChild == nil && currentNode.anyChild == nil
|
||||
} else if lcpLen < prefixLen {
|
||||
// Split node
|
||||
// Split node into two before we insert new node.
|
||||
// This happens when we are inserting path that is submatch of any existing inserted paths.
|
||||
// For example, we have node `/test` and now are about to insert `/te/*`. In that case
|
||||
// 1. overlapping part is `/te` that is used as parent node
|
||||
// 2. `st` is part from existing node that is not matching - it gets its own node (child to `/te`)
|
||||
// 3. `/*` is the new part we are about to insert (child to `/te`)
|
||||
n := newNode(
|
||||
currentNode.kind,
|
||||
currentNode.prefix[lcpLen:],
|
||||
currentNode,
|
||||
currentNode.staticChildren,
|
||||
currentNode.methodHandler,
|
||||
currentNode.ppath,
|
||||
currentNode.pnames,
|
||||
currentNode.originalPath,
|
||||
currentNode.methods,
|
||||
currentNode.paramsCount,
|
||||
currentNode.paramChild,
|
||||
currentNode.anyChild,
|
||||
currentNode.notFoundHandler,
|
||||
)
|
||||
// Update parent path for all children to new node
|
||||
for _, child := range currentNode.staticChildren {
|
||||
@ -243,13 +264,14 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||
currentNode.label = currentNode.prefix[0]
|
||||
currentNode.prefix = currentNode.prefix[:lcpLen]
|
||||
currentNode.staticChildren = nil
|
||||
currentNode.methodHandler = new(methodHandler)
|
||||
currentNode.ppath = ""
|
||||
currentNode.pnames = nil
|
||||
currentNode.originalPath = ""
|
||||
currentNode.methods = new(routeMethods)
|
||||
currentNode.paramsCount = 0
|
||||
currentNode.paramChild = nil
|
||||
currentNode.anyChild = nil
|
||||
currentNode.isLeaf = false
|
||||
currentNode.isHandler = false
|
||||
currentNode.notFoundHandler = nil
|
||||
|
||||
// Only Static children could reach here
|
||||
currentNode.addStaticChild(n)
|
||||
@ -257,13 +279,19 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||
if lcpLen == searchLen {
|
||||
// At parent node
|
||||
currentNode.kind = t
|
||||
currentNode.addHandler(method, h)
|
||||
currentNode.ppath = ppath
|
||||
currentNode.pnames = pnames
|
||||
if rm.handler != nil {
|
||||
currentNode.addMethod(method, &rm)
|
||||
currentNode.paramsCount = len(rm.pnames)
|
||||
currentNode.originalPath = rm.ppath
|
||||
}
|
||||
} else {
|
||||
// Create child node
|
||||
n = newNode(t, search[lcpLen:], currentNode, nil, new(methodHandler), ppath, pnames, nil, nil)
|
||||
n.addHandler(method, h)
|
||||
n = newNode(t, search[lcpLen:], currentNode, nil, "", new(routeMethods), 0, nil, nil, nil)
|
||||
if rm.handler != nil {
|
||||
n.addMethod(method, &rm)
|
||||
n.paramsCount = len(rm.pnames)
|
||||
n.originalPath = rm.ppath
|
||||
}
|
||||
// Only Static children could reach here
|
||||
currentNode.addStaticChild(n)
|
||||
}
|
||||
@ -277,8 +305,12 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||
continue
|
||||
}
|
||||
// Create child node
|
||||
n := newNode(t, search, currentNode, nil, new(methodHandler), ppath, pnames, nil, nil)
|
||||
n.addHandler(method, h)
|
||||
n := newNode(t, search, currentNode, nil, rm.ppath, new(routeMethods), 0, nil, nil, nil)
|
||||
if rm.handler != nil {
|
||||
n.addMethod(method, &rm)
|
||||
n.paramsCount = len(rm.pnames)
|
||||
}
|
||||
|
||||
switch t {
|
||||
case staticKind:
|
||||
currentNode.addStaticChild(n)
|
||||
@ -290,32 +322,42 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
|
||||
currentNode.isLeaf = currentNode.staticChildren == nil && currentNode.paramChild == nil && currentNode.anyChild == nil
|
||||
} else {
|
||||
// Node already exists
|
||||
if h != nil {
|
||||
currentNode.addHandler(method, h)
|
||||
currentNode.ppath = ppath
|
||||
if len(currentNode.pnames) == 0 { // Issue #729
|
||||
currentNode.pnames = pnames
|
||||
}
|
||||
if rm.handler != nil {
|
||||
currentNode.addMethod(method, &rm)
|
||||
currentNode.paramsCount = len(rm.pnames)
|
||||
currentNode.originalPath = rm.ppath
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func newNode(t kind, pre string, p *node, sc children, mh *methodHandler, ppath string, pnames []string, paramChildren, anyChildren *node) *node {
|
||||
func newNode(
|
||||
t kind,
|
||||
pre string,
|
||||
p *node,
|
||||
sc children,
|
||||
originalPath string,
|
||||
methods *routeMethods,
|
||||
paramsCount int,
|
||||
paramChildren,
|
||||
anyChildren *node,
|
||||
notFoundHandler *routeMethod,
|
||||
) *node {
|
||||
return &node{
|
||||
kind: t,
|
||||
label: pre[0],
|
||||
prefix: pre,
|
||||
parent: p,
|
||||
staticChildren: sc,
|
||||
ppath: ppath,
|
||||
pnames: pnames,
|
||||
methodHandler: mh,
|
||||
paramChild: paramChildren,
|
||||
anyChild: anyChildren,
|
||||
isLeaf: sc == nil && paramChildren == nil && anyChildren == nil,
|
||||
isHandler: mh.isHandler(),
|
||||
kind: t,
|
||||
label: pre[0],
|
||||
prefix: pre,
|
||||
parent: p,
|
||||
staticChildren: sc,
|
||||
originalPath: originalPath,
|
||||
methods: methods,
|
||||
paramsCount: paramsCount,
|
||||
paramChild: paramChildren,
|
||||
anyChild: anyChildren,
|
||||
isLeaf: sc == nil && paramChildren == nil && anyChildren == nil,
|
||||
isHandler: methods.isHandler(),
|
||||
notFoundHandler: notFoundHandler,
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,10 +375,8 @@ func (n *node) findStaticChild(l byte) *node {
|
||||
}
|
||||
|
||||
func (n *node) findChildWithLabel(l byte) *node {
|
||||
for _, c := range n.staticChildren {
|
||||
if c.label == l {
|
||||
return c
|
||||
}
|
||||
if c := n.findStaticChild(l); c != nil {
|
||||
return c
|
||||
}
|
||||
if l == paramLabel {
|
||||
return n.paramChild
|
||||
@ -347,66 +387,74 @@ func (n *node) findChildWithLabel(l byte) *node {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *node) addHandler(method string, h HandlerFunc) {
|
||||
func (n *node) addMethod(method string, h *routeMethod) {
|
||||
switch method {
|
||||
case http.MethodConnect:
|
||||
n.methodHandler.connect = h
|
||||
n.methods.connect = h
|
||||
case http.MethodDelete:
|
||||
n.methodHandler.delete = h
|
||||
n.methods.delete = h
|
||||
case http.MethodGet:
|
||||
n.methodHandler.get = h
|
||||
n.methods.get = h
|
||||
case http.MethodHead:
|
||||
n.methodHandler.head = h
|
||||
n.methods.head = h
|
||||
case http.MethodOptions:
|
||||
n.methodHandler.options = h
|
||||
n.methods.options = h
|
||||
case http.MethodPatch:
|
||||
n.methodHandler.patch = h
|
||||
n.methods.patch = h
|
||||
case http.MethodPost:
|
||||
n.methodHandler.post = h
|
||||
n.methods.post = h
|
||||
case PROPFIND:
|
||||
n.methodHandler.propfind = h
|
||||
n.methods.propfind = h
|
||||
case http.MethodPut:
|
||||
n.methodHandler.put = h
|
||||
n.methods.put = h
|
||||
case http.MethodTrace:
|
||||
n.methodHandler.trace = h
|
||||
n.methods.trace = h
|
||||
case REPORT:
|
||||
n.methodHandler.report = h
|
||||
n.methods.report = h
|
||||
case RouteNotFound:
|
||||
n.notFoundHandler = h
|
||||
return // RouteNotFound/404 is not considered as a handler so no further logic needs to be executed
|
||||
default:
|
||||
if n.methods.anyOther == nil {
|
||||
n.methods.anyOther = make(map[string]*routeMethod)
|
||||
}
|
||||
if h.handler == nil {
|
||||
delete(n.methods.anyOther, method)
|
||||
} else {
|
||||
n.methods.anyOther[method] = h
|
||||
}
|
||||
}
|
||||
|
||||
n.methodHandler.updateAllowHeader()
|
||||
if h != nil {
|
||||
n.isHandler = true
|
||||
} else {
|
||||
n.isHandler = n.methodHandler.isHandler()
|
||||
}
|
||||
n.methods.updateAllowHeader()
|
||||
n.isHandler = true
|
||||
}
|
||||
|
||||
func (n *node) findHandler(method string) HandlerFunc {
|
||||
func (n *node) findMethod(method string) *routeMethod {
|
||||
switch method {
|
||||
case http.MethodConnect:
|
||||
return n.methodHandler.connect
|
||||
return n.methods.connect
|
||||
case http.MethodDelete:
|
||||
return n.methodHandler.delete
|
||||
return n.methods.delete
|
||||
case http.MethodGet:
|
||||
return n.methodHandler.get
|
||||
return n.methods.get
|
||||
case http.MethodHead:
|
||||
return n.methodHandler.head
|
||||
return n.methods.head
|
||||
case http.MethodOptions:
|
||||
return n.methodHandler.options
|
||||
return n.methods.options
|
||||
case http.MethodPatch:
|
||||
return n.methodHandler.patch
|
||||
return n.methods.patch
|
||||
case http.MethodPost:
|
||||
return n.methodHandler.post
|
||||
return n.methods.post
|
||||
case PROPFIND:
|
||||
return n.methodHandler.propfind
|
||||
return n.methods.propfind
|
||||
case http.MethodPut:
|
||||
return n.methodHandler.put
|
||||
return n.methods.put
|
||||
case http.MethodTrace:
|
||||
return n.methodHandler.trace
|
||||
return n.methods.trace
|
||||
case REPORT:
|
||||
return n.methodHandler.report
|
||||
default:
|
||||
return nil
|
||||
return n.methods.report
|
||||
default: // RouteNotFound/404 is not considered as a handler
|
||||
return n.methods.anyOther[method]
|
||||
}
|
||||
}
|
||||
|
||||
@ -435,7 +483,7 @@ func (r *Router) Find(method, path string, c Context) {
|
||||
|
||||
var (
|
||||
previousBestMatchNode *node
|
||||
matchedHandler HandlerFunc
|
||||
matchedRouteMethod *routeMethod
|
||||
// search stores the remaining path to check for match. By each iteration we move from start of path to end of the path
|
||||
// and search value gets shorter and shorter.
|
||||
search = path
|
||||
@ -508,7 +556,7 @@ func (r *Router) Find(method, path string, c Context) {
|
||||
// No matching prefix, let's backtrack to the first possible alternative node of the decision path
|
||||
nk, ok := backtrackToNextNodeKind(staticKind)
|
||||
if !ok {
|
||||
return // No other possibilities on the decision path
|
||||
return // No other possibilities on the decision path, handler will be whatever context is reset to.
|
||||
} else if nk == paramKind {
|
||||
goto Param
|
||||
// NOTE: this case (backtracking from static node to previous any node) can not happen by current any matching logic. Any node is end of search currently
|
||||
@ -524,15 +572,21 @@ func (r *Router) Find(method, path string, c Context) {
|
||||
search = search[lcpLen:]
|
||||
searchIndex = searchIndex + lcpLen
|
||||
|
||||
// Finish routing if no remaining search and we are on a node with handler and matching method type
|
||||
if search == "" && currentNode.isHandler {
|
||||
// check if current node has handler registered for http method we are looking for. we store currentNode as
|
||||
// best matching in case we do no find no more routes matching this path+method
|
||||
if previousBestMatchNode == nil {
|
||||
previousBestMatchNode = currentNode
|
||||
}
|
||||
if h := currentNode.findHandler(method); h != nil {
|
||||
matchedHandler = h
|
||||
// Finish routing if is no request path remaining to search
|
||||
if search == "" {
|
||||
// in case of node that is handler we have exact method type match or something for 405 to use
|
||||
if currentNode.isHandler {
|
||||
// check if current node has handler registered for http method we are looking for. we store currentNode as
|
||||
// best matching in case we do no find no more routes matching this path+method
|
||||
if previousBestMatchNode == nil {
|
||||
previousBestMatchNode = currentNode
|
||||
}
|
||||
if h := currentNode.findMethod(method); h != nil {
|
||||
matchedRouteMethod = h
|
||||
break
|
||||
}
|
||||
} else if currentNode.notFoundHandler != nil {
|
||||
matchedRouteMethod = currentNode.notFoundHandler
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -552,7 +606,8 @@ func (r *Router) Find(method, path string, c Context) {
|
||||
i := 0
|
||||
l := len(search)
|
||||
if currentNode.isLeaf {
|
||||
// when param node does not have any children then param node should act similarly to any node - consider all remaining search as match
|
||||
// when param node does not have any children (path param is last piece of route path) then param node should
|
||||
// act similarly to any node - consider all remaining search as match
|
||||
i = l
|
||||
} else {
|
||||
for ; i < l && search[i] != '/'; i++ {
|
||||
@ -571,19 +626,23 @@ func (r *Router) Find(method, path string, c Context) {
|
||||
if child := currentNode.anyChild; child != nil {
|
||||
// If any node is found, use remaining path for paramValues
|
||||
currentNode = child
|
||||
paramValues[len(currentNode.pnames)-1] = search
|
||||
paramValues[currentNode.paramsCount-1] = search
|
||||
|
||||
// update indexes/search in case we need to backtrack when no handler match is found
|
||||
paramIndex++
|
||||
searchIndex += +len(search)
|
||||
search = ""
|
||||
|
||||
// check if current node has handler registered for http method we are looking for. we store currentNode as
|
||||
// best matching in case we do no find no more routes matching this path+method
|
||||
if h := currentNode.findMethod(method); h != nil {
|
||||
matchedRouteMethod = h
|
||||
break
|
||||
}
|
||||
// we store currentNode as best matching in case we do not find more routes matching this path+method. Needed for 405
|
||||
if previousBestMatchNode == nil {
|
||||
previousBestMatchNode = currentNode
|
||||
}
|
||||
if h := currentNode.findHandler(method); h != nil {
|
||||
matchedHandler = h
|
||||
if currentNode.notFoundHandler != nil {
|
||||
matchedRouteMethod = currentNode.notFoundHandler
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -606,22 +665,34 @@ func (r *Router) Find(method, path string, c Context) {
|
||||
return // nothing matched at all
|
||||
}
|
||||
|
||||
if matchedHandler != nil {
|
||||
ctx.handler = matchedHandler
|
||||
// matchedHandler could be method+path handler that we matched or notFoundHandler from node with matching path
|
||||
// user provided not found (404) handler has priority over generic method not found (405) handler or global 404 handler
|
||||
var rPath string
|
||||
var rPNames []string
|
||||
if matchedRouteMethod != nil {
|
||||
rPath = matchedRouteMethod.ppath
|
||||
rPNames = matchedRouteMethod.pnames
|
||||
ctx.handler = matchedRouteMethod.handler
|
||||
} else {
|
||||
// use previous match as basis. although we have no matching handler we have path match.
|
||||
// so we can send http.StatusMethodNotAllowed (405) instead of http.StatusNotFound (404)
|
||||
currentNode = previousBestMatchNode
|
||||
|
||||
rPath = currentNode.originalPath
|
||||
rPNames = nil // no params here
|
||||
ctx.handler = NotFoundHandler
|
||||
if currentNode.isHandler {
|
||||
ctx.Set(ContextKeyHeaderAllow, currentNode.methodHandler.allowHeader)
|
||||
if currentNode.notFoundHandler != nil {
|
||||
rPath = currentNode.notFoundHandler.ppath
|
||||
rPNames = currentNode.notFoundHandler.pnames
|
||||
ctx.handler = currentNode.notFoundHandler.handler
|
||||
} else if currentNode.isHandler {
|
||||
ctx.Set(ContextKeyHeaderAllow, currentNode.methods.allowHeader)
|
||||
ctx.handler = MethodNotAllowedHandler
|
||||
if method == http.MethodOptions {
|
||||
ctx.handler = optionsMethodHandler(currentNode.methodHandler.allowHeader)
|
||||
ctx.handler = optionsMethodHandler(currentNode.methods.allowHeader)
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.path = currentNode.ppath
|
||||
ctx.pnames = currentNode.pnames
|
||||
ctx.path = rPath
|
||||
ctx.pnames = rPNames
|
||||
}
|
||||
|
||||
30
vendor/github.com/matryer/moq/.gitignore
generated
vendored
30
vendor/github.com/matryer/moq/.gitignore
generated
vendored
@ -1,30 +0,0 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
.vscode
|
||||
.idea
|
||||
.playground
|
||||
|
||||
dist/
|
||||
.DS_Store
|
||||
34
vendor/github.com/matryer/moq/.goreleaser.yml
generated
vendored
34
vendor/github.com/matryer/moq/.goreleaser.yml
generated
vendored
@ -1,34 +0,0 @@
|
||||
# This is an example goreleaser.yaml file with some sane defaults.
|
||||
# Make sure to check the documentation at http://goreleaser.com
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- darwin
|
||||
- windows
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
ldflags:
|
||||
- -X main.Version={{.Version}}
|
||||
archives:
|
||||
- replacements:
|
||||
darwin: macOS
|
||||
linux: Linux
|
||||
windows: Windows
|
||||
386: i386
|
||||
amd64: x86_64
|
||||
universal_binaries:
|
||||
- replace: false
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
21
vendor/github.com/matryer/moq/LICENSE
generated
vendored
21
vendor/github.com/matryer/moq/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Mat Ryer and David Hernandez
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
135
vendor/github.com/matryer/moq/README.md
generated
vendored
135
vendor/github.com/matryer/moq/README.md
generated
vendored
@ -1,135 +0,0 @@
|
||||
 [](https://github.com/matryer/moq/actions?query=branch%3Amaster) [](https://goreportcard.com/report/github.com/matryer/moq)
|
||||
|
||||
Interface mocking tool for go generate.
|
||||
|
||||
### What is Moq?
|
||||
|
||||
Moq is a tool that generates a struct from any interface. The struct can be used in test code as a mock of the interface.
|
||||
|
||||

|
||||
|
||||
above: Moq generates the code on the right.
|
||||
|
||||
You can read more in the [Meet Moq blog post](http://bit.ly/meetmoq).
|
||||
|
||||
### Installing
|
||||
|
||||
To start using latest released version of Moq, just run:
|
||||
|
||||
#### Go version < 1.16
|
||||
|
||||
```
|
||||
$ go get github.com/matryer/moq
|
||||
```
|
||||
|
||||
#### Go 1.16+
|
||||
|
||||
```
|
||||
$ go install github.com/matryer/moq@latest
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```
|
||||
moq [flags] source-dir interface [interface2 [interface3 [...]]]
|
||||
-fmt string
|
||||
go pretty-printer: gofmt, goimports or noop (default gofmt)
|
||||
-out string
|
||||
output file (default stdout)
|
||||
-pkg string
|
||||
package name (default will infer)
|
||||
-stub
|
||||
return zero values when no mock implementation is provided, do not panic
|
||||
-skip-ensure
|
||||
suppress mock implementation check, avoid import cycle if mocks
|
||||
generated outside of the tested package
|
||||
|
||||
Specifying an alias for the mock is also supported with the format 'interface:alias'
|
||||
|
||||
Example: moq -pkg different . MyInterface:MyMock
|
||||
```
|
||||
|
||||
**NOTE:** `source-dir` is the directory where the source code (definition) of the target interface is located.
|
||||
It needs to be a path to a directory and not the import statement for a Go package.
|
||||
|
||||
In a command line:
|
||||
|
||||
```
|
||||
$ moq -out mocks_test.go . MyInterface
|
||||
```
|
||||
|
||||
In code (for go generate):
|
||||
|
||||
```go
|
||||
package my
|
||||
|
||||
//go:generate moq -out myinterface_moq_test.go . MyInterface
|
||||
|
||||
type MyInterface interface {
|
||||
Method1() error
|
||||
Method2(i int)
|
||||
}
|
||||
```
|
||||
|
||||
Then run `go generate` for your package.
|
||||
|
||||
### How to use it
|
||||
|
||||
Mocking interfaces is a nice way to write unit tests where you can easily control the behaviour of the mocked object.
|
||||
|
||||
Moq creates a struct that has a function field for each method, which you can declare in your test code.
|
||||
|
||||
In this example, Moq generated the `EmailSenderMock` type:
|
||||
|
||||
```go
|
||||
func TestCompleteSignup(t *testing.T) {
|
||||
|
||||
var sentTo string
|
||||
|
||||
mockedEmailSender = &EmailSenderMock{
|
||||
SendFunc: func(to, subject, body string) error {
|
||||
sentTo = to
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
CompleteSignUp("me@email.com", mockedEmailSender)
|
||||
|
||||
callsToSend := len(mockedEmailSender.SendCalls())
|
||||
if callsToSend != 1 {
|
||||
t.Errorf("Send was called %d times", callsToSend)
|
||||
}
|
||||
if sentTo != "me@email.com" {
|
||||
t.Errorf("unexpected recipient: %s", sentTo)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func CompleteSignUp(to string, sender EmailSender) {
|
||||
// TODO: this
|
||||
}
|
||||
```
|
||||
|
||||
The mocked structure implements the interface, where each method calls the associated function field.
|
||||
|
||||
## Tips
|
||||
|
||||
* Keep mocked logic inside the test that is using it
|
||||
* Only mock the fields you need
|
||||
* It will panic if a nil function gets called
|
||||
* Name arguments in the interface for a better experience
|
||||
* Use closured variables inside your test function to capture details about the calls to the methods
|
||||
* Use `.MethodCalls()` to track the calls
|
||||
* Use `go:generate` to invoke the `moq` command
|
||||
* If Moq fails with a `go/format` error, it indicates the generated code was not valid.
|
||||
You can run the same command with `-fmt noop` to print the generated source code without attempting to format it.
|
||||
This can aid in debugging the root cause.
|
||||
|
||||
## License
|
||||
|
||||
The Moq project (and all code) is licensed under the [MIT License](LICENSE).
|
||||
|
||||
Moq was created by [Mat Ryer](https://twitter.com/matryer) and [David Hernandez](https://github.com/dahernan), with ideas lovingly stolen from [Ernesto Jimenez](https://github.com/ernesto-jimenez). Featuring a major refactor by @sudo-suhas, as well as lots of other contributors.
|
||||
|
||||
The Moq logo was created by [Chris Ryer](http://chrisryer.co.uk) and is licensed under the [Creative Commons Attribution 3.0 License](https://creativecommons.org/licenses/by/3.0/).
|
||||
|
||||
135
vendor/github.com/matryer/moq/internal/registry/method_scope.go
generated
vendored
135
vendor/github.com/matryer/moq/internal/registry/method_scope.go
generated
vendored
@ -1,135 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// MethodScope is the sub-registry for allocating variables present in
|
||||
// the method scope.
|
||||
//
|
||||
// It should be created using a registry instance.
|
||||
type MethodScope struct {
|
||||
registry *Registry
|
||||
moqPkgPath string
|
||||
|
||||
vars []*Var
|
||||
conflicted map[string]bool
|
||||
}
|
||||
|
||||
// AddVar allocates a variable instance and adds it to the method scope.
|
||||
//
|
||||
// Variables names are generated if required and are ensured to be
|
||||
// without conflict with other variables and imported packages. It also
|
||||
// adds the relevant imports to the registry for each added variable.
|
||||
func (m *MethodScope) AddVar(vr *types.Var, suffix string) *Var {
|
||||
imports := make(map[string]*Package)
|
||||
m.populateImports(vr.Type(), imports)
|
||||
m.resolveImportVarConflicts(imports)
|
||||
|
||||
name := varName(vr, suffix)
|
||||
// Ensure that the var name does not conflict with a package import.
|
||||
if _, ok := m.registry.searchImport(name); ok {
|
||||
name += "MoqParam"
|
||||
}
|
||||
if _, ok := m.searchVar(name); ok || m.conflicted[name] {
|
||||
name = m.resolveVarNameConflict(name)
|
||||
}
|
||||
|
||||
v := Var{
|
||||
vr: vr,
|
||||
imports: imports,
|
||||
moqPkgPath: m.moqPkgPath,
|
||||
Name: name,
|
||||
}
|
||||
m.vars = append(m.vars, &v)
|
||||
return &v
|
||||
}
|
||||
|
||||
func (m *MethodScope) resolveVarNameConflict(suggested string) string {
|
||||
for n := 1; ; n++ {
|
||||
_, ok := m.searchVar(suggested + strconv.Itoa(n))
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if n == 1 {
|
||||
conflict, _ := m.searchVar(suggested)
|
||||
conflict.Name += "1"
|
||||
m.conflicted[suggested] = true
|
||||
n++
|
||||
}
|
||||
return suggested + strconv.Itoa(n)
|
||||
}
|
||||
}
|
||||
|
||||
func (m MethodScope) searchVar(name string) (*Var, bool) {
|
||||
for _, v := range m.vars {
|
||||
if v.Name == name {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// populateImports extracts all the package imports for a given type
|
||||
// recursively. The imported packages by a single type can be more than
|
||||
// one (ex: map[a.Type]b.Type).
|
||||
func (m MethodScope) populateImports(t types.Type, imports map[string]*Package) {
|
||||
switch t := t.(type) {
|
||||
case *types.Named:
|
||||
if pkg := t.Obj().Pkg(); pkg != nil {
|
||||
imports[stripVendorPath(pkg.Path())] = m.registry.AddImport(pkg)
|
||||
}
|
||||
|
||||
case *types.Array:
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Slice:
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Signature:
|
||||
for i := 0; i < t.Params().Len(); i++ {
|
||||
m.populateImports(t.Params().At(i).Type(), imports)
|
||||
}
|
||||
for i := 0; i < t.Results().Len(); i++ {
|
||||
m.populateImports(t.Results().At(i).Type(), imports)
|
||||
}
|
||||
|
||||
case *types.Map:
|
||||
m.populateImports(t.Key(), imports)
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Chan:
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Pointer:
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Struct: // anonymous struct
|
||||
for i := 0; i < t.NumFields(); i++ {
|
||||
m.populateImports(t.Field(i).Type(), imports)
|
||||
}
|
||||
|
||||
case *types.Interface: // anonymous interface
|
||||
for i := 0; i < t.NumExplicitMethods(); i++ {
|
||||
m.populateImports(t.ExplicitMethod(i).Type(), imports)
|
||||
}
|
||||
for i := 0; i < t.NumEmbeddeds(); i++ {
|
||||
m.populateImports(t.EmbeddedType(i), imports)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// resolveImportVarConflicts ensures that all the newly added imports do not
|
||||
// conflict with any of the existing vars.
|
||||
func (m MethodScope) resolveImportVarConflicts(imports map[string]*Package) {
|
||||
// Ensure that all the newly added imports do not conflict with any of the
|
||||
// existing vars.
|
||||
for _, imprt := range imports {
|
||||
if v, ok := m.searchVar(imprt.Qualifier()); ok {
|
||||
v.Name += "MoqParam"
|
||||
}
|
||||
}
|
||||
}
|
||||
93
vendor/github.com/matryer/moq/internal/registry/package.go
generated
vendored
93
vendor/github.com/matryer/moq/internal/registry/package.go
generated
vendored
@ -1,93 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Package represents an imported package.
|
||||
type Package struct {
|
||||
pkg *types.Package
|
||||
|
||||
Alias string
|
||||
}
|
||||
|
||||
// NewPackage creates a new instance of Package.
|
||||
func NewPackage(pkg *types.Package) *Package { return &Package{pkg: pkg} }
|
||||
|
||||
// Qualifier returns the qualifier which must be used to refer to types
|
||||
// declared in the package.
|
||||
func (p *Package) Qualifier() string {
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if p.Alias != "" {
|
||||
return p.Alias
|
||||
}
|
||||
|
||||
return p.pkg.Name()
|
||||
}
|
||||
|
||||
// Path is the full package import path (without vendor).
|
||||
func (p *Package) Path() string {
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return stripVendorPath(p.pkg.Path())
|
||||
}
|
||||
|
||||
var replacer = strings.NewReplacer(
|
||||
"go-", "",
|
||||
"-go", "",
|
||||
"-", "",
|
||||
"_", "",
|
||||
".", "",
|
||||
"@", "",
|
||||
"+", "",
|
||||
"~", "",
|
||||
)
|
||||
|
||||
// uniqueName generates a unique name for a package by concatenating
|
||||
// path components. The generated name is guaranteed to unique with an
|
||||
// appropriate level because the full package import paths themselves
|
||||
// are unique.
|
||||
func (p Package) uniqueName(lvl int) string {
|
||||
pp := strings.Split(p.Path(), "/")
|
||||
reverse(pp)
|
||||
|
||||
var name string
|
||||
for i := 0; i < min(len(pp), lvl+1); i++ {
|
||||
name = strings.ToLower(replacer.Replace(pp[i])) + name
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// stripVendorPath strips the vendor dir prefix from a package path.
|
||||
// For example we might encounter an absolute path like
|
||||
// github.com/foo/bar/vendor/github.com/pkg/errors which is resolved
|
||||
// to github.com/pkg/errors.
|
||||
func stripVendorPath(p string) string {
|
||||
parts := strings.Split(p, "/vendor/")
|
||||
if len(parts) == 1 {
|
||||
return p
|
||||
}
|
||||
return strings.TrimLeft(path.Join(parts[1:]...), "/")
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func reverse(a []string) {
|
||||
for i := len(a)/2 - 1; i >= 0; i-- {
|
||||
opp := len(a) - 1 - i
|
||||
a[i], a[opp] = a[opp], a[i]
|
||||
}
|
||||
}
|
||||
190
vendor/github.com/matryer/moq/internal/registry/registry.go
generated
vendored
190
vendor/github.com/matryer/moq/internal/registry/registry.go
generated
vendored
@ -1,190 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/types"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
// Registry encapsulates types information for the source and mock
|
||||
// destination package. For the mock package, it tracks the list of
|
||||
// imports and ensures there are no conflicts in the imported package
|
||||
// qualifiers.
|
||||
type Registry struct {
|
||||
srcPkg *packages.Package
|
||||
moqPkgPath string
|
||||
aliases map[string]string
|
||||
imports map[string]*Package
|
||||
}
|
||||
|
||||
// New loads the source package info and returns a new instance of
|
||||
// Registry.
|
||||
func New(srcDir, moqPkg string) (*Registry, error) {
|
||||
srcPkg, err := pkgInfoFromPath(
|
||||
srcDir, packages.NeedName|packages.NeedSyntax|packages.NeedTypes|packages.NeedTypesInfo|packages.NeedDeps,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't load source package: %s", err)
|
||||
}
|
||||
|
||||
return &Registry{
|
||||
srcPkg: srcPkg,
|
||||
moqPkgPath: findPkgPath(moqPkg, srcPkg),
|
||||
aliases: parseImportsAliases(srcPkg),
|
||||
imports: make(map[string]*Package),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SrcPkg returns the types info for the source package.
|
||||
func (r Registry) SrcPkg() *types.Package {
|
||||
return r.srcPkg.Types
|
||||
}
|
||||
|
||||
// SrcPkgName returns the name of the source package.
|
||||
func (r Registry) SrcPkgName() string {
|
||||
return r.srcPkg.Name
|
||||
}
|
||||
|
||||
// LookupInterface returns the underlying interface definition of the
|
||||
// given interface name.
|
||||
func (r Registry) LookupInterface(name string) (*types.Interface, error) {
|
||||
obj := r.SrcPkg().Scope().Lookup(name)
|
||||
if obj == nil {
|
||||
return nil, fmt.Errorf("interface not found: %s", name)
|
||||
}
|
||||
|
||||
if !types.IsInterface(obj.Type()) {
|
||||
return nil, fmt.Errorf("%s (%s) is not an interface", name, obj.Type())
|
||||
}
|
||||
|
||||
return obj.Type().Underlying().(*types.Interface).Complete(), nil
|
||||
}
|
||||
|
||||
// MethodScope returns a new MethodScope.
|
||||
func (r *Registry) MethodScope() *MethodScope {
|
||||
return &MethodScope{
|
||||
registry: r,
|
||||
moqPkgPath: r.moqPkgPath,
|
||||
conflicted: map[string]bool{},
|
||||
}
|
||||
}
|
||||
|
||||
// AddImport adds the given package to the set of imports. It generates a
|
||||
// suitable alias if there are any conflicts with previously imported
|
||||
// packages.
|
||||
func (r *Registry) AddImport(pkg *types.Package) *Package {
|
||||
path := stripVendorPath(pkg.Path())
|
||||
if path == r.moqPkgPath {
|
||||
return nil
|
||||
}
|
||||
|
||||
if imprt, ok := r.imports[path]; ok {
|
||||
return imprt
|
||||
}
|
||||
|
||||
imprt := Package{pkg: pkg, Alias: r.aliases[path]}
|
||||
|
||||
if conflict, ok := r.searchImport(imprt.Qualifier()); ok {
|
||||
resolveImportConflict(&imprt, conflict, 0)
|
||||
}
|
||||
|
||||
r.imports[path] = &imprt
|
||||
return &imprt
|
||||
}
|
||||
|
||||
// Imports returns the list of imported packages. The list is sorted by
|
||||
// path.
|
||||
func (r Registry) Imports() []*Package {
|
||||
imports := make([]*Package, 0, len(r.imports))
|
||||
for _, imprt := range r.imports {
|
||||
imports = append(imports, imprt)
|
||||
}
|
||||
sort.Slice(imports, func(i, j int) bool {
|
||||
return imports[i].Path() < imports[j].Path()
|
||||
})
|
||||
return imports
|
||||
}
|
||||
|
||||
func (r Registry) searchImport(name string) (*Package, bool) {
|
||||
for _, imprt := range r.imports {
|
||||
if imprt.Qualifier() == name {
|
||||
return imprt, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func pkgInfoFromPath(srcDir string, mode packages.LoadMode) (*packages.Package, error) {
|
||||
pkgs, err := packages.Load(&packages.Config{
|
||||
Mode: mode,
|
||||
Dir: srcDir,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(pkgs) == 0 {
|
||||
return nil, errors.New("package not found")
|
||||
}
|
||||
if len(pkgs) > 1 {
|
||||
return nil, errors.New("found more than one package")
|
||||
}
|
||||
if errs := pkgs[0].Errors; len(errs) != 0 {
|
||||
if len(errs) == 1 {
|
||||
return nil, errs[0]
|
||||
}
|
||||
return nil, fmt.Errorf("%s (and %d more errors)", errs[0], len(errs)-1)
|
||||
}
|
||||
return pkgs[0], nil
|
||||
}
|
||||
|
||||
func findPkgPath(pkgInputVal string, srcPkg *packages.Package) string {
|
||||
if pkgInputVal == "" {
|
||||
return srcPkg.PkgPath
|
||||
}
|
||||
if pkgInDir(srcPkg.PkgPath, pkgInputVal) {
|
||||
return srcPkg.PkgPath
|
||||
}
|
||||
subdirectoryPath := filepath.Join(srcPkg.PkgPath, pkgInputVal)
|
||||
if pkgInDir(subdirectoryPath, pkgInputVal) {
|
||||
return subdirectoryPath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func pkgInDir(pkgName, dir string) bool {
|
||||
currentPkg, err := pkgInfoFromPath(dir, packages.NeedName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return currentPkg.Name == pkgName || currentPkg.Name+"_test" == pkgName
|
||||
}
|
||||
|
||||
func parseImportsAliases(pkg *packages.Package) map[string]string {
|
||||
aliases := make(map[string]string)
|
||||
for _, syntax := range pkg.Syntax {
|
||||
for _, imprt := range syntax.Imports {
|
||||
if imprt.Name != nil && imprt.Name.Name != "." && imprt.Name.Name != "_" {
|
||||
aliases[strings.Trim(imprt.Path.Value, `"`)] = imprt.Name.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
return aliases
|
||||
}
|
||||
|
||||
// resolveImportConflict generates and assigns a unique alias for
|
||||
// packages with conflicting qualifiers.
|
||||
func resolveImportConflict(a, b *Package, lvl int) {
|
||||
u1, u2 := a.uniqueName(lvl), b.uniqueName(lvl)
|
||||
if u1 != u2 {
|
||||
a.Alias, b.Alias = u1, u2
|
||||
return
|
||||
}
|
||||
|
||||
resolveImportConflict(a, b, lvl+1)
|
||||
}
|
||||
146
vendor/github.com/matryer/moq/internal/registry/var.go
generated
vendored
146
vendor/github.com/matryer/moq/internal/registry/var.go
generated
vendored
@ -1,146 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Var represents a method variable/parameter.
|
||||
//
|
||||
// It should be created using a method scope instance.
|
||||
type Var struct {
|
||||
vr *types.Var
|
||||
imports map[string]*Package
|
||||
moqPkgPath string
|
||||
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsSlice returns whether the type (or the underlying type) is a slice.
|
||||
func (v Var) IsSlice() bool {
|
||||
_, ok := v.vr.Type().Underlying().(*types.Slice)
|
||||
return ok
|
||||
}
|
||||
|
||||
// TypeString returns the variable type with the package qualifier in the
|
||||
// format 'pkg.Type'.
|
||||
func (v Var) TypeString() string {
|
||||
return types.TypeString(v.vr.Type(), v.packageQualifier)
|
||||
}
|
||||
|
||||
// packageQualifier is a types.Qualifier.
|
||||
func (v Var) packageQualifier(pkg *types.Package) string {
|
||||
path := stripVendorPath(pkg.Path())
|
||||
if v.moqPkgPath != "" && v.moqPkgPath == path {
|
||||
return ""
|
||||
}
|
||||
|
||||
return v.imports[path].Qualifier()
|
||||
}
|
||||
|
||||
func varName(vr *types.Var, suffix string) string {
|
||||
name := vr.Name()
|
||||
if name != "" && name != "_" {
|
||||
return name + suffix
|
||||
}
|
||||
|
||||
name = varNameForType(vr.Type()) + suffix
|
||||
|
||||
switch name {
|
||||
case "mock", "callInfo", "break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct",
|
||||
"chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for",
|
||||
"import", "return", "var",
|
||||
// avoid shadowing basic types
|
||||
"string", "bool", "byte", "rune", "uintptr",
|
||||
"int", "int8", "int16", "int32", "int64",
|
||||
"uint", "uint8", "uint16", "uint32", "uint64",
|
||||
"float32", "float64", "complex64", "complex128":
|
||||
name += "MoqParam"
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// varNameForType generates a name for the variable using the type
|
||||
// information.
|
||||
//
|
||||
// Examples:
|
||||
// - string -> s
|
||||
// - int -> n
|
||||
// - chan int -> intCh
|
||||
// - []a.MyType -> myTypes
|
||||
// - map[string]int -> stringToInt
|
||||
// - error -> err
|
||||
// - a.MyType -> myType
|
||||
func varNameForType(t types.Type) string {
|
||||
nestedType := func(t types.Type) string {
|
||||
if t, ok := t.(*types.Basic); ok {
|
||||
return deCapitalise(t.String())
|
||||
}
|
||||
return varNameForType(t)
|
||||
}
|
||||
|
||||
switch t := t.(type) {
|
||||
case *types.Named:
|
||||
if t.Obj().Name() == "error" {
|
||||
return "err"
|
||||
}
|
||||
|
||||
name := deCapitalise(t.Obj().Name())
|
||||
if name == t.Obj().Name() {
|
||||
name += "MoqParam"
|
||||
}
|
||||
|
||||
return name
|
||||
|
||||
case *types.Basic:
|
||||
return basicTypeVarName(t)
|
||||
|
||||
case *types.Array:
|
||||
return nestedType(t.Elem()) + "s"
|
||||
|
||||
case *types.Slice:
|
||||
return nestedType(t.Elem()) + "s"
|
||||
|
||||
case *types.Struct: // anonymous struct
|
||||
return "val"
|
||||
|
||||
case *types.Pointer:
|
||||
return varNameForType(t.Elem())
|
||||
|
||||
case *types.Signature:
|
||||
return "fn"
|
||||
|
||||
case *types.Interface: // anonymous interface
|
||||
return "ifaceVal"
|
||||
|
||||
case *types.Map:
|
||||
return nestedType(t.Key()) + "To" + capitalise(nestedType(t.Elem()))
|
||||
|
||||
case *types.Chan:
|
||||
return nestedType(t.Elem()) + "Ch"
|
||||
}
|
||||
|
||||
return "v"
|
||||
}
|
||||
|
||||
func basicTypeVarName(b *types.Basic) string {
|
||||
switch b.Info() {
|
||||
case types.IsBoolean:
|
||||
return "b"
|
||||
|
||||
case types.IsInteger:
|
||||
return "n"
|
||||
|
||||
case types.IsFloat:
|
||||
return "f"
|
||||
|
||||
case types.IsString:
|
||||
return "s"
|
||||
}
|
||||
|
||||
return "v"
|
||||
}
|
||||
|
||||
func capitalise(s string) string { return strings.ToUpper(s[:1]) + s[1:] }
|
||||
func deCapitalise(s string) string { return strings.ToLower(s[:1]) + s[1:] }
|
||||
190
vendor/github.com/matryer/moq/internal/template/template.go
generated
vendored
190
vendor/github.com/matryer/moq/internal/template/template.go
generated
vendored
@ -1,190 +0,0 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/matryer/moq/internal/registry"
|
||||
)
|
||||
|
||||
// Template is the Moq template. It is capable of generating the Moq
|
||||
// implementation for the given template.Data.
|
||||
type Template struct {
|
||||
tmpl *template.Template
|
||||
}
|
||||
|
||||
// New returns a new instance of Template.
|
||||
func New() (Template, error) {
|
||||
tmpl, err := template.New("moq").Funcs(templateFuncs).Parse(moqTemplate)
|
||||
if err != nil {
|
||||
return Template{}, err
|
||||
}
|
||||
|
||||
return Template{tmpl: tmpl}, nil
|
||||
}
|
||||
|
||||
// Execute generates and writes the Moq implementation for the given
|
||||
// data.
|
||||
func (t Template) Execute(w io.Writer, data Data) error {
|
||||
return t.tmpl.Execute(w, data)
|
||||
}
|
||||
|
||||
// moqTemplate is the template for mocked code.
|
||||
// language=GoTemplate
|
||||
var moqTemplate = `// Code generated by moq; DO NOT EDIT.
|
||||
// github.com/matryer/moq
|
||||
|
||||
package {{.PkgName}}
|
||||
|
||||
import (
|
||||
{{- range .Imports}}
|
||||
{{. | ImportStatement}}
|
||||
{{- end}}
|
||||
)
|
||||
|
||||
{{range $i, $mock := .Mocks -}}
|
||||
|
||||
{{- if not $.SkipEnsure -}}
|
||||
// Ensure, that {{.MockName}} does implement {{$.SrcPkgQualifier}}{{.InterfaceName}}.
|
||||
// If this is not the case, regenerate this file with moq.
|
||||
var _ {{$.SrcPkgQualifier}}{{.InterfaceName}} = &{{.MockName}}{}
|
||||
{{- end}}
|
||||
|
||||
// {{.MockName}} is a mock implementation of {{$.SrcPkgQualifier}}{{.InterfaceName}}.
|
||||
//
|
||||
// func TestSomethingThatUses{{.InterfaceName}}(t *testing.T) {
|
||||
//
|
||||
// // make and configure a mocked {{$.SrcPkgQualifier}}{{.InterfaceName}}
|
||||
// mocked{{.InterfaceName}} := &{{.MockName}}{
|
||||
{{- range .Methods}}
|
||||
// {{.Name}}Func: func({{.ArgList}}) {{.ReturnArgTypeList}} {
|
||||
// panic("mock out the {{.Name}} method")
|
||||
// },
|
||||
{{- end}}
|
||||
// }
|
||||
//
|
||||
// // use mocked{{.InterfaceName}} in code that requires {{$.SrcPkgQualifier}}{{.InterfaceName}}
|
||||
// // and then make assertions.
|
||||
//
|
||||
// }
|
||||
type {{.MockName}} struct {
|
||||
{{- range .Methods}}
|
||||
// {{.Name}}Func mocks the {{.Name}} method.
|
||||
{{.Name}}Func func({{.ArgList}}) {{.ReturnArgTypeList}}
|
||||
{{end}}
|
||||
// calls tracks calls to the methods.
|
||||
calls struct {
|
||||
{{- range .Methods}}
|
||||
// {{.Name}} holds details about calls to the {{.Name}} method.
|
||||
{{.Name}} []struct {
|
||||
{{- range .Params}}
|
||||
// {{.Name | Exported}} is the {{.Name}} argument value.
|
||||
{{.Name | Exported}} {{.TypeString}}
|
||||
{{- end}}
|
||||
}
|
||||
{{- end}}
|
||||
}
|
||||
{{- range .Methods}}
|
||||
lock{{.Name}} {{$.Imports | SyncPkgQualifier}}.RWMutex
|
||||
{{- end}}
|
||||
}
|
||||
{{range .Methods}}
|
||||
// {{.Name}} calls {{.Name}}Func.
|
||||
func (mock *{{$mock.MockName}}) {{.Name}}({{.ArgList}}) {{.ReturnArgTypeList}} {
|
||||
{{- if not $.StubImpl}}
|
||||
if mock.{{.Name}}Func == nil {
|
||||
panic("{{$mock.MockName}}.{{.Name}}Func: method is nil but {{$mock.InterfaceName}}.{{.Name}} was just called")
|
||||
}
|
||||
{{- end}}
|
||||
callInfo := struct {
|
||||
{{- range .Params}}
|
||||
{{.Name | Exported}} {{.TypeString}}
|
||||
{{- end}}
|
||||
}{
|
||||
{{- range .Params}}
|
||||
{{.Name | Exported}}: {{.Name}},
|
||||
{{- end}}
|
||||
}
|
||||
mock.lock{{.Name}}.Lock()
|
||||
mock.calls.{{.Name}} = append(mock.calls.{{.Name}}, callInfo)
|
||||
mock.lock{{.Name}}.Unlock()
|
||||
{{- if .Returns}}
|
||||
{{- if $.StubImpl}}
|
||||
if mock.{{.Name}}Func == nil {
|
||||
var (
|
||||
{{- range .Returns}}
|
||||
{{.Name}} {{.TypeString}}
|
||||
{{- end}}
|
||||
)
|
||||
return {{.ReturnArgNameList}}
|
||||
}
|
||||
{{- end}}
|
||||
return mock.{{.Name}}Func({{.ArgCallList}})
|
||||
{{- else}}
|
||||
{{- if $.StubImpl}}
|
||||
if mock.{{.Name}}Func == nil {
|
||||
return
|
||||
}
|
||||
{{- end}}
|
||||
mock.{{.Name}}Func({{.ArgCallList}})
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
// {{.Name}}Calls gets all the calls that were made to {{.Name}}.
|
||||
// Check the length with:
|
||||
// len(mocked{{$mock.InterfaceName}}.{{.Name}}Calls())
|
||||
func (mock *{{$mock.MockName}}) {{.Name}}Calls() []struct {
|
||||
{{- range .Params}}
|
||||
{{.Name | Exported}} {{.TypeString}}
|
||||
{{- end}}
|
||||
} {
|
||||
var calls []struct {
|
||||
{{- range .Params}}
|
||||
{{.Name | Exported}} {{.TypeString}}
|
||||
{{- end}}
|
||||
}
|
||||
mock.lock{{.Name}}.RLock()
|
||||
calls = mock.calls.{{.Name}}
|
||||
mock.lock{{.Name}}.RUnlock()
|
||||
return calls
|
||||
}
|
||||
{{end -}}
|
||||
{{end -}}`
|
||||
|
||||
// This list comes from the golint codebase. Golint will complain about any of
|
||||
// these being mixed-case, like "Id" instead of "ID".
|
||||
var golintInitialisms = []string{
|
||||
"ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS",
|
||||
"QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "UID", "UUID", "URI",
|
||||
"URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS",
|
||||
}
|
||||
|
||||
var templateFuncs = template.FuncMap{
|
||||
"ImportStatement": func(imprt *registry.Package) string {
|
||||
if imprt.Alias == "" {
|
||||
return `"` + imprt.Path() + `"`
|
||||
}
|
||||
return imprt.Alias + ` "` + imprt.Path() + `"`
|
||||
},
|
||||
"SyncPkgQualifier": func(imports []*registry.Package) string {
|
||||
for _, imprt := range imports {
|
||||
if imprt.Path() == "sync" {
|
||||
return imprt.Qualifier()
|
||||
}
|
||||
}
|
||||
|
||||
return "sync"
|
||||
},
|
||||
"Exported": func(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
for _, initialism := range golintInitialisms {
|
||||
if strings.ToUpper(s) == initialism {
|
||||
return initialism
|
||||
}
|
||||
}
|
||||
return strings.ToUpper(s[0:1]) + s[1:]
|
||||
},
|
||||
}
|
||||
125
vendor/github.com/matryer/moq/internal/template/template_data.go
generated
vendored
125
vendor/github.com/matryer/moq/internal/template/template_data.go
generated
vendored
@ -1,125 +0,0 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/matryer/moq/internal/registry"
|
||||
)
|
||||
|
||||
// Data is the template data used to render the Moq template.
|
||||
type Data struct {
|
||||
PkgName string
|
||||
SrcPkgQualifier string
|
||||
Imports []*registry.Package
|
||||
Mocks []MockData
|
||||
StubImpl bool
|
||||
SkipEnsure bool
|
||||
}
|
||||
|
||||
// MocksSomeMethod returns true of any one of the Mocks has at least 1
|
||||
// method.
|
||||
func (d Data) MocksSomeMethod() bool {
|
||||
for _, m := range d.Mocks {
|
||||
if len(m.Methods) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MockData is the data used to generate a mock for some interface.
|
||||
type MockData struct {
|
||||
InterfaceName string
|
||||
MockName string
|
||||
Methods []MethodData
|
||||
}
|
||||
|
||||
// MethodData is the data which represents a method on some interface.
|
||||
type MethodData struct {
|
||||
Name string
|
||||
Params []ParamData
|
||||
Returns []ParamData
|
||||
}
|
||||
|
||||
// ArgList is the string representation of method parameters, ex:
|
||||
// 's string, n int, foo bar.Baz'.
|
||||
func (m MethodData) ArgList() string {
|
||||
params := make([]string, len(m.Params))
|
||||
for i, p := range m.Params {
|
||||
params[i] = p.MethodArg()
|
||||
}
|
||||
return strings.Join(params, ", ")
|
||||
}
|
||||
|
||||
// ArgCallList is the string representation of method call parameters,
|
||||
// ex: 's, n, foo'. In case of a last variadic parameter, it will be of
|
||||
// the format 's, n, foos...'
|
||||
func (m MethodData) ArgCallList() string {
|
||||
params := make([]string, len(m.Params))
|
||||
for i, p := range m.Params {
|
||||
params[i] = p.CallName()
|
||||
}
|
||||
return strings.Join(params, ", ")
|
||||
}
|
||||
|
||||
// ReturnArgTypeList is the string representation of method return
|
||||
// types, ex: 'bar.Baz', '(string, error)'.
|
||||
func (m MethodData) ReturnArgTypeList() string {
|
||||
params := make([]string, len(m.Returns))
|
||||
for i, p := range m.Returns {
|
||||
params[i] = p.TypeString()
|
||||
}
|
||||
if len(m.Returns) > 1 {
|
||||
return fmt.Sprintf("(%s)", strings.Join(params, ", "))
|
||||
}
|
||||
return strings.Join(params, ", ")
|
||||
}
|
||||
|
||||
// ReturnArgNameList is the string representation of values being
|
||||
// returned from the method, ex: 'foo', 's, err'.
|
||||
func (m MethodData) ReturnArgNameList() string {
|
||||
params := make([]string, len(m.Returns))
|
||||
for i, p := range m.Returns {
|
||||
params[i] = p.Name()
|
||||
}
|
||||
return strings.Join(params, ", ")
|
||||
}
|
||||
|
||||
// ParamData is the data which represents a parameter to some method of
|
||||
// an interface.
|
||||
type ParamData struct {
|
||||
Var *registry.Var
|
||||
Variadic bool
|
||||
}
|
||||
|
||||
// Name returns the name of the parameter.
|
||||
func (p ParamData) Name() string {
|
||||
return p.Var.Name
|
||||
}
|
||||
|
||||
// MethodArg is the representation of the parameter in the function
|
||||
// signature, ex: 'name a.Type'.
|
||||
func (p ParamData) MethodArg() string {
|
||||
if p.Variadic {
|
||||
return fmt.Sprintf("%s ...%s", p.Name(), p.TypeString()[2:])
|
||||
}
|
||||
return fmt.Sprintf("%s %s", p.Name(), p.TypeString())
|
||||
}
|
||||
|
||||
// CallName returns the string representation of the parameter to be
|
||||
// used for a method call. For a variadic paramter, it will be of the
|
||||
// format 'foos...'.
|
||||
func (p ParamData) CallName() string {
|
||||
if p.Variadic {
|
||||
return p.Name() + "..."
|
||||
}
|
||||
return p.Name()
|
||||
}
|
||||
|
||||
// TypeString returns the string representation of the type of the
|
||||
// parameter.
|
||||
func (p ParamData) TypeString() string {
|
||||
return p.Var.TypeString()
|
||||
}
|
||||
109
vendor/github.com/matryer/moq/main.go
generated
vendored
109
vendor/github.com/matryer/moq/main.go
generated
vendored
@ -1,109 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/matryer/moq/pkg/moq"
|
||||
)
|
||||
|
||||
// Version is the command version, injected at build time.
|
||||
var Version string = "dev"
|
||||
|
||||
type userFlags struct {
|
||||
outFile string
|
||||
pkgName string
|
||||
formatter string
|
||||
stubImpl bool
|
||||
skipEnsure bool
|
||||
remove bool
|
||||
args []string
|
||||
}
|
||||
|
||||
func main() {
|
||||
var flags userFlags
|
||||
flag.StringVar(&flags.outFile, "out", "", "output file (default stdout)")
|
||||
flag.StringVar(&flags.pkgName, "pkg", "", "package name (default will infer)")
|
||||
flag.StringVar(&flags.formatter, "fmt", "", "go pretty-printer: gofmt, goimports or noop (default gofmt)")
|
||||
flag.BoolVar(&flags.stubImpl, "stub", false,
|
||||
"return zero values when no mock implementation is provided, do not panic")
|
||||
printVersion := flag.Bool("version", false, "show the version for moq")
|
||||
flag.BoolVar(&flags.skipEnsure, "skip-ensure", false,
|
||||
"suppress mock implementation check, avoid import cycle if mocks generated outside of the tested package")
|
||||
flag.BoolVar(&flags.remove, "rm", false, "first remove output file, if it exists")
|
||||
|
||||
flag.Usage = func() {
|
||||
fmt.Println(`moq [flags] source-dir interface [interface2 [interface3 [...]]]`)
|
||||
flag.PrintDefaults()
|
||||
fmt.Println(`Specifying an alias for the mock is also supported with the format 'interface:alias'`)
|
||||
fmt.Println(`Ex: moq -pkg different . MyInterface:MyMock`)
|
||||
}
|
||||
|
||||
flag.Parse()
|
||||
flags.args = flag.Args()
|
||||
|
||||
if *printVersion {
|
||||
fmt.Printf("moq version %s\n", Version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if err := run(flags); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run(flags userFlags) error {
|
||||
if len(flags.args) < 2 {
|
||||
return errors.New("not enough arguments")
|
||||
}
|
||||
|
||||
if flags.remove && flags.outFile != "" {
|
||||
if err := os.Remove(flags.outFile); err != nil {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
var out io.Writer = os.Stdout
|
||||
if flags.outFile != "" {
|
||||
out = &buf
|
||||
}
|
||||
|
||||
srcDir, args := flags.args[0], flags.args[1:]
|
||||
m, err := moq.New(moq.Config{
|
||||
SrcDir: srcDir,
|
||||
PkgName: flags.pkgName,
|
||||
Formatter: flags.formatter,
|
||||
StubImpl: flags.stubImpl,
|
||||
SkipEnsure: flags.skipEnsure,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = m.Mock(out, args...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flags.outFile == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// create the file
|
||||
err = os.MkdirAll(filepath.Dir(flags.outFile), 0750)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(flags.outFile, buf.Bytes(), 0600)
|
||||
}
|
||||
BIN
vendor/github.com/matryer/moq/moq-logo-small.png
generated
vendored
BIN
vendor/github.com/matryer/moq/moq-logo-small.png
generated
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB |
BIN
vendor/github.com/matryer/moq/moq-logo.png
generated
vendored
BIN
vendor/github.com/matryer/moq/moq-logo.png
generated
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
31
vendor/github.com/matryer/moq/pkg/moq/formatter.go
generated
vendored
31
vendor/github.com/matryer/moq/pkg/moq/formatter.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
package moq
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/format"
|
||||
|
||||
"golang.org/x/tools/imports"
|
||||
)
|
||||
|
||||
func goimports(src []byte) ([]byte, error) {
|
||||
formatted, err := imports.Process("filename", src, &imports.Options{
|
||||
TabWidth: 8,
|
||||
TabIndent: true,
|
||||
Comments: true,
|
||||
Fragment: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("goimports: %s", err)
|
||||
}
|
||||
|
||||
return formatted, nil
|
||||
}
|
||||
|
||||
func gofmt(src []byte) ([]byte, error) {
|
||||
formatted, err := format.Source(src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("go/format: %s", err)
|
||||
}
|
||||
|
||||
return formatted, nil
|
||||
}
|
||||
171
vendor/github.com/matryer/moq/pkg/moq/moq.go
generated
vendored
171
vendor/github.com/matryer/moq/pkg/moq/moq.go
generated
vendored
@ -1,171 +0,0 @@
|
||||
package moq
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"go/types"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/matryer/moq/internal/registry"
|
||||
"github.com/matryer/moq/internal/template"
|
||||
)
|
||||
|
||||
// Mocker can generate mock structs.
|
||||
type Mocker struct {
|
||||
cfg Config
|
||||
|
||||
registry *registry.Registry
|
||||
tmpl template.Template
|
||||
}
|
||||
|
||||
// Config specifies details about how interfaces should be mocked.
|
||||
// SrcDir is the only field which needs be specified.
|
||||
type Config struct {
|
||||
SrcDir string
|
||||
PkgName string
|
||||
Formatter string
|
||||
StubImpl bool
|
||||
SkipEnsure bool
|
||||
}
|
||||
|
||||
// New makes a new Mocker for the specified package directory.
|
||||
func New(cfg Config) (*Mocker, error) {
|
||||
reg, err := registry.New(cfg.SrcDir, cfg.PkgName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tmpl, err := template.New()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Mocker{
|
||||
cfg: cfg,
|
||||
registry: reg,
|
||||
tmpl: tmpl,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Mock generates a mock for the specified interface name.
|
||||
func (m *Mocker) Mock(w io.Writer, namePairs ...string) error {
|
||||
if len(namePairs) == 0 {
|
||||
return errors.New("must specify one interface")
|
||||
}
|
||||
|
||||
mocks := make([]template.MockData, len(namePairs))
|
||||
for i, np := range namePairs {
|
||||
name, mockName := parseInterfaceName(np)
|
||||
iface, err := m.registry.LookupInterface(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
methods := make([]template.MethodData, iface.NumMethods())
|
||||
for j := 0; j < iface.NumMethods(); j++ {
|
||||
methods[j] = m.methodData(iface.Method(j))
|
||||
}
|
||||
|
||||
mocks[i] = template.MockData{
|
||||
InterfaceName: name,
|
||||
MockName: mockName,
|
||||
Methods: methods,
|
||||
}
|
||||
}
|
||||
|
||||
data := template.Data{
|
||||
PkgName: m.mockPkgName(),
|
||||
Mocks: mocks,
|
||||
StubImpl: m.cfg.StubImpl,
|
||||
SkipEnsure: m.cfg.SkipEnsure,
|
||||
}
|
||||
|
||||
if data.MocksSomeMethod() {
|
||||
m.registry.AddImport(types.NewPackage("sync", "sync"))
|
||||
}
|
||||
if m.registry.SrcPkgName() != m.mockPkgName() {
|
||||
data.SrcPkgQualifier = m.registry.SrcPkgName() + "."
|
||||
if !m.cfg.SkipEnsure {
|
||||
imprt := m.registry.AddImport(m.registry.SrcPkg())
|
||||
data.SrcPkgQualifier = imprt.Qualifier() + "."
|
||||
}
|
||||
}
|
||||
|
||||
data.Imports = m.registry.Imports()
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := m.tmpl.Execute(&buf, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
formatted, err := m.format(buf.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := w.Write(formatted); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Mocker) methodData(f *types.Func) template.MethodData {
|
||||
sig := f.Type().(*types.Signature)
|
||||
|
||||
scope := m.registry.MethodScope()
|
||||
n := sig.Params().Len()
|
||||
params := make([]template.ParamData, n)
|
||||
for i := 0; i < n; i++ {
|
||||
p := template.ParamData{
|
||||
Var: scope.AddVar(sig.Params().At(i), ""),
|
||||
}
|
||||
p.Variadic = sig.Variadic() && i == n-1 && p.Var.IsSlice() // check for final variadic argument
|
||||
|
||||
params[i] = p
|
||||
}
|
||||
|
||||
n = sig.Results().Len()
|
||||
results := make([]template.ParamData, n)
|
||||
for i := 0; i < n; i++ {
|
||||
results[i] = template.ParamData{
|
||||
Var: scope.AddVar(sig.Results().At(i), "Out"),
|
||||
}
|
||||
}
|
||||
|
||||
return template.MethodData{
|
||||
Name: f.Name(),
|
||||
Params: params,
|
||||
Returns: results,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Mocker) mockPkgName() string {
|
||||
if m.cfg.PkgName != "" {
|
||||
return m.cfg.PkgName
|
||||
}
|
||||
|
||||
return m.registry.SrcPkgName()
|
||||
}
|
||||
|
||||
func (m *Mocker) format(src []byte) ([]byte, error) {
|
||||
switch m.cfg.Formatter {
|
||||
case "goimports":
|
||||
return goimports(src)
|
||||
|
||||
case "noop":
|
||||
return src, nil
|
||||
}
|
||||
|
||||
return gofmt(src)
|
||||
}
|
||||
|
||||
func parseInterfaceName(namePair string) (ifaceName, mockName string) {
|
||||
parts := strings.SplitN(namePair, ":", 2)
|
||||
if len(parts) == 2 {
|
||||
return parts[0], parts[1]
|
||||
}
|
||||
|
||||
ifaceName = parts[0]
|
||||
return ifaceName, ifaceName + "Mock"
|
||||
}
|
||||
BIN
vendor/github.com/matryer/moq/preview.png
generated
vendored
BIN
vendor/github.com/matryer/moq/preview.png
generated
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 726 KiB |
36
vendor/github.com/matryer/moq/releasing.md
generated
vendored
36
vendor/github.com/matryer/moq/releasing.md
generated
vendored
@ -1,36 +0,0 @@
|
||||
# Releasing
|
||||
|
||||
This tool uses Go Releaser to manage release builds.
|
||||
|
||||
## Setup
|
||||
|
||||
Install Go Releaser.
|
||||
|
||||
```bash
|
||||
brew install goreleaser/tap/goreleaser
|
||||
```
|
||||
|
||||
* Make a [New personal access token on GitHub](https://github.com/settings/tokens/new) and set it as the `GITHUB_TOKEN` environment variable
|
||||
|
||||
## Releasing
|
||||
|
||||
Tag the repo:
|
||||
|
||||
```bash
|
||||
$ git tag -a v0.1.0 -m "release tag."
|
||||
$ git push origin v0.1.0
|
||||
```
|
||||
|
||||
Then:
|
||||
|
||||
```bash
|
||||
GITHUB_TOKEN=xxx goreleaser --rm-dist
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
To test and verify changes to Go Releaser config, use the following:
|
||||
|
||||
```bash
|
||||
goreleaser --snapshot --skip-publish --rm-dist
|
||||
```
|
||||
6
vendor/github.com/prometheus/client_golang/prometheus/collector.go
generated
vendored
6
vendor/github.com/prometheus/client_golang/prometheus/collector.go
generated
vendored
@ -69,9 +69,9 @@ type Collector interface {
|
||||
// If a Collector collects the same metrics throughout its lifetime, its
|
||||
// Describe method can simply be implemented as:
|
||||
//
|
||||
// func (c customCollector) Describe(ch chan<- *Desc) {
|
||||
// DescribeByCollect(c, ch)
|
||||
// }
|
||||
// func (c customCollector) Describe(ch chan<- *Desc) {
|
||||
// DescribeByCollect(c, ch)
|
||||
// }
|
||||
//
|
||||
// However, this will not work if the metrics collected change dynamically over
|
||||
// the lifetime of the Collector in a way that their combined set of descriptors
|
||||
|
||||
2
vendor/github.com/prometheus/client_golang/prometheus/counter.go
generated
vendored
2
vendor/github.com/prometheus/client_golang/prometheus/counter.go
generated
vendored
@ -51,7 +51,7 @@ type Counter interface {
|
||||
// will lead to a valid (label-less) exemplar. But if Labels is nil, the current
|
||||
// exemplar is left in place. AddWithExemplar panics if the value is < 0, if any
|
||||
// of the provided labels are invalid, or if the provided labels contain more
|
||||
// than 64 runes in total.
|
||||
// than 128 runes in total.
|
||||
type ExemplarAdder interface {
|
||||
AddWithExemplar(value float64, exemplar Labels)
|
||||
}
|
||||
|
||||
5
vendor/github.com/prometheus/client_golang/prometheus/desc.go
generated
vendored
5
vendor/github.com/prometheus/client_golang/prometheus/desc.go
generated
vendored
@ -20,6 +20,9 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/cespare/xxhash/v2"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/internal"
|
||||
|
||||
//nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility.
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/prometheus/common/model"
|
||||
@ -154,7 +157,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
|
||||
Value: proto.String(v),
|
||||
})
|
||||
}
|
||||
sort.Sort(labelPairSorter(d.constLabelPairs))
|
||||
sort.Sort(internal.LabelPairSorter(d.constLabelPairs))
|
||||
return d
|
||||
}
|
||||
|
||||
|
||||
26
vendor/github.com/prometheus/client_golang/prometheus/get_pid.go
generated
vendored
Normal file
26
vendor/github.com/prometheus/client_golang/prometheus/get_pid.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !js || wasm
|
||||
// +build !js wasm
|
||||
|
||||
package prometheus
|
||||
|
||||
import "os"
|
||||
|
||||
func getPIDFn() func() (int, error) {
|
||||
pid := os.Getpid()
|
||||
return func() (int, error) {
|
||||
return pid, nil
|
||||
}
|
||||
}
|
||||
23
vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go
generated
vendored
Normal file
23
vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2015 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build js && !wasm
|
||||
// +build js,!wasm
|
||||
|
||||
package prometheus
|
||||
|
||||
func getPIDFn() func() (int, error) {
|
||||
return func() (int, error) {
|
||||
return 1, nil
|
||||
}
|
||||
}
|
||||
12
vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
generated
vendored
12
vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
generated
vendored
@ -19,6 +19,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats.
|
||||
// From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so
|
||||
// while eval closure works on runtime.MemStats, the struct from Go 1.17+ is
|
||||
// populated using runtime/metrics.
|
||||
func goRuntimeMemStats() memStatsMetrics {
|
||||
return memStatsMetrics{
|
||||
{
|
||||
@ -224,7 +228,7 @@ func newBaseGoCollector() baseGoCollector {
|
||||
"A summary of the pause duration of garbage collection cycles.",
|
||||
nil, nil),
|
||||
gcLastTimeDesc: NewDesc(
|
||||
memstatNamespace("last_gc_time_seconds"),
|
||||
"go_memstats_last_gc_time_seconds",
|
||||
"Number of seconds since 1970 of last garbage collection.",
|
||||
nil, nil),
|
||||
goInfoDesc: NewDesc(
|
||||
@ -246,8 +250,9 @@ func (c *baseGoCollector) Describe(ch chan<- *Desc) {
|
||||
// Collect returns the current state of all metrics of the collector.
|
||||
func (c *baseGoCollector) Collect(ch chan<- Metric) {
|
||||
ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))
|
||||
n, _ := runtime.ThreadCreateProfile(nil)
|
||||
ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n))
|
||||
|
||||
n := getRuntimeNumThreads()
|
||||
ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, n)
|
||||
|
||||
var stats debug.GCStats
|
||||
stats.PauseQuantiles = make([]time.Duration, 5)
|
||||
@ -269,7 +274,6 @@ func memstatNamespace(s string) string {
|
||||
|
||||
// memStatsMetrics provide description, evaluator, runtime/metrics name, and
|
||||
// value type for memstat metrics.
|
||||
// TODO(bwplotka): Remove with end Go 1.16 EOL and replace with runtime/metrics.Description
|
||||
type memStatsMetrics []struct {
|
||||
desc *Desc
|
||||
eval func(*runtime.MemStats) float64
|
||||
|
||||
249
vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go
generated
vendored
249
vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go
generated
vendored
@ -31,9 +31,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// constants for strings referenced more than once.
|
||||
goGCHeapTinyAllocsObjects = "/gc/heap/tiny/allocs:objects"
|
||||
goGCHeapAllocsObjects = "/gc/heap/allocs:objects"
|
||||
goGCHeapFreesObjects = "/gc/heap/frees:objects"
|
||||
goGCHeapFreesBytes = "/gc/heap/frees:bytes"
|
||||
goGCHeapAllocsBytes = "/gc/heap/allocs:bytes"
|
||||
goGCHeapObjects = "/gc/heap/objects:objects"
|
||||
goGCHeapGoalBytes = "/gc/heap/goal:bytes"
|
||||
@ -53,8 +55,9 @@ const (
|
||||
goMemoryClassesOtherBytes = "/memory/classes/other:bytes"
|
||||
)
|
||||
|
||||
// runtime/metrics names required for runtimeMemStats like logic.
|
||||
var rmForMemStats = []string{goGCHeapTinyAllocsObjects,
|
||||
// rmNamesForMemStatsMetrics represents runtime/metrics names required to populate goRuntimeMemStats from like logic.
|
||||
var rmNamesForMemStatsMetrics = []string{
|
||||
goGCHeapTinyAllocsObjects,
|
||||
goGCHeapAllocsObjects,
|
||||
goGCHeapFreesObjects,
|
||||
goGCHeapAllocsBytes,
|
||||
@ -89,74 +92,90 @@ func bestEffortLookupRM(lookup []string) []metrics.Description {
|
||||
}
|
||||
|
||||
type goCollector struct {
|
||||
opt GoCollectorOptions
|
||||
base baseGoCollector
|
||||
|
||||
// mu protects updates to all fields ensuring a consistent
|
||||
// snapshot is always produced by Collect.
|
||||
mu sync.Mutex
|
||||
|
||||
// rm... fields all pertain to the runtime/metrics package.
|
||||
rmSampleBuf []metrics.Sample
|
||||
rmSampleMap map[string]*metrics.Sample
|
||||
rmMetrics []collectorMetric
|
||||
// Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed).
|
||||
sampleBuf []metrics.Sample
|
||||
// sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums.
|
||||
sampleMap map[string]*metrics.Sample
|
||||
|
||||
// rmExposedMetrics represents all runtime/metrics package metrics
|
||||
// that were configured to be exposed.
|
||||
rmExposedMetrics []collectorMetric
|
||||
rmExactSumMapForHist map[string]string
|
||||
|
||||
// With Go 1.17, the runtime/metrics package was introduced.
|
||||
// From that point on, metric names produced by the runtime/metrics
|
||||
// package could be generated from runtime/metrics names. However,
|
||||
// these differ from the old names for the same values.
|
||||
//
|
||||
// This field exist to export the same values under the old names
|
||||
// This field exists to export the same values under the old names
|
||||
// as well.
|
||||
msMetrics memStatsMetrics
|
||||
msMetrics memStatsMetrics
|
||||
msMetricsEnabled bool
|
||||
}
|
||||
|
||||
const (
|
||||
// Those are not exposed due to need to move Go collector to another package in v2.
|
||||
// See issue https://github.com/prometheus/client_golang/issues/1030.
|
||||
goRuntimeMemStatsCollection uint32 = 1 << iota
|
||||
goRuntimeMetricsCollection
|
||||
)
|
||||
|
||||
// GoCollectorOptions should not be used be directly by anything, except `collectors` package.
|
||||
// Use it via collectors package instead. See issue
|
||||
// https://github.com/prometheus/client_golang/issues/1030.
|
||||
//
|
||||
// Deprecated: Use collectors.WithGoCollections
|
||||
type GoCollectorOptions struct {
|
||||
// EnabledCollection sets what type of collections collector should expose on top of base collection.
|
||||
// By default it's goMemStatsCollection | goRuntimeMetricsCollection.
|
||||
EnabledCollections uint32
|
||||
type rmMetricDesc struct {
|
||||
metrics.Description
|
||||
}
|
||||
|
||||
func (c GoCollectorOptions) isEnabled(flag uint32) bool {
|
||||
return c.EnabledCollections&flag != 0
|
||||
func matchRuntimeMetricsRules(rules []internal.GoCollectorRule) []rmMetricDesc {
|
||||
var descs []rmMetricDesc
|
||||
for _, d := range metrics.All() {
|
||||
var (
|
||||
deny = true
|
||||
desc rmMetricDesc
|
||||
)
|
||||
|
||||
for _, r := range rules {
|
||||
if !r.Matcher.MatchString(d.Name) {
|
||||
continue
|
||||
}
|
||||
deny = r.Deny
|
||||
}
|
||||
if deny {
|
||||
continue
|
||||
}
|
||||
|
||||
desc.Description = d
|
||||
descs = append(descs, desc)
|
||||
}
|
||||
return descs
|
||||
}
|
||||
|
||||
const defaultGoCollections = goRuntimeMemStatsCollection
|
||||
func defaultGoCollectorOptions() internal.GoCollectorOptions {
|
||||
return internal.GoCollectorOptions{
|
||||
RuntimeMetricSumForHist: map[string]string{
|
||||
"/gc/heap/allocs-by-size:bytes": goGCHeapAllocsBytes,
|
||||
"/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes,
|
||||
},
|
||||
RuntimeMetricRules: []internal.GoCollectorRule{
|
||||
//{Matcher: regexp.MustCompile("")},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewGoCollector is the obsolete version of collectors.NewGoCollector.
|
||||
// See there for documentation.
|
||||
//
|
||||
// Deprecated: Use collectors.NewGoCollector instead.
|
||||
func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector {
|
||||
opt := GoCollectorOptions{EnabledCollections: defaultGoCollections}
|
||||
func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
|
||||
opt := defaultGoCollectorOptions()
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
var descriptions []metrics.Description
|
||||
if opt.isEnabled(goRuntimeMetricsCollection) {
|
||||
descriptions = metrics.All()
|
||||
} else if opt.isEnabled(goRuntimeMemStatsCollection) {
|
||||
descriptions = bestEffortLookupRM(rmForMemStats)
|
||||
}
|
||||
exposedDescriptions := matchRuntimeMetricsRules(opt.RuntimeMetricRules)
|
||||
|
||||
// Collect all histogram samples so that we can get their buckets.
|
||||
// The API guarantees that the buckets are always fixed for the lifetime
|
||||
// of the process.
|
||||
var histograms []metrics.Sample
|
||||
for _, d := range descriptions {
|
||||
for _, d := range exposedDescriptions {
|
||||
if d.Kind == metrics.KindFloat64Histogram {
|
||||
histograms = append(histograms, metrics.Sample{Name: d.Name})
|
||||
}
|
||||
@ -171,13 +190,14 @@ func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector {
|
||||
bucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets
|
||||
}
|
||||
|
||||
// Generate a Desc and ValueType for each runtime/metrics metric.
|
||||
metricSet := make([]collectorMetric, 0, len(descriptions))
|
||||
sampleBuf := make([]metrics.Sample, 0, len(descriptions))
|
||||
sampleMap := make(map[string]*metrics.Sample, len(descriptions))
|
||||
for i := range descriptions {
|
||||
d := &descriptions[i]
|
||||
namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(d)
|
||||
// Generate a collector for each exposed runtime/metrics metric.
|
||||
metricSet := make([]collectorMetric, 0, len(exposedDescriptions))
|
||||
// SampleBuf is used for reading from runtime/metrics.
|
||||
// We are assuming the largest case to have stable pointers for sampleMap purposes.
|
||||
sampleBuf := make([]metrics.Sample, 0, len(exposedDescriptions)+len(opt.RuntimeMetricSumForHist)+len(rmNamesForMemStatsMetrics))
|
||||
sampleMap := make(map[string]*metrics.Sample, len(exposedDescriptions))
|
||||
for _, d := range exposedDescriptions {
|
||||
namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(&d.Description)
|
||||
if !ok {
|
||||
// Just ignore this metric; we can't do anything with it here.
|
||||
// If a user decides to use the latest version of Go, we don't want
|
||||
@ -185,19 +205,17 @@ func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector {
|
||||
continue
|
||||
}
|
||||
|
||||
// Set up sample buffer for reading, and a map
|
||||
// for quick lookup of sample values.
|
||||
sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name})
|
||||
sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1]
|
||||
|
||||
var m collectorMetric
|
||||
if d.Kind == metrics.KindFloat64Histogram {
|
||||
_, hasSum := rmExactSumMap[d.Name]
|
||||
_, hasSum := opt.RuntimeMetricSumForHist[d.Name]
|
||||
unit := d.Name[strings.IndexRune(d.Name, ':')+1:]
|
||||
m = newBatchHistogram(
|
||||
NewDesc(
|
||||
BuildFQName(namespace, subsystem, name),
|
||||
d.Description,
|
||||
d.Description.Description,
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
@ -209,30 +227,61 @@ func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector {
|
||||
Namespace: namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: name,
|
||||
Help: d.Description,
|
||||
})
|
||||
Help: d.Description.Description,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
m = NewGauge(GaugeOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: name,
|
||||
Help: d.Description,
|
||||
Help: d.Description.Description,
|
||||
})
|
||||
}
|
||||
metricSet = append(metricSet, m)
|
||||
}
|
||||
|
||||
var msMetrics memStatsMetrics
|
||||
if opt.isEnabled(goRuntimeMemStatsCollection) {
|
||||
msMetrics = goRuntimeMemStats()
|
||||
// Add exact sum metrics to sampleBuf if not added before.
|
||||
for _, h := range histograms {
|
||||
sumMetric, ok := opt.RuntimeMetricSumForHist[h.Name]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := sampleMap[sumMetric]; ok {
|
||||
continue
|
||||
}
|
||||
sampleBuf = append(sampleBuf, metrics.Sample{Name: sumMetric})
|
||||
sampleMap[sumMetric] = &sampleBuf[len(sampleBuf)-1]
|
||||
}
|
||||
|
||||
var (
|
||||
msMetrics memStatsMetrics
|
||||
msDescriptions []metrics.Description
|
||||
)
|
||||
|
||||
if !opt.DisableMemStatsLikeMetrics {
|
||||
msMetrics = goRuntimeMemStats()
|
||||
msDescriptions = bestEffortLookupRM(rmNamesForMemStatsMetrics)
|
||||
|
||||
// Check if metric was not exposed before and if not, add to sampleBuf.
|
||||
for _, mdDesc := range msDescriptions {
|
||||
if _, ok := sampleMap[mdDesc.Name]; ok {
|
||||
continue
|
||||
}
|
||||
sampleBuf = append(sampleBuf, metrics.Sample{Name: mdDesc.Name})
|
||||
sampleMap[mdDesc.Name] = &sampleBuf[len(sampleBuf)-1]
|
||||
}
|
||||
}
|
||||
|
||||
return &goCollector{
|
||||
opt: opt,
|
||||
base: newBaseGoCollector(),
|
||||
rmSampleBuf: sampleBuf,
|
||||
rmSampleMap: sampleMap,
|
||||
rmMetrics: metricSet,
|
||||
msMetrics: msMetrics,
|
||||
base: newBaseGoCollector(),
|
||||
sampleBuf: sampleBuf,
|
||||
sampleMap: sampleMap,
|
||||
rmExposedMetrics: metricSet,
|
||||
rmExactSumMapForHist: opt.RuntimeMetricSumForHist,
|
||||
msMetrics: msMetrics,
|
||||
msMetricsEnabled: !opt.DisableMemStatsLikeMetrics,
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,7 +291,7 @@ func (c *goCollector) Describe(ch chan<- *Desc) {
|
||||
for _, i := range c.msMetrics {
|
||||
ch <- i.desc
|
||||
}
|
||||
for _, m := range c.rmMetrics {
|
||||
for _, m := range c.rmExposedMetrics {
|
||||
ch <- m.Desc()
|
||||
}
|
||||
}
|
||||
@ -252,8 +301,12 @@ func (c *goCollector) Collect(ch chan<- Metric) {
|
||||
// Collect base non-memory metrics.
|
||||
c.base.Collect(ch)
|
||||
|
||||
if len(c.sampleBuf) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Collect must be thread-safe, so prevent concurrent use of
|
||||
// rmSampleBuf. Just read into rmSampleBuf but write all the data
|
||||
// sampleBuf elements. Just read into sampleBuf but write all the data
|
||||
// we get into our Metrics or MemStats.
|
||||
//
|
||||
// This lock also ensures that the Metrics we send out are all from
|
||||
@ -267,44 +320,43 @@ func (c *goCollector) Collect(ch chan<- Metric) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if len(c.rmSampleBuf) > 0 {
|
||||
// Populate runtime/metrics sample buffer.
|
||||
metrics.Read(c.rmSampleBuf)
|
||||
}
|
||||
// Populate runtime/metrics sample buffer.
|
||||
metrics.Read(c.sampleBuf)
|
||||
|
||||
if c.opt.isEnabled(goRuntimeMetricsCollection) {
|
||||
// Collect all our metrics from rmSampleBuf.
|
||||
for i, sample := range c.rmSampleBuf {
|
||||
// N.B. switch on concrete type because it's significantly more efficient
|
||||
// than checking for the Counter and Gauge interface implementations. In
|
||||
// this case, we control all the types here.
|
||||
switch m := c.rmMetrics[i].(type) {
|
||||
case *counter:
|
||||
// Guard against decreases. This should never happen, but a failure
|
||||
// to do so will result in a panic, which is a harsh consequence for
|
||||
// a metrics collection bug.
|
||||
v0, v1 := m.get(), unwrapScalarRMValue(sample.Value)
|
||||
if v1 > v0 {
|
||||
m.Add(unwrapScalarRMValue(sample.Value) - m.get())
|
||||
}
|
||||
m.Collect(ch)
|
||||
case *gauge:
|
||||
m.Set(unwrapScalarRMValue(sample.Value))
|
||||
m.Collect(ch)
|
||||
case *batchHistogram:
|
||||
m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name))
|
||||
m.Collect(ch)
|
||||
default:
|
||||
panic("unexpected metric type")
|
||||
// Collect all our runtime/metrics user chose to expose from sampleBuf (if any).
|
||||
for i, metric := range c.rmExposedMetrics {
|
||||
// We created samples for exposed metrics first in order, so indexes match.
|
||||
sample := c.sampleBuf[i]
|
||||
|
||||
// N.B. switch on concrete type because it's significantly more efficient
|
||||
// than checking for the Counter and Gauge interface implementations. In
|
||||
// this case, we control all the types here.
|
||||
switch m := metric.(type) {
|
||||
case *counter:
|
||||
// Guard against decreases. This should never happen, but a failure
|
||||
// to do so will result in a panic, which is a harsh consequence for
|
||||
// a metrics collection bug.
|
||||
v0, v1 := m.get(), unwrapScalarRMValue(sample.Value)
|
||||
if v1 > v0 {
|
||||
m.Add(unwrapScalarRMValue(sample.Value) - m.get())
|
||||
}
|
||||
m.Collect(ch)
|
||||
case *gauge:
|
||||
m.Set(unwrapScalarRMValue(sample.Value))
|
||||
m.Collect(ch)
|
||||
case *batchHistogram:
|
||||
m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name))
|
||||
m.Collect(ch)
|
||||
default:
|
||||
panic("unexpected metric type")
|
||||
}
|
||||
}
|
||||
|
||||
// ms is a dummy MemStats that we populate ourselves so that we can
|
||||
// populate the old metrics from it if goMemStatsCollection is enabled.
|
||||
if c.opt.isEnabled(goRuntimeMemStatsCollection) {
|
||||
if c.msMetricsEnabled {
|
||||
// ms is a dummy MemStats that we populate ourselves so that we can
|
||||
// populate the old metrics from it if goMemStatsCollection is enabled.
|
||||
var ms runtime.MemStats
|
||||
memStatsFromRM(&ms, c.rmSampleMap)
|
||||
memStatsFromRM(&ms, c.sampleMap)
|
||||
for _, i := range c.msMetrics {
|
||||
ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms))
|
||||
}
|
||||
@ -335,11 +387,6 @@ func unwrapScalarRMValue(v metrics.Value) float64 {
|
||||
}
|
||||
}
|
||||
|
||||
var rmExactSumMap = map[string]string{
|
||||
"/gc/heap/allocs-by-size:bytes": "/gc/heap/allocs:bytes",
|
||||
"/gc/heap/frees-by-size:bytes": "/gc/heap/frees:bytes",
|
||||
}
|
||||
|
||||
// exactSumFor takes a runtime/metrics metric name (that is assumed to
|
||||
// be of kind KindFloat64Histogram) and returns its exact sum and whether
|
||||
// its exact sum exists.
|
||||
@ -347,11 +394,11 @@ var rmExactSumMap = map[string]string{
|
||||
// The runtime/metrics API for histograms doesn't currently expose exact
|
||||
// sums, but some of the other metrics are in fact exact sums of histograms.
|
||||
func (c *goCollector) exactSumFor(rmName string) float64 {
|
||||
sumName, ok := rmExactSumMap[rmName]
|
||||
sumName, ok := c.rmExactSumMapForHist[rmName]
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
s, ok := c.rmSampleMap[sumName]
|
||||
s, ok := c.sampleMap[sumName]
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
|
||||
2
vendor/github.com/prometheus/client_golang/prometheus/histogram.go
generated
vendored
2
vendor/github.com/prometheus/client_golang/prometheus/histogram.go
generated
vendored
@ -581,11 +581,11 @@ func (h *constHistogram) Desc() *Desc {
|
||||
|
||||
func (h *constHistogram) Write(out *dto.Metric) error {
|
||||
his := &dto.Histogram{}
|
||||
|
||||
buckets := make([]*dto.Bucket, 0, len(h.buckets))
|
||||
|
||||
his.SampleCount = proto.Uint64(h.count)
|
||||
his.SampleSum = proto.Float64(h.sum)
|
||||
|
||||
for upperBound, count := range h.buckets {
|
||||
buckets = append(buckets, &dto.Bucket{
|
||||
CumulativeCount: proto.Uint64(count),
|
||||
|
||||
651
vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
generated
vendored
Normal file
651
vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
generated
vendored
Normal file
@ -0,0 +1,651 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// It provides tools to compare sequences of strings and generate textual diffs.
|
||||
//
|
||||
// Maintaining `GetUnifiedDiffString` here because original repository
|
||||
// (https://github.com/pmezard/go-difflib) is no loger maintained.
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func calculateRatio(matches, length int) float64 {
|
||||
if length > 0 {
|
||||
return 2.0 * float64(matches) / float64(length)
|
||||
}
|
||||
return 1.0
|
||||
}
|
||||
|
||||
type Match struct {
|
||||
A int
|
||||
B int
|
||||
Size int
|
||||
}
|
||||
|
||||
type OpCode struct {
|
||||
Tag byte
|
||||
I1 int
|
||||
I2 int
|
||||
J1 int
|
||||
J2 int
|
||||
}
|
||||
|
||||
// SequenceMatcher compares sequence of strings. The basic
|
||||
// algorithm predates, and is a little fancier than, an algorithm
|
||||
// published in the late 1980's by Ratcliff and Obershelp under the
|
||||
// hyperbolic name "gestalt pattern matching". The basic idea is to find
|
||||
// the longest contiguous matching subsequence that contains no "junk"
|
||||
// elements (R-O doesn't address junk). The same idea is then applied
|
||||
// recursively to the pieces of the sequences to the left and to the right
|
||||
// of the matching subsequence. This does not yield minimal edit
|
||||
// sequences, but does tend to yield matches that "look right" to people.
|
||||
//
|
||||
// SequenceMatcher tries to compute a "human-friendly diff" between two
|
||||
// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the
|
||||
// longest *contiguous* & junk-free matching subsequence. That's what
|
||||
// catches peoples' eyes. The Windows(tm) windiff has another interesting
|
||||
// notion, pairing up elements that appear uniquely in each sequence.
|
||||
// That, and the method here, appear to yield more intuitive difference
|
||||
// reports than does diff. This method appears to be the least vulnerable
|
||||
// to synching up on blocks of "junk lines", though (like blank lines in
|
||||
// ordinary text files, or maybe "<P>" lines in HTML files). That may be
|
||||
// because this is the only method of the 3 that has a *concept* of
|
||||
// "junk" <wink>.
|
||||
//
|
||||
// Timing: Basic R-O is cubic time worst case and quadratic time expected
|
||||
// case. SequenceMatcher is quadratic time for the worst case and has
|
||||
// expected-case behavior dependent in a complicated way on how many
|
||||
// elements the sequences have in common; best case time is linear.
|
||||
type SequenceMatcher struct {
|
||||
a []string
|
||||
b []string
|
||||
b2j map[string][]int
|
||||
IsJunk func(string) bool
|
||||
autoJunk bool
|
||||
bJunk map[string]struct{}
|
||||
matchingBlocks []Match
|
||||
fullBCount map[string]int
|
||||
bPopular map[string]struct{}
|
||||
opCodes []OpCode
|
||||
}
|
||||
|
||||
func NewMatcher(a, b []string) *SequenceMatcher {
|
||||
m := SequenceMatcher{autoJunk: true}
|
||||
m.SetSeqs(a, b)
|
||||
return &m
|
||||
}
|
||||
|
||||
func NewMatcherWithJunk(a, b []string, autoJunk bool,
|
||||
isJunk func(string) bool,
|
||||
) *SequenceMatcher {
|
||||
m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk}
|
||||
m.SetSeqs(a, b)
|
||||
return &m
|
||||
}
|
||||
|
||||
// Set two sequences to be compared.
|
||||
func (m *SequenceMatcher) SetSeqs(a, b []string) {
|
||||
m.SetSeq1(a)
|
||||
m.SetSeq2(b)
|
||||
}
|
||||
|
||||
// Set the first sequence to be compared. The second sequence to be compared is
|
||||
// not changed.
|
||||
//
|
||||
// SequenceMatcher computes and caches detailed information about the second
|
||||
// sequence, so if you want to compare one sequence S against many sequences,
|
||||
// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other
|
||||
// sequences.
|
||||
//
|
||||
// See also SetSeqs() and SetSeq2().
|
||||
func (m *SequenceMatcher) SetSeq1(a []string) {
|
||||
if &a == &m.a {
|
||||
return
|
||||
}
|
||||
m.a = a
|
||||
m.matchingBlocks = nil
|
||||
m.opCodes = nil
|
||||
}
|
||||
|
||||
// Set the second sequence to be compared. The first sequence to be compared is
|
||||
// not changed.
|
||||
func (m *SequenceMatcher) SetSeq2(b []string) {
|
||||
if &b == &m.b {
|
||||
return
|
||||
}
|
||||
m.b = b
|
||||
m.matchingBlocks = nil
|
||||
m.opCodes = nil
|
||||
m.fullBCount = nil
|
||||
m.chainB()
|
||||
}
|
||||
|
||||
func (m *SequenceMatcher) chainB() {
|
||||
// Populate line -> index mapping
|
||||
b2j := map[string][]int{}
|
||||
for i, s := range m.b {
|
||||
indices := b2j[s]
|
||||
indices = append(indices, i)
|
||||
b2j[s] = indices
|
||||
}
|
||||
|
||||
// Purge junk elements
|
||||
m.bJunk = map[string]struct{}{}
|
||||
if m.IsJunk != nil {
|
||||
junk := m.bJunk
|
||||
for s := range b2j {
|
||||
if m.IsJunk(s) {
|
||||
junk[s] = struct{}{}
|
||||
}
|
||||
}
|
||||
for s := range junk {
|
||||
delete(b2j, s)
|
||||
}
|
||||
}
|
||||
|
||||
// Purge remaining popular elements
|
||||
popular := map[string]struct{}{}
|
||||
n := len(m.b)
|
||||
if m.autoJunk && n >= 200 {
|
||||
ntest := n/100 + 1
|
||||
for s, indices := range b2j {
|
||||
if len(indices) > ntest {
|
||||
popular[s] = struct{}{}
|
||||
}
|
||||
}
|
||||
for s := range popular {
|
||||
delete(b2j, s)
|
||||
}
|
||||
}
|
||||
m.bPopular = popular
|
||||
m.b2j = b2j
|
||||
}
|
||||
|
||||
func (m *SequenceMatcher) isBJunk(s string) bool {
|
||||
_, ok := m.bJunk[s]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Find longest matching block in a[alo:ahi] and b[blo:bhi].
|
||||
//
|
||||
// If IsJunk is not defined:
|
||||
//
|
||||
// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
|
||||
// alo <= i <= i+k <= ahi
|
||||
// blo <= j <= j+k <= bhi
|
||||
// and for all (i',j',k') meeting those conditions,
|
||||
// k >= k'
|
||||
// i <= i'
|
||||
// and if i == i', j <= j'
|
||||
//
|
||||
// In other words, of all maximal matching blocks, return one that
|
||||
// starts earliest in a, and of all those maximal matching blocks that
|
||||
// start earliest in a, return the one that starts earliest in b.
|
||||
//
|
||||
// If IsJunk is defined, first the longest matching block is
|
||||
// determined as above, but with the additional restriction that no
|
||||
// junk element appears in the block. Then that block is extended as
|
||||
// far as possible by matching (only) junk elements on both sides. So
|
||||
// the resulting block never matches on junk except as identical junk
|
||||
// happens to be adjacent to an "interesting" match.
|
||||
//
|
||||
// If no blocks match, return (alo, blo, 0).
|
||||
func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {
|
||||
// CAUTION: stripping common prefix or suffix would be incorrect.
|
||||
// E.g.,
|
||||
// ab
|
||||
// acab
|
||||
// Longest matching block is "ab", but if common prefix is
|
||||
// stripped, it's "a" (tied with "b"). UNIX(tm) diff does so
|
||||
// strip, so ends up claiming that ab is changed to acab by
|
||||
// inserting "ca" in the middle. That's minimal but unintuitive:
|
||||
// "it's obvious" that someone inserted "ac" at the front.
|
||||
// Windiff ends up at the same place as diff, but by pairing up
|
||||
// the unique 'b's and then matching the first two 'a's.
|
||||
besti, bestj, bestsize := alo, blo, 0
|
||||
|
||||
// find longest junk-free match
|
||||
// during an iteration of the loop, j2len[j] = length of longest
|
||||
// junk-free match ending with a[i-1] and b[j]
|
||||
j2len := map[int]int{}
|
||||
for i := alo; i != ahi; i++ {
|
||||
// look at all instances of a[i] in b; note that because
|
||||
// b2j has no junk keys, the loop is skipped if a[i] is junk
|
||||
newj2len := map[int]int{}
|
||||
for _, j := range m.b2j[m.a[i]] {
|
||||
// a[i] matches b[j]
|
||||
if j < blo {
|
||||
continue
|
||||
}
|
||||
if j >= bhi {
|
||||
break
|
||||
}
|
||||
k := j2len[j-1] + 1
|
||||
newj2len[j] = k
|
||||
if k > bestsize {
|
||||
besti, bestj, bestsize = i-k+1, j-k+1, k
|
||||
}
|
||||
}
|
||||
j2len = newj2len
|
||||
}
|
||||
|
||||
// Extend the best by non-junk elements on each end. In particular,
|
||||
// "popular" non-junk elements aren't in b2j, which greatly speeds
|
||||
// the inner loop above, but also means "the best" match so far
|
||||
// doesn't contain any junk *or* popular non-junk elements.
|
||||
for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&
|
||||
m.a[besti-1] == m.b[bestj-1] {
|
||||
besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
|
||||
}
|
||||
for besti+bestsize < ahi && bestj+bestsize < bhi &&
|
||||
!m.isBJunk(m.b[bestj+bestsize]) &&
|
||||
m.a[besti+bestsize] == m.b[bestj+bestsize] {
|
||||
bestsize++
|
||||
}
|
||||
|
||||
// Now that we have a wholly interesting match (albeit possibly
|
||||
// empty!), we may as well suck up the matching junk on each
|
||||
// side of it too. Can't think of a good reason not to, and it
|
||||
// saves post-processing the (possibly considerable) expense of
|
||||
// figuring out what to do with it. In the case of an empty
|
||||
// interesting match, this is clearly the right thing to do,
|
||||
// because no other kind of match is possible in the regions.
|
||||
for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&
|
||||
m.a[besti-1] == m.b[bestj-1] {
|
||||
besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
|
||||
}
|
||||
for besti+bestsize < ahi && bestj+bestsize < bhi &&
|
||||
m.isBJunk(m.b[bestj+bestsize]) &&
|
||||
m.a[besti+bestsize] == m.b[bestj+bestsize] {
|
||||
bestsize++
|
||||
}
|
||||
|
||||
return Match{A: besti, B: bestj, Size: bestsize}
|
||||
}
|
||||
|
||||
// Return list of triples describing matching subsequences.
|
||||
//
|
||||
// Each triple is of the form (i, j, n), and means that
|
||||
// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in
|
||||
// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are
|
||||
// adjacent triples in the list, and the second is not the last triple in the
|
||||
// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe
|
||||
// adjacent equal blocks.
|
||||
//
|
||||
// The last triple is a dummy, (len(a), len(b), 0), and is the only
|
||||
// triple with n==0.
|
||||
func (m *SequenceMatcher) GetMatchingBlocks() []Match {
|
||||
if m.matchingBlocks != nil {
|
||||
return m.matchingBlocks
|
||||
}
|
||||
|
||||
var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match
|
||||
matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {
|
||||
match := m.findLongestMatch(alo, ahi, blo, bhi)
|
||||
i, j, k := match.A, match.B, match.Size
|
||||
if match.Size > 0 {
|
||||
if alo < i && blo < j {
|
||||
matched = matchBlocks(alo, i, blo, j, matched)
|
||||
}
|
||||
matched = append(matched, match)
|
||||
if i+k < ahi && j+k < bhi {
|
||||
matched = matchBlocks(i+k, ahi, j+k, bhi, matched)
|
||||
}
|
||||
}
|
||||
return matched
|
||||
}
|
||||
matched := matchBlocks(0, len(m.a), 0, len(m.b), nil)
|
||||
|
||||
// It's possible that we have adjacent equal blocks in the
|
||||
// matching_blocks list now.
|
||||
nonAdjacent := []Match{}
|
||||
i1, j1, k1 := 0, 0, 0
|
||||
for _, b := range matched {
|
||||
// Is this block adjacent to i1, j1, k1?
|
||||
i2, j2, k2 := b.A, b.B, b.Size
|
||||
if i1+k1 == i2 && j1+k1 == j2 {
|
||||
// Yes, so collapse them -- this just increases the length of
|
||||
// the first block by the length of the second, and the first
|
||||
// block so lengthened remains the block to compare against.
|
||||
k1 += k2
|
||||
} else {
|
||||
// Not adjacent. Remember the first block (k1==0 means it's
|
||||
// the dummy we started with), and make the second block the
|
||||
// new block to compare against.
|
||||
if k1 > 0 {
|
||||
nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
|
||||
}
|
||||
i1, j1, k1 = i2, j2, k2
|
||||
}
|
||||
}
|
||||
if k1 > 0 {
|
||||
nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
|
||||
}
|
||||
|
||||
nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})
|
||||
m.matchingBlocks = nonAdjacent
|
||||
return m.matchingBlocks
|
||||
}
|
||||
|
||||
// Return list of 5-tuples describing how to turn a into b.
|
||||
//
|
||||
// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple
|
||||
// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
|
||||
// tuple preceding it, and likewise for j1 == the previous j2.
|
||||
//
|
||||
// The tags are characters, with these meanings:
|
||||
//
|
||||
// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2]
|
||||
//
|
||||
// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case.
|
||||
//
|
||||
// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.
|
||||
//
|
||||
// 'e' (equal): a[i1:i2] == b[j1:j2]
|
||||
func (m *SequenceMatcher) GetOpCodes() []OpCode {
|
||||
if m.opCodes != nil {
|
||||
return m.opCodes
|
||||
}
|
||||
i, j := 0, 0
|
||||
matching := m.GetMatchingBlocks()
|
||||
opCodes := make([]OpCode, 0, len(matching))
|
||||
for _, m := range matching {
|
||||
// invariant: we've pumped out correct diffs to change
|
||||
// a[:i] into b[:j], and the next matching block is
|
||||
// a[ai:ai+size] == b[bj:bj+size]. So we need to pump
|
||||
// out a diff to change a[i:ai] into b[j:bj], pump out
|
||||
// the matching block, and move (i,j) beyond the match
|
||||
ai, bj, size := m.A, m.B, m.Size
|
||||
tag := byte(0)
|
||||
if i < ai && j < bj {
|
||||
tag = 'r'
|
||||
} else if i < ai {
|
||||
tag = 'd'
|
||||
} else if j < bj {
|
||||
tag = 'i'
|
||||
}
|
||||
if tag > 0 {
|
||||
opCodes = append(opCodes, OpCode{tag, i, ai, j, bj})
|
||||
}
|
||||
i, j = ai+size, bj+size
|
||||
// the list of matching blocks is terminated by a
|
||||
// sentinel with size 0
|
||||
if size > 0 {
|
||||
opCodes = append(opCodes, OpCode{'e', ai, i, bj, j})
|
||||
}
|
||||
}
|
||||
m.opCodes = opCodes
|
||||
return m.opCodes
|
||||
}
|
||||
|
||||
// Isolate change clusters by eliminating ranges with no changes.
|
||||
//
|
||||
// Return a generator of groups with up to n lines of context.
|
||||
// Each group is in the same format as returned by GetOpCodes().
|
||||
func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
|
||||
if n < 0 {
|
||||
n = 3
|
||||
}
|
||||
codes := m.GetOpCodes()
|
||||
if len(codes) == 0 {
|
||||
codes = []OpCode{{'e', 0, 1, 0, 1}}
|
||||
}
|
||||
// Fixup leading and trailing groups if they show no changes.
|
||||
if codes[0].Tag == 'e' {
|
||||
c := codes[0]
|
||||
i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
|
||||
codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2}
|
||||
}
|
||||
if codes[len(codes)-1].Tag == 'e' {
|
||||
c := codes[len(codes)-1]
|
||||
i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
|
||||
codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)}
|
||||
}
|
||||
nn := n + n
|
||||
groups := [][]OpCode{}
|
||||
group := []OpCode{}
|
||||
for _, c := range codes {
|
||||
i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
|
||||
// End the current group and start a new one whenever
|
||||
// there is a large range with no changes.
|
||||
if c.Tag == 'e' && i2-i1 > nn {
|
||||
group = append(group, OpCode{
|
||||
c.Tag, i1, min(i2, i1+n),
|
||||
j1, min(j2, j1+n),
|
||||
})
|
||||
groups = append(groups, group)
|
||||
group = []OpCode{}
|
||||
i1, j1 = max(i1, i2-n), max(j1, j2-n)
|
||||
}
|
||||
group = append(group, OpCode{c.Tag, i1, i2, j1, j2})
|
||||
}
|
||||
if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {
|
||||
groups = append(groups, group)
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
// Return a measure of the sequences' similarity (float in [0,1]).
|
||||
//
|
||||
// Where T is the total number of elements in both sequences, and
|
||||
// M is the number of matches, this is 2.0*M / T.
|
||||
// Note that this is 1 if the sequences are identical, and 0 if
|
||||
// they have nothing in common.
|
||||
//
|
||||
// .Ratio() is expensive to compute if you haven't already computed
|
||||
// .GetMatchingBlocks() or .GetOpCodes(), in which case you may
|
||||
// want to try .QuickRatio() or .RealQuickRation() first to get an
|
||||
// upper bound.
|
||||
func (m *SequenceMatcher) Ratio() float64 {
|
||||
matches := 0
|
||||
for _, m := range m.GetMatchingBlocks() {
|
||||
matches += m.Size
|
||||
}
|
||||
return calculateRatio(matches, len(m.a)+len(m.b))
|
||||
}
|
||||
|
||||
// Return an upper bound on ratio() relatively quickly.
|
||||
//
|
||||
// This isn't defined beyond that it is an upper bound on .Ratio(), and
|
||||
// is faster to compute.
|
||||
func (m *SequenceMatcher) QuickRatio() float64 {
|
||||
// viewing a and b as multisets, set matches to the cardinality
|
||||
// of their intersection; this counts the number of matches
|
||||
// without regard to order, so is clearly an upper bound
|
||||
if m.fullBCount == nil {
|
||||
m.fullBCount = map[string]int{}
|
||||
for _, s := range m.b {
|
||||
m.fullBCount[s]++
|
||||
}
|
||||
}
|
||||
|
||||
// avail[x] is the number of times x appears in 'b' less the
|
||||
// number of times we've seen it in 'a' so far ... kinda
|
||||
avail := map[string]int{}
|
||||
matches := 0
|
||||
for _, s := range m.a {
|
||||
n, ok := avail[s]
|
||||
if !ok {
|
||||
n = m.fullBCount[s]
|
||||
}
|
||||
avail[s] = n - 1
|
||||
if n > 0 {
|
||||
matches++
|
||||
}
|
||||
}
|
||||
return calculateRatio(matches, len(m.a)+len(m.b))
|
||||
}
|
||||
|
||||
// Return an upper bound on ratio() very quickly.
|
||||
//
|
||||
// This isn't defined beyond that it is an upper bound on .Ratio(), and
|
||||
// is faster to compute than either .Ratio() or .QuickRatio().
|
||||
func (m *SequenceMatcher) RealQuickRatio() float64 {
|
||||
la, lb := len(m.a), len(m.b)
|
||||
return calculateRatio(min(la, lb), la+lb)
|
||||
}
|
||||
|
||||
// Convert range to the "ed" format
|
||||
func formatRangeUnified(start, stop int) string {
|
||||
// Per the diff spec at http://www.unix.org/single_unix_specification/
|
||||
beginning := start + 1 // lines start numbering with one
|
||||
length := stop - start
|
||||
if length == 1 {
|
||||
return fmt.Sprintf("%d", beginning)
|
||||
}
|
||||
if length == 0 {
|
||||
beginning-- // empty ranges begin at line just before the range
|
||||
}
|
||||
return fmt.Sprintf("%d,%d", beginning, length)
|
||||
}
|
||||
|
||||
// Unified diff parameters
|
||||
type UnifiedDiff struct {
|
||||
A []string // First sequence lines
|
||||
FromFile string // First file name
|
||||
FromDate string // First file time
|
||||
B []string // Second sequence lines
|
||||
ToFile string // Second file name
|
||||
ToDate string // Second file time
|
||||
Eol string // Headers end of line, defaults to LF
|
||||
Context int // Number of context lines
|
||||
}
|
||||
|
||||
// Compare two sequences of lines; generate the delta as a unified diff.
|
||||
//
|
||||
// Unified diffs are a compact way of showing line changes and a few
|
||||
// lines of context. The number of context lines is set by 'n' which
|
||||
// defaults to three.
|
||||
//
|
||||
// By default, the diff control lines (those with ---, +++, or @@) are
|
||||
// created with a trailing newline. This is helpful so that inputs
|
||||
// created from file.readlines() result in diffs that are suitable for
|
||||
// file.writelines() since both the inputs and outputs have trailing
|
||||
// newlines.
|
||||
//
|
||||
// For inputs that do not have trailing newlines, set the lineterm
|
||||
// argument to "" so that the output will be uniformly newline free.
|
||||
//
|
||||
// The unidiff format normally has a header for filenames and modification
|
||||
// times. Any or all of these may be specified using strings for
|
||||
// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
|
||||
// The modification times are normally expressed in the ISO 8601 format.
|
||||
func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error {
|
||||
buf := bufio.NewWriter(writer)
|
||||
defer buf.Flush()
|
||||
wf := func(format string, args ...interface{}) error {
|
||||
_, err := buf.WriteString(fmt.Sprintf(format, args...))
|
||||
return err
|
||||
}
|
||||
ws := func(s string) error {
|
||||
_, err := buf.WriteString(s)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(diff.Eol) == 0 {
|
||||
diff.Eol = "\n"
|
||||
}
|
||||
|
||||
started := false
|
||||
m := NewMatcher(diff.A, diff.B)
|
||||
for _, g := range m.GetGroupedOpCodes(diff.Context) {
|
||||
if !started {
|
||||
started = true
|
||||
fromDate := ""
|
||||
if len(diff.FromDate) > 0 {
|
||||
fromDate = "\t" + diff.FromDate
|
||||
}
|
||||
toDate := ""
|
||||
if len(diff.ToDate) > 0 {
|
||||
toDate = "\t" + diff.ToDate
|
||||
}
|
||||
if diff.FromFile != "" || diff.ToFile != "" {
|
||||
err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
first, last := g[0], g[len(g)-1]
|
||||
range1 := formatRangeUnified(first.I1, last.I2)
|
||||
range2 := formatRangeUnified(first.J1, last.J2)
|
||||
if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, c := range g {
|
||||
i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
|
||||
if c.Tag == 'e' {
|
||||
for _, line := range diff.A[i1:i2] {
|
||||
if err := ws(" " + line); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if c.Tag == 'r' || c.Tag == 'd' {
|
||||
for _, line := range diff.A[i1:i2] {
|
||||
if err := ws("-" + line); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.Tag == 'r' || c.Tag == 'i' {
|
||||
for _, line := range diff.B[j1:j2] {
|
||||
if err := ws("+" + line); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Like WriteUnifiedDiff but returns the diff a string.
|
||||
func GetUnifiedDiffString(diff UnifiedDiff) (string, error) {
|
||||
w := &bytes.Buffer{}
|
||||
err := WriteUnifiedDiff(w, diff)
|
||||
return w.String(), err
|
||||
}
|
||||
|
||||
// Split a string on "\n" while preserving them. The output can be used
|
||||
// as input for UnifiedDiff and ContextDiff structures.
|
||||
func SplitLines(s string) []string {
|
||||
lines := strings.SplitAfter(s, "\n")
|
||||
lines[len(lines)-1] += "\n"
|
||||
return lines
|
||||
}
|
||||
32
vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go
generated
vendored
Normal file
32
vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2021 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package internal
|
||||
|
||||
import "regexp"
|
||||
|
||||
type GoCollectorRule struct {
|
||||
Matcher *regexp.Regexp
|
||||
Deny bool
|
||||
}
|
||||
|
||||
// GoCollectorOptions should not be used be directly by anything, except `collectors` package.
|
||||
// Use it via collectors package instead. See issue
|
||||
// https://github.com/prometheus/client_golang/issues/1030.
|
||||
//
|
||||
// This is internal, so external users only can use it via `collector.WithGoCollector*` methods
|
||||
type GoCollectorOptions struct {
|
||||
DisableMemStatsLikeMetrics bool
|
||||
RuntimeMetricSumForHist map[string]string
|
||||
RuntimeMetricRules []GoCollectorRule
|
||||
}
|
||||
4
vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go
generated
vendored
4
vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go
generated
vendored
@ -61,9 +61,9 @@ func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool)
|
||||
// name has - replaced with _ and is concatenated with the unit and
|
||||
// other data.
|
||||
name = strings.ReplaceAll(name, "-", "_")
|
||||
name = name + "_" + unit
|
||||
name += "_" + unit
|
||||
if d.Cumulative && d.Kind != metrics.KindFloat64Histogram {
|
||||
name = name + "_total"
|
||||
name += "_total"
|
||||
}
|
||||
|
||||
valid := model.IsValidMetricName(model.LabelValue(namespace + "_" + subsystem + "_" + name))
|
||||
|
||||
28
vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go
generated
vendored
28
vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go
generated
vendored
@ -19,18 +19,34 @@ import (
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
// metricSorter is a sortable slice of *dto.Metric.
|
||||
type metricSorter []*dto.Metric
|
||||
// LabelPairSorter implements sort.Interface. It is used to sort a slice of
|
||||
// dto.LabelPair pointers.
|
||||
type LabelPairSorter []*dto.LabelPair
|
||||
|
||||
func (s metricSorter) Len() int {
|
||||
func (s LabelPairSorter) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s metricSorter) Swap(i, j int) {
|
||||
func (s LabelPairSorter) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
func (s metricSorter) Less(i, j int) bool {
|
||||
func (s LabelPairSorter) Less(i, j int) bool {
|
||||
return s[i].GetName() < s[j].GetName()
|
||||
}
|
||||
|
||||
// MetricSorter is a sortable slice of *dto.Metric.
|
||||
type MetricSorter []*dto.Metric
|
||||
|
||||
func (s MetricSorter) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s MetricSorter) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
func (s MetricSorter) Less(i, j int) bool {
|
||||
if len(s[i].Label) != len(s[j].Label) {
|
||||
// This should not happen. The metrics are
|
||||
// inconsistent. However, we have to deal with the fact, as
|
||||
@ -68,7 +84,7 @@ func (s metricSorter) Less(i, j int) bool {
|
||||
// the slice, with the contained Metrics sorted within each MetricFamily.
|
||||
func NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily {
|
||||
for _, mf := range metricFamiliesByName {
|
||||
sort.Sort(metricSorter(mf.Metric))
|
||||
sort.Sort(MetricSorter(mf.Metric))
|
||||
}
|
||||
names := make([]string, 0, len(metricFamiliesByName))
|
||||
for name, mf := range metricFamiliesByName {
|
||||
|
||||
6
vendor/github.com/prometheus/client_golang/prometheus/labels.go
generated
vendored
6
vendor/github.com/prometheus/client_golang/prometheus/labels.go
generated
vendored
@ -39,7 +39,7 @@ var errInconsistentCardinality = errors.New("inconsistent label cardinality")
|
||||
|
||||
func makeInconsistentCardinalityError(fqName string, labels, labelValues []string) error {
|
||||
return fmt.Errorf(
|
||||
"%s: %q has %d variable labels named %q but %d values %q were provided",
|
||||
"%w: %q has %d variable labels named %q but %d values %q were provided",
|
||||
errInconsistentCardinality, fqName,
|
||||
len(labels), labels,
|
||||
len(labelValues), labelValues,
|
||||
@ -49,7 +49,7 @@ func makeInconsistentCardinalityError(fqName string, labels, labelValues []strin
|
||||
func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error {
|
||||
if len(labels) != expectedNumberOfValues {
|
||||
return fmt.Errorf(
|
||||
"%s: expected %d label values but got %d in %#v",
|
||||
"%w: expected %d label values but got %d in %#v",
|
||||
errInconsistentCardinality, expectedNumberOfValues,
|
||||
len(labels), labels,
|
||||
)
|
||||
@ -67,7 +67,7 @@ func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error {
|
||||
func validateLabelValues(vals []string, expectedNumberOfValues int) error {
|
||||
if len(vals) != expectedNumberOfValues {
|
||||
return fmt.Errorf(
|
||||
"%s: expected %d label values but got %d in %#v",
|
||||
"%w: expected %d label values but got %d in %#v",
|
||||
errInconsistentCardinality, expectedNumberOfValues,
|
||||
len(vals), vals,
|
||||
)
|
||||
|
||||
112
vendor/github.com/prometheus/client_golang/prometheus/metric.go
generated
vendored
112
vendor/github.com/prometheus/client_golang/prometheus/metric.go
generated
vendored
@ -14,6 +14,9 @@
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -115,22 +118,6 @@ func BuildFQName(namespace, subsystem, name string) string {
|
||||
return name
|
||||
}
|
||||
|
||||
// labelPairSorter implements sort.Interface. It is used to sort a slice of
|
||||
// dto.LabelPair pointers.
|
||||
type labelPairSorter []*dto.LabelPair
|
||||
|
||||
func (s labelPairSorter) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s labelPairSorter) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
func (s labelPairSorter) Less(i, j int) bool {
|
||||
return s[i].GetName() < s[j].GetName()
|
||||
}
|
||||
|
||||
type invalidMetric struct {
|
||||
desc *Desc
|
||||
err error
|
||||
@ -174,3 +161,96 @@ func (m timestampedMetric) Write(pb *dto.Metric) error {
|
||||
func NewMetricWithTimestamp(t time.Time, m Metric) Metric {
|
||||
return timestampedMetric{Metric: m, t: t}
|
||||
}
|
||||
|
||||
type withExemplarsMetric struct {
|
||||
Metric
|
||||
|
||||
exemplars []*dto.Exemplar
|
||||
}
|
||||
|
||||
func (m *withExemplarsMetric) Write(pb *dto.Metric) error {
|
||||
if err := m.Metric.Write(pb); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case pb.Counter != nil:
|
||||
pb.Counter.Exemplar = m.exemplars[len(m.exemplars)-1]
|
||||
case pb.Histogram != nil:
|
||||
for _, e := range m.exemplars {
|
||||
// pb.Histogram.Bucket are sorted by UpperBound.
|
||||
i := sort.Search(len(pb.Histogram.Bucket), func(i int) bool {
|
||||
return pb.Histogram.Bucket[i].GetUpperBound() >= e.GetValue()
|
||||
})
|
||||
if i < len(pb.Histogram.Bucket) {
|
||||
pb.Histogram.Bucket[i].Exemplar = e
|
||||
} else {
|
||||
// The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365.
|
||||
b := &dto.Bucket{
|
||||
CumulativeCount: proto.Uint64(pb.Histogram.Bucket[len(pb.Histogram.GetBucket())-1].GetCumulativeCount()),
|
||||
UpperBound: proto.Float64(math.Inf(1)),
|
||||
Exemplar: e,
|
||||
}
|
||||
pb.Histogram.Bucket = append(pb.Histogram.Bucket, b)
|
||||
}
|
||||
}
|
||||
default:
|
||||
// TODO(bwplotka): Implement Gauge?
|
||||
return errors.New("cannot inject exemplar into Gauge, Summary or Untyped")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Exemplar is easier to use, user-facing representation of *dto.Exemplar.
|
||||
type Exemplar struct {
|
||||
Value float64
|
||||
Labels Labels
|
||||
// Optional.
|
||||
// Default value (time.Time{}) indicates its empty, which should be
|
||||
// understood as time.Now() time at the moment of creation of metric.
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
// NewMetricWithExemplars returns a new Metric wrapping the provided Metric with given
|
||||
// exemplars. Exemplars are validated.
|
||||
//
|
||||
// Only last applicable exemplar is injected from the list.
|
||||
// For example for Counter it means last exemplar is injected.
|
||||
// For Histogram, it means last applicable exemplar for each bucket is injected.
|
||||
//
|
||||
// NewMetricWithExemplars works best with MustNewConstMetric and
|
||||
// MustNewConstHistogram, see example.
|
||||
func NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) {
|
||||
if len(exemplars) == 0 {
|
||||
return nil, errors.New("no exemplar was passed for NewMetricWithExemplars")
|
||||
}
|
||||
|
||||
var (
|
||||
now = time.Now()
|
||||
exs = make([]*dto.Exemplar, len(exemplars))
|
||||
err error
|
||||
)
|
||||
for i, e := range exemplars {
|
||||
ts := e.Timestamp
|
||||
if ts == (time.Time{}) {
|
||||
ts = now
|
||||
}
|
||||
exs[i], err = newExemplar(e.Value, ts, e.Labels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &withExemplarsMetric{Metric: m, exemplars: exs}, nil
|
||||
}
|
||||
|
||||
// MustNewMetricWithExemplars is a version of NewMetricWithExemplars that panics where
|
||||
// NewMetricWithExemplars would have returned an error.
|
||||
func MustNewMetricWithExemplars(m Metric, exemplars ...Exemplar) Metric {
|
||||
ret, err := NewMetricWithExemplars(m, exemplars...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
25
vendor/github.com/prometheus/client_golang/prometheus/num_threads.go
generated
vendored
Normal file
25
vendor/github.com/prometheus/client_golang/prometheus/num_threads.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !js || wasm
|
||||
// +build !js wasm
|
||||
|
||||
package prometheus
|
||||
|
||||
import "runtime"
|
||||
|
||||
// getRuntimeNumThreads returns the number of open OS threads.
|
||||
func getRuntimeNumThreads() float64 {
|
||||
n, _ := runtime.ThreadCreateProfile(nil)
|
||||
return float64(n)
|
||||
}
|
||||
22
vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go
generated
vendored
Normal file
22
vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build js && !wasm
|
||||
// +build js,!wasm
|
||||
|
||||
package prometheus
|
||||
|
||||
// getRuntimeNumThreads returns the number of open OS threads.
|
||||
func getRuntimeNumThreads() float64 {
|
||||
return 1
|
||||
}
|
||||
2
vendor/github.com/prometheus/client_golang/prometheus/observer.go
generated
vendored
2
vendor/github.com/prometheus/client_golang/prometheus/observer.go
generated
vendored
@ -58,7 +58,7 @@ type ObserverVec interface {
|
||||
// current time as timestamp, and the provided Labels. Empty Labels will lead to
|
||||
// a valid (label-less) exemplar. But if Labels is nil, the current exemplar is
|
||||
// left in place. ObserveWithExemplar panics if any of the provided labels are
|
||||
// invalid or if the provided labels contain more than 64 runes in total.
|
||||
// invalid or if the provided labels contain more than 128 runes in total.
|
||||
type ExemplarObserver interface {
|
||||
ObserveWithExemplar(value float64, exemplar Labels)
|
||||
}
|
||||
|
||||
10
vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
generated
vendored
10
vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
generated
vendored
@ -16,7 +16,6 @@ package prometheus
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -104,8 +103,7 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector {
|
||||
}
|
||||
|
||||
if opts.PidFn == nil {
|
||||
pid := os.Getpid()
|
||||
c.pidFn = func() (int, error) { return pid, nil }
|
||||
c.pidFn = getPIDFn()
|
||||
} else {
|
||||
c.pidFn = opts.PidFn
|
||||
}
|
||||
@ -152,13 +150,13 @@ func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error)
|
||||
// It is meant to be used for the PidFn field in ProcessCollectorOpts.
|
||||
func NewPidFileFn(pidFilePath string) func() (int, error) {
|
||||
return func() (int, error) {
|
||||
content, err := ioutil.ReadFile(pidFilePath)
|
||||
content, err := os.ReadFile(pidFilePath)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't read pid file %q: %+v", pidFilePath, err)
|
||||
return 0, fmt.Errorf("can't read pid file %q: %w", pidFilePath, err)
|
||||
}
|
||||
pid, err := strconv.Atoi(strings.TrimSpace(string(content)))
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't parse pid file %q: %+v", pidFilePath, err)
|
||||
return 0, fmt.Errorf("can't parse pid file %q: %w", pidFilePath, err)
|
||||
}
|
||||
|
||||
return pid, nil
|
||||
|
||||
26
vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go
generated
vendored
Normal file
26
vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build js
|
||||
// +build js
|
||||
|
||||
package prometheus
|
||||
|
||||
func canCollectProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *processCollector) processCollect(ch chan<- Metric) {
|
||||
// noop on this platform
|
||||
return
|
||||
}
|
||||
4
vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
generated
vendored
4
vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
generated
vendored
@ -11,8 +11,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
//go:build !windows && !js
|
||||
// +build !windows,!js
|
||||
|
||||
package prometheus
|
||||
|
||||
|
||||
18
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
generated
vendored
18
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
generated
vendored
@ -76,16 +76,19 @@ func (r *responseWriterDelegator) Write(b []byte) (int, error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
type closeNotifierDelegator struct{ *responseWriterDelegator }
|
||||
type flusherDelegator struct{ *responseWriterDelegator }
|
||||
type hijackerDelegator struct{ *responseWriterDelegator }
|
||||
type readerFromDelegator struct{ *responseWriterDelegator }
|
||||
type pusherDelegator struct{ *responseWriterDelegator }
|
||||
type (
|
||||
closeNotifierDelegator struct{ *responseWriterDelegator }
|
||||
flusherDelegator struct{ *responseWriterDelegator }
|
||||
hijackerDelegator struct{ *responseWriterDelegator }
|
||||
readerFromDelegator struct{ *responseWriterDelegator }
|
||||
pusherDelegator struct{ *responseWriterDelegator }
|
||||
)
|
||||
|
||||
func (d closeNotifierDelegator) CloseNotify() <-chan bool {
|
||||
//nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.
|
||||
return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
||||
}
|
||||
|
||||
func (d flusherDelegator) Flush() {
|
||||
// If applicable, call WriteHeader here so that observeWriteHeader is
|
||||
// handled appropriately.
|
||||
@ -94,9 +97,11 @@ func (d flusherDelegator) Flush() {
|
||||
}
|
||||
d.ResponseWriter.(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
return d.ResponseWriter.(http.Hijacker).Hijack()
|
||||
}
|
||||
|
||||
func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
|
||||
// If applicable, call WriteHeader here so that observeWriteHeader is
|
||||
// handled appropriately.
|
||||
@ -107,6 +112,7 @@ func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
|
||||
d.written += n
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (d pusherDelegator) Push(target string, opts *http.PushOptions) error {
|
||||
return d.ResponseWriter.(http.Pusher).Push(target, opts)
|
||||
}
|
||||
@ -261,7 +267,7 @@ func init() {
|
||||
http.Flusher
|
||||
}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
|
||||
}
|
||||
pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23
|
||||
pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 23
|
||||
return struct {
|
||||
*responseWriterDelegator
|
||||
http.Pusher
|
||||
|
||||
20
vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
generated
vendored
20
vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
generated
vendored
@ -33,6 +33,7 @@ package promhttp
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@ -84,6 +85,13 @@ func Handler() http.Handler {
|
||||
// instrumentation. Use the InstrumentMetricHandler function to apply the same
|
||||
// kind of instrumentation as it is used by the Handler function.
|
||||
func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
|
||||
return HandlerForTransactional(prometheus.ToTransactionalGatherer(reg), opts)
|
||||
}
|
||||
|
||||
// HandlerForTransactional is like HandlerFor, but it uses transactional gather, which
|
||||
// can safely change in-place returned *dto.MetricFamily before call to `Gather` and after
|
||||
// call to `done` of that `Gather`.
|
||||
func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerOpts) http.Handler {
|
||||
var (
|
||||
inFlightSem chan struct{}
|
||||
errCnt = prometheus.NewCounterVec(
|
||||
@ -103,7 +111,8 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
|
||||
errCnt.WithLabelValues("gathering")
|
||||
errCnt.WithLabelValues("encoding")
|
||||
if err := opts.Registry.Register(errCnt); err != nil {
|
||||
if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
|
||||
are := &prometheus.AlreadyRegisteredError{}
|
||||
if errors.As(err, are) {
|
||||
errCnt = are.ExistingCollector.(*prometheus.CounterVec)
|
||||
} else {
|
||||
panic(err)
|
||||
@ -123,7 +132,8 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
|
||||
return
|
||||
}
|
||||
}
|
||||
mfs, err := reg.Gather()
|
||||
mfs, done, err := reg.Gather()
|
||||
defer done()
|
||||
if err != nil {
|
||||
if opts.ErrorLog != nil {
|
||||
opts.ErrorLog.Println("error gathering metrics:", err)
|
||||
@ -242,7 +252,8 @@ func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) ht
|
||||
cnt.WithLabelValues("500")
|
||||
cnt.WithLabelValues("503")
|
||||
if err := reg.Register(cnt); err != nil {
|
||||
if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
|
||||
are := &prometheus.AlreadyRegisteredError{}
|
||||
if errors.As(err, are) {
|
||||
cnt = are.ExistingCollector.(*prometheus.CounterVec)
|
||||
} else {
|
||||
panic(err)
|
||||
@ -254,7 +265,8 @@ func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) ht
|
||||
Help: "Current number of scrapes being served.",
|
||||
})
|
||||
if err := reg.Register(gge); err != nil {
|
||||
if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
|
||||
are := &prometheus.AlreadyRegisteredError{}
|
||||
if errors.As(err, are) {
|
||||
gge = are.ExistingCollector.(prometheus.Gauge)
|
||||
} else {
|
||||
panic(err)
|
||||
|
||||
39
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
generated
vendored
39
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
generated
vendored
@ -38,11 +38,11 @@ func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
//
|
||||
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
|
||||
func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc {
|
||||
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||||
return func(r *http.Request) (*http.Response, error) {
|
||||
gauge.Inc()
|
||||
defer gauge.Dec()
|
||||
return next.RoundTrip(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// InstrumentRoundTripperCounter is a middleware that wraps the provided
|
||||
@ -59,22 +59,29 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp
|
||||
// If the wrapped RoundTripper panics or returns a non-nil error, the Counter
|
||||
// is not incremented.
|
||||
//
|
||||
// Use with WithExemplarFromContext to instrument the exemplars on the counter of requests.
|
||||
//
|
||||
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
|
||||
func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
|
||||
rtOpts := &option{}
|
||||
rtOpts := defaultOptions()
|
||||
for _, o := range opts {
|
||||
o(rtOpts)
|
||||
o.apply(rtOpts)
|
||||
}
|
||||
|
||||
code, method := checkLabels(counter)
|
||||
|
||||
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||||
return func(r *http.Request) (*http.Response, error) {
|
||||
resp, err := next.RoundTrip(r)
|
||||
if err == nil {
|
||||
exemplarAdd(
|
||||
counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)),
|
||||
1,
|
||||
rtOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Inc()
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// InstrumentRoundTripperDuration is a middleware that wraps the provided
|
||||
@ -94,24 +101,30 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou
|
||||
// If the wrapped RoundTripper panics or returns a non-nil error, no values are
|
||||
// reported.
|
||||
//
|
||||
// Use with WithExemplarFromContext to instrument the exemplars on the duration histograms.
|
||||
//
|
||||
// Note that this method is only guaranteed to never observe negative durations
|
||||
// if used with Go1.9+.
|
||||
func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
|
||||
rtOpts := &option{}
|
||||
rtOpts := defaultOptions()
|
||||
for _, o := range opts {
|
||||
o(rtOpts)
|
||||
o.apply(rtOpts)
|
||||
}
|
||||
|
||||
code, method := checkLabels(obs)
|
||||
|
||||
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||||
return func(r *http.Request) (*http.Response, error) {
|
||||
start := time.Now()
|
||||
resp, err := next.RoundTrip(r)
|
||||
if err == nil {
|
||||
obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Observe(time.Since(start).Seconds())
|
||||
exemplarObserve(
|
||||
obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)),
|
||||
time.Since(start).Seconds(),
|
||||
rtOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// InstrumentTrace is used to offer flexibility in instrumenting the available
|
||||
@ -149,7 +162,7 @@ type InstrumentTrace struct {
|
||||
//
|
||||
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
|
||||
func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {
|
||||
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||||
return func(r *http.Request) (*http.Response, error) {
|
||||
start := time.Now()
|
||||
|
||||
trace := &httptrace.ClientTrace{
|
||||
@ -231,5 +244,5 @@ func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) Ro
|
||||
r = r.WithContext(httptrace.WithClientTrace(r.Context(), trace))
|
||||
|
||||
return next.RoundTrip(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
119
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
generated
vendored
119
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
generated
vendored
@ -28,6 +28,22 @@ import (
|
||||
// magicString is used for the hacky label test in checkLabels. Remove once fixed.
|
||||
const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa"
|
||||
|
||||
func exemplarObserve(obs prometheus.Observer, val float64, labels map[string]string) {
|
||||
if labels == nil {
|
||||
obs.Observe(val)
|
||||
return
|
||||
}
|
||||
obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels)
|
||||
}
|
||||
|
||||
func exemplarAdd(obs prometheus.Counter, val float64, labels map[string]string) {
|
||||
if labels == nil {
|
||||
obs.Add(val)
|
||||
return
|
||||
}
|
||||
obs.(prometheus.ExemplarAdder).AddWithExemplar(val, labels)
|
||||
}
|
||||
|
||||
// InstrumentHandlerInFlight is a middleware that wraps the provided
|
||||
// http.Handler. It sets the provided prometheus.Gauge to the number of
|
||||
// requests currently handled by the wrapped http.Handler.
|
||||
@ -48,7 +64,7 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl
|
||||
// names are "code" and "method". The function panics otherwise. For the "method"
|
||||
// label a predefined default label value set is used to filter given values.
|
||||
// Values besides predefined values will count as `unknown` method.
|
||||
//`WithExtraMethods` can be used to add more methods to the set. The Observe
|
||||
// `WithExtraMethods` can be used to add more methods to the set. The Observe
|
||||
// method of the Observer in the ObserverVec is called with the request duration
|
||||
// in seconds. Partitioning happens by HTTP status code and/or HTTP method if
|
||||
// the respective instance label names are present in the ObserverVec. For
|
||||
@ -62,28 +78,37 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl
|
||||
// Note that this method is only guaranteed to never observe negative durations
|
||||
// if used with Go1.9+.
|
||||
func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||||
mwOpts := &option{}
|
||||
hOpts := defaultOptions()
|
||||
for _, o := range opts {
|
||||
o(mwOpts)
|
||||
o.apply(hOpts)
|
||||
}
|
||||
|
||||
code, method := checkLabels(obs)
|
||||
|
||||
if code {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
d := newDelegator(w, nil)
|
||||
next.ServeHTTP(d, r)
|
||||
|
||||
obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||||
})
|
||||
exemplarObserve(
|
||||
obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)),
|
||||
time.Since(now).Seconds(),
|
||||
hOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
next.ServeHTTP(w, r)
|
||||
obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||||
})
|
||||
|
||||
exemplarObserve(
|
||||
obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)),
|
||||
time.Since(now).Seconds(),
|
||||
hOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// InstrumentHandlerCounter is a middleware that wraps the provided http.Handler
|
||||
@ -104,25 +129,34 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op
|
||||
//
|
||||
// See the example for InstrumentHandlerDuration for example usage.
|
||||
func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||||
mwOpts := &option{}
|
||||
hOpts := defaultOptions()
|
||||
for _, o := range opts {
|
||||
o(mwOpts)
|
||||
o.apply(hOpts)
|
||||
}
|
||||
|
||||
code, method := checkLabels(counter)
|
||||
|
||||
if code {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
d := newDelegator(w, nil)
|
||||
next.ServeHTTP(d, r)
|
||||
counter.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Inc()
|
||||
})
|
||||
|
||||
exemplarAdd(
|
||||
counter.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)),
|
||||
1,
|
||||
hOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
next.ServeHTTP(w, r)
|
||||
counter.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Inc()
|
||||
})
|
||||
exemplarAdd(
|
||||
counter.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)),
|
||||
1,
|
||||
hOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
|
||||
@ -148,20 +182,24 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler,
|
||||
//
|
||||
// See the example for InstrumentHandlerDuration for example usage.
|
||||
func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||||
mwOpts := &option{}
|
||||
hOpts := defaultOptions()
|
||||
for _, o := range opts {
|
||||
o(mwOpts)
|
||||
o.apply(hOpts)
|
||||
}
|
||||
|
||||
code, method := checkLabels(obs)
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
d := newDelegator(w, func(status int) {
|
||||
obs.With(labels(code, method, r.Method, status, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||||
exemplarObserve(
|
||||
obs.With(labels(code, method, r.Method, status, hOpts.extraMethods...)),
|
||||
time.Since(now).Seconds(),
|
||||
hOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
})
|
||||
next.ServeHTTP(d, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// InstrumentHandlerRequestSize is a middleware that wraps the provided
|
||||
@ -184,27 +222,34 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha
|
||||
//
|
||||
// See the example for InstrumentHandlerDuration for example usage.
|
||||
func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||||
mwOpts := &option{}
|
||||
hOpts := defaultOptions()
|
||||
for _, o := range opts {
|
||||
o(mwOpts)
|
||||
o.apply(hOpts)
|
||||
}
|
||||
|
||||
code, method := checkLabels(obs)
|
||||
|
||||
if code {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
d := newDelegator(w, nil)
|
||||
next.ServeHTTP(d, r)
|
||||
size := computeApproximateRequestSize(r)
|
||||
obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(size))
|
||||
})
|
||||
exemplarObserve(
|
||||
obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)),
|
||||
float64(size),
|
||||
hOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
next.ServeHTTP(w, r)
|
||||
size := computeApproximateRequestSize(r)
|
||||
obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(float64(size))
|
||||
})
|
||||
exemplarObserve(
|
||||
obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)),
|
||||
float64(size),
|
||||
hOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// InstrumentHandlerResponseSize is a middleware that wraps the provided
|
||||
@ -227,9 +272,9 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler,
|
||||
//
|
||||
// See the example for InstrumentHandlerDuration for example usage.
|
||||
func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler {
|
||||
mwOpts := &option{}
|
||||
hOpts := defaultOptions()
|
||||
for _, o := range opts {
|
||||
o(mwOpts)
|
||||
o.apply(hOpts)
|
||||
}
|
||||
|
||||
code, method := checkLabels(obs)
|
||||
@ -237,7 +282,11 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
d := newDelegator(w, nil)
|
||||
next.ServeHTTP(d, r)
|
||||
obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(d.Written()))
|
||||
exemplarObserve(
|
||||
obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)),
|
||||
float64(d.Written()),
|
||||
hOpts.getExemplarFn(r.Context()),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@ -246,7 +295,7 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler
|
||||
// Collector does not have a Desc or has more than one Desc or its Desc is
|
||||
// invalid. It also panics if the Collector has any non-const, non-curried
|
||||
// labels that are not named "code" or "method".
|
||||
func checkLabels(c prometheus.Collector) (code bool, method bool) {
|
||||
func checkLabels(c prometheus.Collector) (code, method bool) {
|
||||
// TODO(beorn7): Remove this hacky way to check for instance labels
|
||||
// once Descriptors can have their dimensionality queried.
|
||||
var (
|
||||
|
||||
39
vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
generated
vendored
39
vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
generated
vendored
@ -13,19 +13,46 @@
|
||||
|
||||
package promhttp
|
||||
|
||||
// Option are used to configure a middleware or round tripper..
|
||||
type Option func(*option)
|
||||
import (
|
||||
"context"
|
||||
|
||||
type option struct {
|
||||
extraMethods []string
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// Option are used to configure both handler (middleware) or round tripper.
|
||||
type Option interface {
|
||||
apply(*options)
|
||||
}
|
||||
|
||||
// options store options for both a handler or round tripper.
|
||||
type options struct {
|
||||
extraMethods []string
|
||||
getExemplarFn func(requestCtx context.Context) prometheus.Labels
|
||||
}
|
||||
|
||||
func defaultOptions() *options {
|
||||
return &options{getExemplarFn: func(ctx context.Context) prometheus.Labels { return nil }}
|
||||
}
|
||||
|
||||
type optionApplyFunc func(*options)
|
||||
|
||||
func (o optionApplyFunc) apply(opt *options) { o(opt) }
|
||||
|
||||
// WithExtraMethods adds additional HTTP methods to the list of allowed methods.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list.
|
||||
//
|
||||
// See the example for ExampleInstrumentHandlerWithExtraMethods for example usage.
|
||||
func WithExtraMethods(methods ...string) Option {
|
||||
return func(o *option) {
|
||||
return optionApplyFunc(func(o *options) {
|
||||
o.extraMethods = methods
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// WithExemplarFromContext adds allows to put a hook to all counter and histogram metrics.
|
||||
// If the hook function returns non-nil labels, exemplars will be added for that request, otherwise metric
|
||||
// will get instrumented without exemplar.
|
||||
func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option {
|
||||
return optionApplyFunc(func(o *options) {
|
||||
o.getExemplarFn = getExemplarFn
|
||||
})
|
||||
}
|
||||
|
||||
118
vendor/github.com/prometheus/client_golang/prometheus/registry.go
generated
vendored
118
vendor/github.com/prometheus/client_golang/prometheus/registry.go
generated
vendored
@ -15,8 +15,8 @@ package prometheus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@ -289,7 +289,7 @@ func (r *Registry) Register(c Collector) error {
|
||||
|
||||
// Is the descriptor valid at all?
|
||||
if desc.err != nil {
|
||||
return fmt.Errorf("descriptor %s is invalid: %s", desc, desc.err)
|
||||
return fmt.Errorf("descriptor %s is invalid: %w", desc, desc.err)
|
||||
}
|
||||
|
||||
// Is the descID unique?
|
||||
@ -407,6 +407,14 @@ func (r *Registry) MustRegister(cs ...Collector) {
|
||||
|
||||
// Gather implements Gatherer.
|
||||
func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
|
||||
r.mtx.RLock()
|
||||
|
||||
if len(r.collectorsByID) == 0 && len(r.uncheckedCollectors) == 0 {
|
||||
// Fast path.
|
||||
r.mtx.RUnlock()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var (
|
||||
checkedMetricChan = make(chan Metric, capMetricChan)
|
||||
uncheckedMetricChan = make(chan Metric, capMetricChan)
|
||||
@ -416,7 +424,6 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
|
||||
registeredDescIDs map[uint64]struct{} // Only used for pedantic checks
|
||||
)
|
||||
|
||||
r.mtx.RLock()
|
||||
goroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors)
|
||||
metricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName))
|
||||
checkedCollectors := make(chan Collector, len(r.collectorsByID))
|
||||
@ -556,7 +563,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
|
||||
// This is intended for use with the textfile collector of the node exporter.
|
||||
// Note that the node exporter expects the filename to be suffixed with ".prom".
|
||||
func WriteToTextfile(filename string, g Gatherer) error {
|
||||
tmp, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename))
|
||||
tmp, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -575,7 +582,7 @@ func WriteToTextfile(filename string, g Gatherer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.Chmod(tmp.Name(), 0644); err != nil {
|
||||
if err := os.Chmod(tmp.Name(), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Rename(tmp.Name(), filename)
|
||||
@ -596,7 +603,7 @@ func processMetric(
|
||||
}
|
||||
dtoMetric := &dto.Metric{}
|
||||
if err := metric.Write(dtoMetric); err != nil {
|
||||
return fmt.Errorf("error collecting metric %v: %s", desc, err)
|
||||
return fmt.Errorf("error collecting metric %v: %w", desc, err)
|
||||
}
|
||||
metricFamily, ok := metricFamiliesByName[desc.fqName]
|
||||
if ok { // Existing name.
|
||||
@ -718,12 +725,13 @@ func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) {
|
||||
for i, g := range gs {
|
||||
mfs, err := g.Gather()
|
||||
if err != nil {
|
||||
if multiErr, ok := err.(MultiError); ok {
|
||||
multiErr := MultiError{}
|
||||
if errors.As(err, &multiErr) {
|
||||
for _, err := range multiErr {
|
||||
errs = append(errs, fmt.Errorf("[from Gatherer #%d] %s", i+1, err))
|
||||
errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err))
|
||||
}
|
||||
} else {
|
||||
errs = append(errs, fmt.Errorf("[from Gatherer #%d] %s", i+1, err))
|
||||
errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err))
|
||||
}
|
||||
}
|
||||
for _, mf := range mfs {
|
||||
@ -884,11 +892,11 @@ func checkMetricConsistency(
|
||||
h.Write(separatorByteSlice)
|
||||
// Make sure label pairs are sorted. We depend on it for the consistency
|
||||
// check.
|
||||
if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) {
|
||||
if !sort.IsSorted(internal.LabelPairSorter(dtoMetric.Label)) {
|
||||
// We cannot sort dtoMetric.Label in place as it is immutable by contract.
|
||||
copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label))
|
||||
copy(copiedLabels, dtoMetric.Label)
|
||||
sort.Sort(labelPairSorter(copiedLabels))
|
||||
sort.Sort(internal.LabelPairSorter(copiedLabels))
|
||||
dtoMetric.Label = copiedLabels
|
||||
}
|
||||
for _, lp := range dtoMetric.Label {
|
||||
@ -935,7 +943,7 @@ func checkDescConsistency(
|
||||
metricFamily.GetName(), dtoMetric, desc,
|
||||
)
|
||||
}
|
||||
sort.Sort(labelPairSorter(lpsFromDesc))
|
||||
sort.Sort(internal.LabelPairSorter(lpsFromDesc))
|
||||
for i, lpFromDesc := range lpsFromDesc {
|
||||
lpFromMetric := dtoMetric.Label[i]
|
||||
if lpFromDesc.GetName() != lpFromMetric.GetName() ||
|
||||
@ -948,3 +956,89 @@ func checkDescConsistency(
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ TransactionalGatherer = &MultiTRegistry{}
|
||||
|
||||
// MultiTRegistry is a TransactionalGatherer that joins gathered metrics from multiple
|
||||
// transactional gatherers.
|
||||
//
|
||||
// It is caller responsibility to ensure two registries have mutually exclusive metric families,
|
||||
// no deduplication will happen.
|
||||
type MultiTRegistry struct {
|
||||
tGatherers []TransactionalGatherer
|
||||
}
|
||||
|
||||
// NewMultiTRegistry creates MultiTRegistry.
|
||||
func NewMultiTRegistry(tGatherers ...TransactionalGatherer) *MultiTRegistry {
|
||||
return &MultiTRegistry{
|
||||
tGatherers: tGatherers,
|
||||
}
|
||||
}
|
||||
|
||||
// Gather implements TransactionalGatherer interface.
|
||||
func (r *MultiTRegistry) Gather() (mfs []*dto.MetricFamily, done func(), err error) {
|
||||
errs := MultiError{}
|
||||
|
||||
dFns := make([]func(), 0, len(r.tGatherers))
|
||||
// TODO(bwplotka): Implement concurrency for those?
|
||||
for _, g := range r.tGatherers {
|
||||
// TODO(bwplotka): Check for duplicates?
|
||||
m, d, err := g.Gather()
|
||||
errs.Append(err)
|
||||
|
||||
mfs = append(mfs, m...)
|
||||
dFns = append(dFns, d)
|
||||
}
|
||||
|
||||
// TODO(bwplotka): Consider sort in place, given metric family in gather is sorted already.
|
||||
sort.Slice(mfs, func(i, j int) bool {
|
||||
return *mfs[i].Name < *mfs[j].Name
|
||||
})
|
||||
return mfs, func() {
|
||||
for _, d := range dFns {
|
||||
d()
|
||||
}
|
||||
}, errs.MaybeUnwrap()
|
||||
}
|
||||
|
||||
// TransactionalGatherer represents transactional gatherer that can be triggered to notify gatherer that memory
|
||||
// used by metric family is no longer used by a caller. This allows implementations with cache.
|
||||
type TransactionalGatherer interface {
|
||||
// Gather returns metrics in a lexicographically sorted slice
|
||||
// of uniquely named MetricFamily protobufs. Gather ensures that the
|
||||
// returned slice is valid and self-consistent so that it can be used
|
||||
// for valid exposition. As an exception to the strict consistency
|
||||
// requirements described for metric.Desc, Gather will tolerate
|
||||
// different sets of label names for metrics of the same metric family.
|
||||
//
|
||||
// Even if an error occurs, Gather attempts to gather as many metrics as
|
||||
// possible. Hence, if a non-nil error is returned, the returned
|
||||
// MetricFamily slice could be nil (in case of a fatal error that
|
||||
// prevented any meaningful metric collection) or contain a number of
|
||||
// MetricFamily protobufs, some of which might be incomplete, and some
|
||||
// might be missing altogether. The returned error (which might be a
|
||||
// MultiError) explains the details. Note that this is mostly useful for
|
||||
// debugging purposes. If the gathered protobufs are to be used for
|
||||
// exposition in actual monitoring, it is almost always better to not
|
||||
// expose an incomplete result and instead disregard the returned
|
||||
// MetricFamily protobufs in case the returned error is non-nil.
|
||||
//
|
||||
// Important: done is expected to be triggered (even if the error occurs!)
|
||||
// once caller does not need returned slice of dto.MetricFamily.
|
||||
Gather() (_ []*dto.MetricFamily, done func(), err error)
|
||||
}
|
||||
|
||||
// ToTransactionalGatherer transforms Gatherer to transactional one with noop as done function.
|
||||
func ToTransactionalGatherer(g Gatherer) TransactionalGatherer {
|
||||
return &noTransactionGatherer{g: g}
|
||||
}
|
||||
|
||||
type noTransactionGatherer struct {
|
||||
g Gatherer
|
||||
}
|
||||
|
||||
// Gather implements TransactionalGatherer interface.
|
||||
func (g *noTransactionGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) {
|
||||
mfs, err := g.g.Gather()
|
||||
return mfs, func() {}, err
|
||||
}
|
||||
|
||||
47
vendor/github.com/prometheus/client_golang/prometheus/value.go
generated
vendored
47
vendor/github.com/prometheus/client_golang/prometheus/value.go
generated
vendored
@ -23,6 +23,8 @@ import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/internal"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
@ -38,6 +40,23 @@ const (
|
||||
UntypedValue
|
||||
)
|
||||
|
||||
var (
|
||||
CounterMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_COUNTER; return &d }()
|
||||
GaugeMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_GAUGE; return &d }()
|
||||
UntypedMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_UNTYPED; return &d }()
|
||||
)
|
||||
|
||||
func (v ValueType) ToDTO() *dto.MetricType {
|
||||
switch v {
|
||||
case CounterValue:
|
||||
return CounterMetricTypePtr
|
||||
case GaugeValue:
|
||||
return GaugeMetricTypePtr
|
||||
default:
|
||||
return UntypedMetricTypePtr
|
||||
}
|
||||
}
|
||||
|
||||
// valueFunc is a generic metric for simple values retrieved on collect time
|
||||
// from a function. It implements Metric and Collector. Its effective type is
|
||||
// determined by ValueType. This is a low-level building block used by the
|
||||
@ -91,11 +110,15 @@ func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues
|
||||
if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metric := &dto.Metric{}
|
||||
if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &constMetric{
|
||||
desc: desc,
|
||||
valType: valueType,
|
||||
val: value,
|
||||
labelPairs: MakeLabelPairs(desc, labelValues),
|
||||
desc: desc,
|
||||
metric: metric,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -110,10 +133,8 @@ func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelVal
|
||||
}
|
||||
|
||||
type constMetric struct {
|
||||
desc *Desc
|
||||
valType ValueType
|
||||
val float64
|
||||
labelPairs []*dto.LabelPair
|
||||
desc *Desc
|
||||
metric *dto.Metric
|
||||
}
|
||||
|
||||
func (m *constMetric) Desc() *Desc {
|
||||
@ -121,7 +142,11 @@ func (m *constMetric) Desc() *Desc {
|
||||
}
|
||||
|
||||
func (m *constMetric) Write(out *dto.Metric) error {
|
||||
return populateMetric(m.valType, m.val, m.labelPairs, nil, out)
|
||||
out.Label = m.metric.Label
|
||||
out.Counter = m.metric.Counter
|
||||
out.Gauge = m.metric.Gauge
|
||||
out.Untyped = m.metric.Untyped
|
||||
return nil
|
||||
}
|
||||
|
||||
func populateMetric(
|
||||
@ -170,12 +195,12 @@ func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {
|
||||
})
|
||||
}
|
||||
labelPairs = append(labelPairs, desc.constLabelPairs...)
|
||||
sort.Sort(labelPairSorter(labelPairs))
|
||||
sort.Sort(internal.LabelPairSorter(labelPairs))
|
||||
return labelPairs
|
||||
}
|
||||
|
||||
// ExemplarMaxRunes is the max total number of runes allowed in exemplar labels.
|
||||
const ExemplarMaxRunes = 64
|
||||
const ExemplarMaxRunes = 128
|
||||
|
||||
// newExemplar creates a new dto.Exemplar from the provided values. An error is
|
||||
// returned if any of the label names or values are invalid or if the total
|
||||
|
||||
88
vendor/github.com/prometheus/client_golang/prometheus/vec.go
generated
vendored
88
vendor/github.com/prometheus/client_golang/prometheus/vec.go
generated
vendored
@ -99,6 +99,16 @@ func (m *MetricVec) Delete(labels Labels) bool {
|
||||
return m.metricMap.deleteByHashWithLabels(h, labels, m.curry)
|
||||
}
|
||||
|
||||
// DeletePartialMatch deletes all metrics where the variable labels contain all of those
|
||||
// passed in as labels. The order of the labels does not matter.
|
||||
// It returns the number of metrics deleted.
|
||||
//
|
||||
// Note that curried labels will never be matched if deleting from the curried vector.
|
||||
// To match curried labels with DeletePartialMatch, it must be called on the base vector.
|
||||
func (m *MetricVec) DeletePartialMatch(labels Labels) int {
|
||||
return m.metricMap.deleteByLabels(labels, m.curry)
|
||||
}
|
||||
|
||||
// Without explicit forwarding of Describe, Collect, Reset, those methods won't
|
||||
// show up in GoDoc.
|
||||
|
||||
@ -381,6 +391,82 @@ func (m *metricMap) deleteByHashWithLabels(
|
||||
return true
|
||||
}
|
||||
|
||||
// deleteByLabels deletes a metric if the given labels are present in the metric.
|
||||
func (m *metricMap) deleteByLabels(labels Labels, curry []curriedLabelValue) int {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
|
||||
var numDeleted int
|
||||
|
||||
for h, metrics := range m.metrics {
|
||||
i := findMetricWithPartialLabels(m.desc, metrics, labels, curry)
|
||||
if i >= len(metrics) {
|
||||
// Didn't find matching labels in this metric slice.
|
||||
continue
|
||||
}
|
||||
delete(m.metrics, h)
|
||||
numDeleted++
|
||||
}
|
||||
|
||||
return numDeleted
|
||||
}
|
||||
|
||||
// findMetricWithPartialLabel returns the index of the matching metric or
|
||||
// len(metrics) if not found.
|
||||
func findMetricWithPartialLabels(
|
||||
desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue,
|
||||
) int {
|
||||
for i, metric := range metrics {
|
||||
if matchPartialLabels(desc, metric.values, labels, curry) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return len(metrics)
|
||||
}
|
||||
|
||||
// indexOf searches the given slice of strings for the target string and returns
|
||||
// the index or len(items) as well as a boolean whether the search succeeded.
|
||||
func indexOf(target string, items []string) (int, bool) {
|
||||
for i, l := range items {
|
||||
if l == target {
|
||||
return i, true
|
||||
}
|
||||
}
|
||||
return len(items), false
|
||||
}
|
||||
|
||||
// valueMatchesVariableOrCurriedValue determines if a value was previously curried,
|
||||
// and returns whether it matches either the "base" value or the curried value accordingly.
|
||||
// It also indicates whether the match is against a curried or uncurried value.
|
||||
func valueMatchesVariableOrCurriedValue(targetValue string, index int, values []string, curry []curriedLabelValue) (bool, bool) {
|
||||
for _, curriedValue := range curry {
|
||||
if curriedValue.index == index {
|
||||
// This label was curried. See if the curried value matches our target.
|
||||
return curriedValue.value == targetValue, true
|
||||
}
|
||||
}
|
||||
// This label was not curried. See if the current value matches our target label.
|
||||
return values[index] == targetValue, false
|
||||
}
|
||||
|
||||
// matchPartialLabels searches the current metric and returns whether all of the target label:value pairs are present.
|
||||
func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool {
|
||||
for l, v := range labels {
|
||||
// Check if the target label exists in our metrics and get the index.
|
||||
varLabelIndex, validLabel := indexOf(l, desc.variableLabels)
|
||||
if validLabel {
|
||||
// Check the value of that label against the target value.
|
||||
// We don't consider curried values in partial matches.
|
||||
matches, curried := valueMatchesVariableOrCurriedValue(v, varLabelIndex, values, curry)
|
||||
if matches && !curried {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value
|
||||
// or creates it and returns the new one.
|
||||
//
|
||||
@ -485,7 +571,7 @@ func findMetricWithLabels(
|
||||
return len(metrics)
|
||||
}
|
||||
|
||||
func matchLabelValues(values []string, lvs []string, curry []curriedLabelValue) bool {
|
||||
func matchLabelValues(values, lvs []string, curry []curriedLabelValue) bool {
|
||||
if len(values) != len(lvs)+len(curry) {
|
||||
return false
|
||||
}
|
||||
|
||||
4
vendor/github.com/prometheus/client_golang/prometheus/wrap.go
generated
vendored
4
vendor/github.com/prometheus/client_golang/prometheus/wrap.go
generated
vendored
@ -21,6 +21,8 @@ import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/internal"
|
||||
)
|
||||
|
||||
// WrapRegistererWith returns a Registerer wrapping the provided
|
||||
@ -182,7 +184,7 @@ func (m *wrappingMetric) Write(out *dto.Metric) error {
|
||||
Value: proto.String(lv),
|
||||
})
|
||||
}
|
||||
sort.Sort(labelPairSorter(out.Label))
|
||||
sort.Sort(internal.LabelPairSorter(out.Label))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
21
vendor/github.com/shirou/gopsutil/v3/cpu/cpu.go
generated
vendored
21
vendor/github.com/shirou/gopsutil/v3/cpu/cpu.go
generated
vendored
@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -86,10 +87,12 @@ func (c TimesStat) String() string {
|
||||
return `{` + strings.Join(v, ",") + `}`
|
||||
}
|
||||
|
||||
// Total returns the total number of seconds in a CPUTimesStat
|
||||
// Deprecated: Total returns the total number of seconds in a CPUTimesStat
|
||||
// Please do not use this internal function.
|
||||
func (c TimesStat) Total() float64 {
|
||||
total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq +
|
||||
c.Steal + c.Idle
|
||||
total := c.User + c.System + c.Idle + c.Nice + c.Iowait + c.Irq +
|
||||
c.Softirq + c.Steal + c.Guest + c.GuestNice
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
@ -99,9 +102,15 @@ func (c InfoStat) String() string {
|
||||
}
|
||||
|
||||
func getAllBusy(t TimesStat) (float64, float64) {
|
||||
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq +
|
||||
t.Softirq + t.Steal
|
||||
return busy + t.Idle, busy
|
||||
tot := t.Total()
|
||||
if runtime.GOOS == "linux" {
|
||||
tot -= t.Guest // Linux 2.6.24+
|
||||
tot -= t.GuestNice // Linux 3.2.0+
|
||||
}
|
||||
|
||||
busy := tot - t.Idle - t.Iowait
|
||||
|
||||
return tot, busy
|
||||
}
|
||||
|
||||
func calculateBusy(t1, t2 TimesStat) float64 {
|
||||
|
||||
4
vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.c
generated
vendored
4
vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.c
generated
vendored
@ -18,17 +18,15 @@ static int fillstat(io_registry_entry_t d, DriveStats *stat);
|
||||
int
|
||||
gopsutil_v3_readdrivestat(DriveStats a[], int n)
|
||||
{
|
||||
mach_port_t port;
|
||||
CFMutableDictionaryRef match;
|
||||
io_iterator_t drives;
|
||||
io_registry_entry_t d;
|
||||
kern_return_t status;
|
||||
int na, rv;
|
||||
|
||||
IOMainPort(bootstrap_port, &port);
|
||||
match = IOServiceMatching("IOMedia");
|
||||
CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);
|
||||
status = IOServiceGetMatchingServices(port, match, &drives);
|
||||
status = IOServiceGetMatchingServices(0, match, &drives);
|
||||
if(status != KERN_SUCCESS)
|
||||
return -1;
|
||||
|
||||
|
||||
4
vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.h
generated
vendored
4
vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.h
generated
vendored
@ -30,7 +30,3 @@ struct CPUStats {
|
||||
};
|
||||
|
||||
extern int gopsutil_v3_readdrivestat(DriveStats a[], int n);
|
||||
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < 120000) // Before macOS 12 Monterey
|
||||
#define IOMainPort IOMasterPort
|
||||
#endif
|
||||
|
||||
9
vendor/github.com/shirou/gopsutil/v3/internal/common/common.go
generated
vendored
9
vendor/github.com/shirou/gopsutil/v3/internal/common/common.go
generated
vendored
@ -311,6 +311,15 @@ func PathExists(filename string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// PathExistsWithContents returns the filename exists and it is not empty
|
||||
func PathExistsWithContents(filename string) bool {
|
||||
info, err := os.Stat(filename)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return info.Size() > 4 // at least 4 bytes
|
||||
}
|
||||
|
||||
// GetEnv retrieves the environment variable key. If it does not exist it returns the default.
|
||||
func GetEnv(key string, dfault string, combineWith ...string) string {
|
||||
value := os.Getenv(key)
|
||||
|
||||
6
vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go
generated
vendored
6
vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go
generated
vendored
@ -274,6 +274,12 @@ func GetOSRelease() (platform string, version string, err error) {
|
||||
version = trimQuotes(field[1])
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup amazon ID
|
||||
if platform == "amzn" {
|
||||
platform = "amazon"
|
||||
}
|
||||
|
||||
return platform, version, nil
|
||||
}
|
||||
|
||||
|
||||
10
vendor/github.com/shirou/gopsutil/v3/internal/common/endian.go
generated
vendored
Normal file
10
vendor/github.com/shirou/gopsutil/v3/internal/common/endian.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
package common
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// IsLittleEndian checks if the current platform uses little-endian.
|
||||
// copied from https://github.com/ntrrg/ntgo/blob/v0.8.0/runtime/infrastructure.go#L16 (MIT License)
|
||||
func IsLittleEndian() bool {
|
||||
var x int16 = 0x0011
|
||||
return *(*byte)(unsafe.Pointer(&x)) == 0x11
|
||||
}
|
||||
5
vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin_cgo.go
generated
vendored
5
vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin_cgo.go
generated
vendored
@ -5,6 +5,7 @@ package mem
|
||||
|
||||
/*
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/vm_page_size.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
@ -12,8 +13,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// VirtualMemory returns VirtualmemoryStat.
|
||||
@ -34,7 +33,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
||||
return nil, fmt.Errorf("host_statistics error=%d", status)
|
||||
}
|
||||
|
||||
pageSize := uint64(unix.Getpagesize())
|
||||
pageSize := uint64(C.vm_kernel_page_size)
|
||||
total, err := getHwMemsize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
8
vendor/github.com/shirou/gopsutil/v3/net/net_linux.go
generated
vendored
8
vendor/github.com/shirou/gopsutil/v3/net/net_linux.go
generated
vendored
@ -721,9 +721,13 @@ func decodeAddressWithContext(ctx context.Context, family uint32, src string) (A
|
||||
return Addr{}, fmt.Errorf("decode error, %w", err)
|
||||
}
|
||||
var ip net.IP
|
||||
// Assumes this is little_endian
|
||||
|
||||
if family == syscall.AF_INET {
|
||||
ip = net.IP(ReverseWithContext(ctx, decoded))
|
||||
if common.IsLittleEndian() {
|
||||
ip = net.IP(ReverseWithContext(ctx, decoded))
|
||||
} else {
|
||||
ip = net.IP(decoded)
|
||||
}
|
||||
} else { // IPv6
|
||||
ip, err = parseIPv6HexStringWithContext(ctx, decoded)
|
||||
if err != nil {
|
||||
|
||||
236
vendor/github.com/shirou/gopsutil/v3/process/process_darwin_386.go
generated
vendored
236
vendor/github.com/shirou/gopsutil/v3/process/process_darwin_386.go
generated
vendored
@ -1,236 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_darwin.go
|
||||
|
||||
package process
|
||||
|
||||
const (
|
||||
sizeofPtr = 0x8
|
||||
sizeofShort = 0x2
|
||||
sizeofInt = 0x4
|
||||
sizeofLong = 0x8
|
||||
sizeofLongLong = 0x8
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int64
|
||||
_C_long_long int64
|
||||
)
|
||||
|
||||
type Timespec struct {
|
||||
Sec int64
|
||||
Nsec int64
|
||||
}
|
||||
|
||||
type Timeval struct {
|
||||
Sec int64
|
||||
Usec int32
|
||||
Pad_cgo_0 [4]byte
|
||||
}
|
||||
|
||||
type Rusage struct {
|
||||
Utime Timeval
|
||||
Stime Timeval
|
||||
Maxrss int64
|
||||
Ixrss int64
|
||||
Idrss int64
|
||||
Isrss int64
|
||||
Minflt int64
|
||||
Majflt int64
|
||||
Nswap int64
|
||||
Inblock int64
|
||||
Oublock int64
|
||||
Msgsnd int64
|
||||
Msgrcv int64
|
||||
Nsignals int64
|
||||
Nvcsw int64
|
||||
Nivcsw int64
|
||||
}
|
||||
|
||||
type Rlimit struct {
|
||||
Cur uint64
|
||||
Max uint64
|
||||
}
|
||||
|
||||
type UGid_t uint32
|
||||
|
||||
type KinfoProc struct {
|
||||
Proc ExternProc
|
||||
Eproc Eproc
|
||||
}
|
||||
|
||||
type Eproc struct {
|
||||
Paddr *uint64
|
||||
Sess *Session
|
||||
Pcred Upcred
|
||||
Ucred Uucred
|
||||
Pad_cgo_0 [4]byte
|
||||
Vm Vmspace
|
||||
Ppid int32
|
||||
Pgid int32
|
||||
Jobc int16
|
||||
Pad_cgo_1 [2]byte
|
||||
Tdev int32
|
||||
Tpgid int32
|
||||
Pad_cgo_2 [4]byte
|
||||
Tsess *Session
|
||||
Wmesg [8]int8
|
||||
Xsize int32
|
||||
Xrssize int16
|
||||
Xccount int16
|
||||
Xswrss int16
|
||||
Pad_cgo_3 [2]byte
|
||||
Flag int32
|
||||
Login [12]int8
|
||||
Spare [4]int32
|
||||
Pad_cgo_4 [4]byte
|
||||
}
|
||||
|
||||
type Proc struct{}
|
||||
|
||||
type Session struct{}
|
||||
|
||||
type ucred struct {
|
||||
Link _Ctype_struct___0
|
||||
Ref uint64
|
||||
Posix Posix_cred
|
||||
Label *Label
|
||||
Audit Au_session
|
||||
}
|
||||
|
||||
type Uucred struct {
|
||||
Ref int32
|
||||
UID uint32
|
||||
Ngroups int16
|
||||
Pad_cgo_0 [2]byte
|
||||
Groups [16]uint32
|
||||
}
|
||||
|
||||
type Upcred struct {
|
||||
Pc_lock [72]int8
|
||||
Pc_ucred *ucred
|
||||
P_ruid uint32
|
||||
P_svuid uint32
|
||||
P_rgid uint32
|
||||
P_svgid uint32
|
||||
P_refcnt int32
|
||||
Pad_cgo_0 [4]byte
|
||||
}
|
||||
|
||||
type Vmspace struct {
|
||||
Dummy int32
|
||||
Pad_cgo_0 [4]byte
|
||||
Dummy2 *int8
|
||||
Dummy3 [5]int32
|
||||
Pad_cgo_1 [4]byte
|
||||
Dummy4 [3]*int8
|
||||
}
|
||||
|
||||
type Sigacts struct{}
|
||||
|
||||
type ExternProc struct {
|
||||
P_un [16]byte
|
||||
P_vmspace uint64
|
||||
P_sigacts uint64
|
||||
Pad_cgo_0 [3]byte
|
||||
P_flag int32
|
||||
P_stat int8
|
||||
P_pid int32
|
||||
P_oppid int32
|
||||
P_dupfd int32
|
||||
Pad_cgo_1 [4]byte
|
||||
User_stack uint64
|
||||
Exit_thread uint64
|
||||
P_debugger int32
|
||||
Sigwait int32
|
||||
P_estcpu uint32
|
||||
P_cpticks int32
|
||||
P_pctcpu uint32
|
||||
Pad_cgo_2 [4]byte
|
||||
P_wchan uint64
|
||||
P_wmesg uint64
|
||||
P_swtime uint32
|
||||
P_slptime uint32
|
||||
P_realtimer Itimerval
|
||||
P_rtime Timeval
|
||||
P_uticks uint64
|
||||
P_sticks uint64
|
||||
P_iticks uint64
|
||||
P_traceflag int32
|
||||
Pad_cgo_3 [4]byte
|
||||
P_tracep uint64
|
||||
P_siglist int32
|
||||
Pad_cgo_4 [4]byte
|
||||
P_textvp uint64
|
||||
P_holdcnt int32
|
||||
P_sigmask uint32
|
||||
P_sigignore uint32
|
||||
P_sigcatch uint32
|
||||
P_priority uint8
|
||||
P_usrpri uint8
|
||||
P_nice int8
|
||||
P_comm [17]int8
|
||||
Pad_cgo_5 [4]byte
|
||||
P_pgrp uint64
|
||||
P_addr uint64
|
||||
P_xstat uint16
|
||||
P_acflag uint16
|
||||
Pad_cgo_6 [4]byte
|
||||
P_ru uint64
|
||||
}
|
||||
|
||||
type Itimerval struct {
|
||||
Interval Timeval
|
||||
Value Timeval
|
||||
}
|
||||
|
||||
type Vnode struct{}
|
||||
|
||||
type Pgrp struct{}
|
||||
|
||||
type UserStruct struct{}
|
||||
|
||||
type Au_session struct {
|
||||
Aia_p *AuditinfoAddr
|
||||
Mask AuMask
|
||||
}
|
||||
|
||||
type Posix_cred struct {
|
||||
UID uint32
|
||||
Ruid uint32
|
||||
Svuid uint32
|
||||
Ngroups int16
|
||||
Pad_cgo_0 [2]byte
|
||||
Groups [16]uint32
|
||||
Rgid uint32
|
||||
Svgid uint32
|
||||
Gmuid uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type Label struct{}
|
||||
|
||||
type AuditinfoAddr struct {
|
||||
Auid uint32
|
||||
Mask AuMask
|
||||
Termid AuTidAddr
|
||||
Asid int32
|
||||
Flags uint64
|
||||
}
|
||||
|
||||
type AuMask struct {
|
||||
Success uint32
|
||||
Failure uint32
|
||||
}
|
||||
|
||||
type AuTidAddr struct {
|
||||
Port int32
|
||||
Type uint32
|
||||
Addr [4]uint32
|
||||
}
|
||||
|
||||
type UcredQueue struct {
|
||||
Next *ucred
|
||||
Prev **ucred
|
||||
}
|
||||
6
vendor/github.com/shirou/gopsutil/v3/process/process_linux.go
generated
vendored
6
vendor/github.com/shirou/gopsutil/v3/process/process_linux.go
generated
vendored
@ -688,9 +688,9 @@ func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string
|
||||
if len(cmdline) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if cmdline[len(cmdline)-1] == 0 {
|
||||
cmdline = cmdline[:len(cmdline)-1]
|
||||
}
|
||||
|
||||
cmdline = bytes.TrimRight(cmdline, "\x00")
|
||||
|
||||
parts := bytes.Split(cmdline, []byte{0})
|
||||
var strParts []string
|
||||
for _, p := range parts {
|
||||
|
||||
10
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
10
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
@ -736,6 +736,16 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim
|
||||
return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// WithinRangef asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted")
|
||||
func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// YAMLEqf asserts that two YAML strings are equivalent.
|
||||
func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
|
||||
20
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
20
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
@ -1461,6 +1461,26 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta
|
||||
return WithinDurationf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// WithinRange asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))
|
||||
func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return WithinRange(a.t, actual, start, end, msgAndArgs...)
|
||||
}
|
||||
|
||||
// WithinRangef asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted")
|
||||
func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return WithinRangef(a.t, actual, start, end, msg, args...)
|
||||
}
|
||||
|
||||
// YAMLEq asserts that two YAML strings are equivalent.
|
||||
func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
|
||||
71
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
71
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@ -144,7 +145,8 @@ func CallerInfo() []string {
|
||||
if len(parts) > 1 {
|
||||
dir := parts[len(parts)-2]
|
||||
if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
|
||||
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
|
||||
path, _ := filepath.Abs(file)
|
||||
callers = append(callers, fmt.Sprintf("%s:%d", path, line))
|
||||
}
|
||||
}
|
||||
|
||||
@ -816,7 +818,6 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
|
||||
return true // we consider nil to be equal to the nil set
|
||||
}
|
||||
|
||||
subsetValue := reflect.ValueOf(subset)
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ok = false
|
||||
@ -826,14 +827,32 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
|
||||
listKind := reflect.TypeOf(list).Kind()
|
||||
subsetKind := reflect.TypeOf(subset).Kind()
|
||||
|
||||
if listKind != reflect.Array && listKind != reflect.Slice {
|
||||
if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice {
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
subsetValue := reflect.ValueOf(subset)
|
||||
if subsetKind == reflect.Map && listKind == reflect.Map {
|
||||
listValue := reflect.ValueOf(list)
|
||||
subsetKeys := subsetValue.MapKeys()
|
||||
|
||||
for i := 0; i < len(subsetKeys); i++ {
|
||||
subsetKey := subsetKeys[i]
|
||||
subsetElement := subsetValue.MapIndex(subsetKey).Interface()
|
||||
listElement := listValue.MapIndex(subsetKey).Interface()
|
||||
|
||||
if !ObjectsAreEqual(subsetElement, listElement) {
|
||||
return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, subsetElement), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < subsetValue.Len(); i++ {
|
||||
element := subsetValue.Index(i).Interface()
|
||||
ok, found := containsElement(list, element)
|
||||
@ -860,7 +879,6 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
|
||||
return Fail(t, "nil is the empty set which is a subset of every set", msgAndArgs...)
|
||||
}
|
||||
|
||||
subsetValue := reflect.ValueOf(subset)
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ok = false
|
||||
@ -870,14 +888,32 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
|
||||
listKind := reflect.TypeOf(list).Kind()
|
||||
subsetKind := reflect.TypeOf(subset).Kind()
|
||||
|
||||
if listKind != reflect.Array && listKind != reflect.Slice {
|
||||
if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice {
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
subsetValue := reflect.ValueOf(subset)
|
||||
if subsetKind == reflect.Map && listKind == reflect.Map {
|
||||
listValue := reflect.ValueOf(list)
|
||||
subsetKeys := subsetValue.MapKeys()
|
||||
|
||||
for i := 0; i < len(subsetKeys); i++ {
|
||||
subsetKey := subsetKeys[i]
|
||||
subsetElement := subsetValue.MapIndex(subsetKey).Interface()
|
||||
listElement := listValue.MapIndex(subsetKey).Interface()
|
||||
|
||||
if !ObjectsAreEqual(subsetElement, listElement) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
|
||||
}
|
||||
|
||||
for i := 0; i < subsetValue.Len(); i++ {
|
||||
element := subsetValue.Index(i).Interface()
|
||||
ok, found := containsElement(list, element)
|
||||
@ -1110,6 +1146,27 @@ func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration,
|
||||
return true
|
||||
}
|
||||
|
||||
// WithinRange asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))
|
||||
func WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
|
||||
if end.Before(start) {
|
||||
return Fail(t, "Start should be before end", msgAndArgs...)
|
||||
}
|
||||
|
||||
if actual.Before(start) {
|
||||
return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is before the range", actual, start, end), msgAndArgs...)
|
||||
} else if actual.After(end) {
|
||||
return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is after the range", actual, start, end), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func toFloat(x interface{}) (float64, bool) {
|
||||
var xf float64
|
||||
xok := true
|
||||
|
||||
26
vendor/github.com/stretchr/testify/require/require.go
generated
vendored
26
vendor/github.com/stretchr/testify/require/require.go
generated
vendored
@ -1864,6 +1864,32 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// WithinRange asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))
|
||||
func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.WithinRange(t, actual, start, end, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// WithinRangef asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted")
|
||||
func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.WithinRangef(t, actual, start, end, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// YAMLEq asserts that two YAML strings are equivalent.
|
||||
func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
|
||||
20
vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
20
vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
@ -1462,6 +1462,26 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta
|
||||
WithinDurationf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// WithinRange asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))
|
||||
func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
WithinRange(a.t, actual, start, end, msgAndArgs...)
|
||||
}
|
||||
|
||||
// WithinRangef asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted")
|
||||
func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
WithinRangef(a.t, actual, start, end, msg, args...)
|
||||
}
|
||||
|
||||
// YAMLEq asserts that two YAML strings are equivalent.
|
||||
func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user