diff --git a/backend/go.mod b/backend/go.mod index b8b8169a..c13f71bf 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -29,7 +29,7 @@ require ( go.opentelemetry.io/otel/exporters/zipkin v1.35.0 go.opentelemetry.io/otel/sdk v1.35.0 go.uber.org/fx v1.23.0 - golang.org/x/crypto v0.37.0 + golang.org/x/crypto v0.38.0 golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 golang.org/x/oauth2 v0.29.0 google.golang.org/grpc v1.72.0 @@ -105,9 +105,9 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/net v0.39.0 // indirect - golang.org/x/sync v0.13.0 // indirect - golang.org/x/sys v0.32.0 // indirect - golang.org/x/text v0.24.0 // indirect + golang.org/x/sync v0.14.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.25.0 // indirect golang.org/x/tools v0.32.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250425173222-7b384671a197 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250425173222-7b384671a197 // indirect diff --git a/backend/go.sum b/backend/go.sum index cc575f73..73c44d51 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -42,8 +42,6 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= -github.com/cucumber/godog v0.13.0 h1:KvX9kNWmAJwp882HmObGOyBbNUP5SXQ+SDLNajsuV7A= -github.com/cucumber/godog v0.13.0/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces= github.com/cucumber/godog v0.15.0 h1:51AL8lBXF3f0cyA5CV4TnJFCTHpgiy+1x1Hb3TtZUmo= github.com/cucumber/godog v0.15.0/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces= github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= @@ -114,13 +112,11 @@ github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPArei github.com/gofiber/swagger v1.1.1 h1:FZVhVQQ9s1ZKLHL/O0loLh49bYB5l1HEAgxDlcTtkRA= github.com/gofiber/swagger v1.1.1/go.mod h1:vtvY/sQAMc/lGTUCg0lqmBL7Ht9O7uzChpbvJeJQINw= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -184,7 +180,6 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= github.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo= github.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y= @@ -208,7 +203,6 @@ github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -362,7 +356,6 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -474,8 +467,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= @@ -515,8 +508,8 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -545,8 +538,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -555,8 +548,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/backend/vendor/github.com/cucumber/godog/.gitignore b/backend/vendor/github.com/cucumber/godog/.gitignore index 76481388..bd77fc9f 100644 --- a/backend/vendor/github.com/cucumber/godog/.gitignore +++ b/backend/vendor/github.com/cucumber/godog/.gitignore @@ -8,4 +8,6 @@ Gopkg.toml .idea .vscode -_artifacts \ No newline at end of file +_artifacts + +vendor diff --git a/backend/vendor/github.com/cucumber/godog/CHANGELOG.md b/backend/vendor/github.com/cucumber/godog/CHANGELOG.md index d0718848..11558f10 100644 --- a/backend/vendor/github.com/cucumber/godog/CHANGELOG.md +++ b/backend/vendor/github.com/cucumber/godog/CHANGELOG.md @@ -8,6 +8,38 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt ## Unreleased +## [v0.15.0] + +### Added +- Improved the type checking of step return types and improved the error messages - ([647](https://github.com/cucumber/godog/pull/647) - [johnlon](https://github.com/johnlon)) +- Ambiguous step definitions will now be detected when strict mode is activated - ([636](https://github.com/cucumber/godog/pull/636)/([648](https://github.com/cucumber/godog/pull/648) - [johnlon](https://github.com/johnlon)) +- Provide support for attachments / embeddings including a new example in the examples dir - ([623](https://github.com/cucumber/godog/pull/623) - [johnlon](https://github.com/johnlon)) + +### Changed +- Formatters now have a `Close` method and associated `io.Writer` changed to `io.WriteCloser`. + +## [v0.14.1] + +### Added +- Provide testing.T-compatible interface on test context, allowing usage of assertion libraries such as testify's assert/require - ([571](https://github.com/cucumber/godog/pull/571) - [mrsheepuk](https://github.com/mrsheepuk)) +- Created releasing guidelines - ([608](https://github.com/cucumber/godog/pull/608) - [glibas](https://github.com/glibas)) + +### Fixed +- Step duration calculation - ([616](https://github.com/cucumber/godog/pull/616) - [iaroslav-ciupin](https://github.com/iaroslav-ciupin)) +- Invalid memory address or nil pointer dereference in RetrieveFeatures - ([566](https://github.com/cucumber/godog/pull/566) - [corneldamian](https://github.com/corneldamian)) + +## [v0.14.0] +### Added +- Improve ErrSkip handling, add test for Summary and operations order ([584](https://github.com/cucumber/godog/pull/584) - [vearutop](https://github.com/vearutop)) + +### Fixed +- Remove line overwriting for scenario outlines in cucumber formatter ([605](https://github.com/cucumber/godog/pull/605) - [glibas](https://github.com/glibas)) +- Remove duplicate warning message ([590](https://github.com/cucumber/godog/pull/590) - [vearutop](https://github.com/vearutop)) +- updated base formatter to set a scenario as passed unless there exist ([582](https://github.com/cucumber/godog/pull/582) - [roskee](https://github.com/roskee)) + +### Changed +- Update test.yml ([583](https://github.com/cucumber/godog/pull/583) - [vearutop](https://github.com/vearutop)) + ## [v0.13.0] ### Added - Support for reading feature files from an `fs.FS` ([550](https://github.com/cucumber/godog/pull/550) - [tigh-latte](https://github.com/tigh-latte)) @@ -209,6 +241,9 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt ### Changed - Changed code references to DATA-DOG/godog to cucumber/godog to help get things building correctly. ([mxygem](https://github.com/mxygem)) +[v0.15.0]: https://github.com/cucumber/godog/compare/v0.14.1...v0.15.0 +[v0.14.1]: https://github.com/cucumber/godog/compare/v0.14.0...v0.14.1 +[v0.14.0]: https://github.com/cucumber/godog/compare/v0.13.0...v0.14.0 [v0.13.0]: https://github.com/cucumber/godog/compare/v0.12.6...v0.13.0 [v0.12.6]: https://github.com/cucumber/godog/compare/v0.12.5...v0.12.6 [v0.12.5]: https://github.com/cucumber/godog/compare/v0.12.4...v0.12.5 diff --git a/backend/vendor/github.com/cucumber/godog/CONTRIBUTING.md b/backend/vendor/github.com/cucumber/godog/CONTRIBUTING.md index 44678225..c21ee426 100644 --- a/backend/vendor/github.com/cucumber/godog/CONTRIBUTING.md +++ b/backend/vendor/github.com/cucumber/godog/CONTRIBUTING.md @@ -7,7 +7,7 @@ to give you a grounding in some of the basic concepts. You could also watch [thi We want you to feel safe to make mistakes, and ask questions. If anything in this guide or anywhere else in the codebase doesn't make sense to you, please let us know! It's through your feedback that we can make this codebase more welcoming, so we'll be glad to hear thoughts. -You can chat with us in the [#committers-go](https://cucumberbdd.slack.com/archives/CA5NJPDJ4) channel in our [community Slack], or feel free to [raise an issue] if you're experiencing any friction trying make your contribution. +You can chat with us in the `#committers` channel in our [community Discord](https://cucumber.io/docs/community/get-in-touch/#discord), or feel free to [raise an issue] if you're experiencing any friction trying make your contribution. ## Setup @@ -20,7 +20,7 @@ Once that's done, try running the tests: If everything passes, you're ready to hack! [install go]: https://golang.org/doc/install -[community Slack]: https://cucumber.io/community#slack +[community Discord]: https://cucumber.io/community#discord [raise an issue]: https://github.com/cucumber/godog/issues/new/choose ## Changing dependencies diff --git a/backend/vendor/github.com/cucumber/godog/Makefile b/backend/vendor/github.com/cucumber/godog/Makefile index 01bbc5c4..aefccb13 100644 --- a/backend/vendor/github.com/cucumber/godog/Makefile +++ b/backend/vendor/github.com/cucumber/godog/Makefile @@ -2,21 +2,32 @@ VERS ?= $(shell git symbolic-ref -q --short HEAD || git describe --tags --exact-match) -FOUND_GO_VERSION := $(shell go version) -EXPECTED_GO_VERSION = 1.17 +GO_MAJOR_VERSION = $(shell go version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1) +GO_MINOR_VERSION = $(shell go version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2) +MINIMUM_SUPPORTED_GO_MAJOR_VERSION = 1 +MINIMUM_SUPPORTED_GO_MINOR_VERSION = 16 +GO_VERSION_VALIDATION_ERR_MSG = Go version $(GO_MAJOR_VERSION).$(GO_MINOR_VERSION) is not supported, please update to at least $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION).$(MINIMUM_SUPPORTED_GO_MINOR_VERSION) + .PHONY: check-go-version check-go-version: - @$(if $(findstring ${EXPECTED_GO_VERSION}, ${FOUND_GO_VERSION}),(exit 0),(echo Wrong go version! Please install ${EXPECTED_GO_VERSION}; exit 1)) + @if [ $(GO_MAJOR_VERSION) -gt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \ + exit 0 ;\ + elif [ $(GO_MAJOR_VERSION) -lt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \ + echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\ + exit 1; \ + elif [ $(GO_MINOR_VERSION) -lt $(MINIMUM_SUPPORTED_GO_MINOR_VERSION) ] ; then \ + echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\ + exit 1; \ + fi test: check-go-version @echo "running all tests" - @go install ./... @go fmt ./... - @go run honnef.co/go/tools/cmd/staticcheck@v0.2.2 github.com/cucumber/godog - @go run honnef.co/go/tools/cmd/staticcheck@v0.2.2 github.com/cucumber/godog/cmd/godog + @go run honnef.co/go/tools/cmd/staticcheck@v0.4.7 github.com/cucumber/godog + @go run honnef.co/go/tools/cmd/staticcheck@v0.4.7 github.com/cucumber/godog/cmd/godog go vet ./... go test -race ./... - godog -f progress -c 4 + go run ./cmd/godog -f progress -c 4 gherkin: @if [ -z "$(VERS)" ]; then echo "Provide gherkin version like: 'VERS=commit-hash'"; exit 1; fi diff --git a/backend/vendor/github.com/cucumber/godog/README.md b/backend/vendor/github.com/cucumber/godog/README.md index 494f4426..fbe765f5 100644 --- a/backend/vendor/github.com/cucumber/godog/README.md +++ b/backend/vendor/github.com/cucumber/godog/README.md @@ -46,15 +46,11 @@ Godog is a community driven Open Source Project within the Cucumber organization See the [contributing guide] for more detail on how to get started. -## Getting help - -We have a [community Slack] where you can chat with other users, developers, and BDD practitioners. +See the [releasing guide] for release flow details. -Here are some useful channels to try: +## Getting help -- [#help-godog](https://cucumberbdd.slack.com/archives/CTNL1JCVA) - General Godog Adoption Help -- [#committers-go](https://cucumberbdd.slack.com/archives/CA5NJPDJ4) - Golang focused Cucumber Contributors -- [#committers](https://cucumberbdd.slack.com/archives/C62D0FK0E) - General Cucumber Contributors +We have a [community Discord](https://cucumber.io/docs/community/get-in-touch/#discord) where you can chat with other users, developers, and BDD practitioners. ## Examples @@ -290,6 +286,10 @@ When steps are orthogonal and small, you can combine them just like you do with `TestFeatures` acts as a regular Go test, so you can leverage your IDE facilities to run and debug it. +### Attachments + +An example showing how to make attachments (aka embeddings) to the results is shown in [_examples/attachments](/_examples/attachments/) + ## Code of Conduct Everyone interacting in this codebase and issue tracker is expected to follow the Cucumber [code of conduct](https://github.com/cucumber/cucumber/blob/master/CODE_OF_CONDUCT.md). @@ -493,31 +493,12 @@ If you want to filter scenarios by tags, you can use the `-t=` or `- A more extensive example can be [found here](/_examples/assert-godogs). ```go -func thereShouldBeRemaining(remaining int) error { - return assertExpectedAndActual( - assert.Equal, Godogs, remaining, - "Expected %d godogs to be remaining, but there is %d", remaining, Godogs, - ) -} - -// assertExpectedAndActual is a helper function to allow the step function to call -// assertion functions where you want to compare an expected and an actual value. -func assertExpectedAndActual(a expectedAndActualAssertion, expected, actual interface{}, msgAndArgs ...interface{}) error { - var t asserter - a(&t, expected, actual, msgAndArgs...) - return t.err -} - -type expectedAndActualAssertion func(t assert.TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool - -// asserter is used to be able to retrieve the error reported by the called assertion -type asserter struct { - err error -} - -// Errorf is used by the called assertion to report an error -func (a *asserter) Errorf(format string, args ...interface{}) { - a.err = fmt.Errorf(format, args...) +func thereShouldBeRemaining(ctx context.Context, remaining int) error { + assert.Equal( + godog.T(ctx), Godogs, remaining, + "Expected %d godogs to be remaining, but there is %d", remaining, Godogs, + ) + return nil } ``` @@ -595,4 +576,8 @@ A simple example can be [found here](/_examples/custom-formatter). [cucumber]: https://cucumber.io/ "Behavior driven development framework" [license]: https://en.wikipedia.org/wiki/MIT_License "The MIT license" [contributing guide]: https://github.com/cucumber/godog/blob/main/CONTRIBUTING.md -[community Slack]: https://cucumber.io/community#slack +[releasing guide]: https://github.com/cucumber/godog/blob/main/RELEASING.md +[community Discord]: https://cucumber.io/community#discord + + + diff --git a/backend/vendor/github.com/cucumber/godog/RELEASING.md b/backend/vendor/github.com/cucumber/godog/RELEASING.md new file mode 100644 index 00000000..cba24365 --- /dev/null +++ b/backend/vendor/github.com/cucumber/godog/RELEASING.md @@ -0,0 +1,67 @@ +# Releasing Guidelines for Cucumber Godog + +This document provides guidelines for releasing new versions of Cucumber Godog. Follow these steps to ensure a smooth and consistent release process. + +## Versioning + +Cucumber Godog follows [Semantic Versioning]. Version numbers are in the format `MAJOR.MINOR.PATCH`. + +### Current (for v0.MINOR.PATCH) + +- **MINOR**: Incompatible API changes. +- **PATCH**: Backward-compatible new features and bug fixes. + +### After v1.X.X release + +- **MAJOR**: Incompatible API changes. +- **MINOR**: Backward-compatible new features. +- **PATCH**: Backward-compatible bug fixes. + +## Release Process + +1. **Update Changelog:** + - Open `CHANGELOG.md` and add an entry for the upcoming release formatting according to the principles of [Keep A CHANGELOG]. + - Include details about new features, enhancements, and bug fixes. + +2. **Run Tests:** + - Run the test suite to ensure all existing features are working as expected. + +3. **Manual Testing for Backwards Compatibility:** + - Manually test the new release with external libraries that depend on Cucumber Godog. + - Look for any potential backwards compatibility issues, especially with widely-used libraries. + - Address any identified issues before proceeding. + +4. **Create Release on GitHub:** + - Go to the [Releases] page on GitHub. + - Click on "Draft a new release." + - Tag version should be set to the new tag vMAJOR.MINOR.PATCH + - Title the release using the version number (e.g., "vMAJOR.MINOR.PATCH"). + - Click 'Generate release notes' + +5. **Publish Release:** + - Click "Publish release" to make the release public. + +6. **Announce the Release:** + - Make an announcement on relevant communication channels (e.g., [community Discord]) about the new release. + +## Additional Considerations + +- **Documentation:** + - Update the project documentation on the [website], if applicable. + +- **Deprecation Notices:** + - If any features are deprecated, clearly document them in the release notes and provide guidance on migration. + +- **Compatibility:** + - Clearly state any compatibility requirements or changes in the release notes. + +- **Feedback:** + - Encourage users to provide feedback and report any issues with the new release. + +Following these guidelines, including manual testing with external libraries, will help ensure a thorough release process for Cucumber Godog, allowing detection and resolution of potential backwards compatibility issues before tagging the release. + +[community Discord]: https://cucumber.io/community#discord +[website]: https://cucumber.github.io/godog/ +[Releases]: https://github.com/cucumber/godog/releases +[Semantic Versioning]: http://semver.org +[Keep A CHANGELOG]: http://keepachangelog.com \ No newline at end of file diff --git a/backend/vendor/github.com/cucumber/godog/flags.go b/backend/vendor/github.com/cucumber/godog/flags.go index 14782e16..45efbfec 100644 --- a/backend/vendor/github.com/cucumber/godog/flags.go +++ b/backend/vendor/github.com/cucumber/godog/flags.go @@ -121,7 +121,7 @@ func BindFlags(prefix string, set *flag.FlagSet, opt *Options) { set.BoolVar(&opt.ShowStepDefinitions, prefix+"definitions", defShowStepDefinitions, "Print all available step definitions.") set.BoolVar(&opt.ShowStepDefinitions, prefix+"d", defShowStepDefinitions, "Print all available step definitions.") set.BoolVar(&opt.StopOnFailure, prefix+"stop-on-failure", defStopOnFailure, "Stop processing on first failed scenario.") - set.BoolVar(&opt.Strict, prefix+"strict", defStrict, "Fail suite when there are pending or undefined steps.") + set.BoolVar(&opt.Strict, prefix+"strict", defStrict, "Fail suite when there are pending or undefined or ambiguous steps.") set.BoolVar(&opt.NoColors, prefix+"no-colors", defNoColors, "Disable ansi colors.") set.Var(&randomSeed{&opt.Randomize}, prefix+"random", descRandomOption) set.BoolVar(&opt.ShowHelp, "godog.help", false, "Show usage help.") diff --git a/backend/vendor/github.com/cucumber/godog/formatters/fmt.go b/backend/vendor/github.com/cucumber/godog/formatters/fmt.go index aa098b0f..fec96961 100644 --- a/backend/vendor/github.com/cucumber/godog/formatters/fmt.go +++ b/backend/vendor/github.com/cucumber/godog/formatters/fmt.go @@ -70,6 +70,7 @@ type Formatter interface { Skipped(*messages.Pickle, *messages.PickleStep, *StepDefinition) Undefined(*messages.Pickle, *messages.PickleStep, *StepDefinition) Pending(*messages.Pickle, *messages.PickleStep, *StepDefinition) + Ambiguous(*messages.Pickle, *messages.PickleStep, *StepDefinition, error) Summary() } diff --git a/backend/vendor/github.com/cucumber/godog/internal/flags/flags.go b/backend/vendor/github.com/cucumber/godog/internal/flags/flags.go index 2d4a60d1..1bd67e59 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/flags/flags.go +++ b/backend/vendor/github.com/cucumber/godog/internal/flags/flags.go @@ -39,7 +39,7 @@ built-in formatters are: flagSet.BoolVarP(&opts.ShowStepDefinitions, prefix+"definitions", "d", opts.ShowStepDefinitions, "print all available step definitions") flagSet.BoolVar(&opts.StopOnFailure, prefix+"stop-on-failure", opts.StopOnFailure, "stop processing on first failed scenario") - flagSet.BoolVar(&opts.Strict, prefix+"strict", opts.Strict, "fail suite when there are pending or undefined steps") + flagSet.BoolVar(&opts.Strict, prefix+"strict", opts.Strict, "fail suite when there are pending or undefined or ambiguous steps") flagSet.Int64Var(&opts.Randomize, prefix+"random", opts.Randomize, `randomly shuffle the scenario execution order --random diff --git a/backend/vendor/github.com/cucumber/godog/internal/flags/options.go b/backend/vendor/github.com/cucumber/godog/internal/flags/options.go index fed059a7..5ca40f91 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/flags/options.go +++ b/backend/vendor/github.com/cucumber/godog/internal/flags/options.go @@ -38,7 +38,7 @@ type Options struct { // Stops on the first failure StopOnFailure bool - // Fail suite when there are pending or undefined steps + // Fail suite when there are pending or undefined or ambiguous steps Strict bool // Forces ansi color stripping diff --git a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt.go b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt.go index 883bc740..3efe1f46 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt.go +++ b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt.go @@ -36,6 +36,7 @@ var ( skipped = models.Skipped undefined = models.Undefined pending = models.Pending + ambiguous = models.Ambiguous ) type sortFeaturesByName []*models.Feature diff --git a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_base.go b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_base.go index 2166509e..607a1c06 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_base.go +++ b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_base.go @@ -85,10 +85,14 @@ func (f *Base) Failed(*messages.Pickle, *messages.PickleStep, *formatters.StepDe func (f *Base) Pending(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) { } +// Ambiguous captures ambiguous step. +func (f *Base) Ambiguous(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition, error) { +} + // Summary renders summary information. func (f *Base) Summary() { var totalSc, passedSc, undefinedSc int - var totalSt, passedSt, failedSt, skippedSt, pendingSt, undefinedSt int + var totalSt, passedSt, failedSt, skippedSt, pendingSt, undefinedSt, ambiguousSt int pickleResults := f.Storage.MustGetPickleResults() for _, pr := range pickleResults { @@ -106,11 +110,13 @@ func (f *Base) Summary() { switch sr.Status { case passed: - prStatus = passed passedSt++ case failed: prStatus = failed failedSt++ + case ambiguous: + prStatus = ambiguous + ambiguousSt++ case skipped: skippedSt++ case undefined: @@ -141,6 +147,10 @@ func (f *Base) Summary() { parts = append(parts, yellow(fmt.Sprintf("%d pending", pendingSt))) steps = append(steps, yellow(fmt.Sprintf("%d pending", pendingSt))) } + if ambiguousSt > 0 { + parts = append(parts, yellow(fmt.Sprintf("%d ambiguous", ambiguousSt))) + steps = append(steps, yellow(fmt.Sprintf("%d ambiguous", ambiguousSt))) + } if undefinedSt > 0 { parts = append(parts, yellow(fmt.Sprintf("%d undefined", undefinedSc))) steps = append(steps, yellow(fmt.Sprintf("%d undefined", undefinedSt))) diff --git a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_cucumber.go b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_cucumber.go index 8adbfcba..31380c97 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_cucumber.go +++ b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_cucumber.go @@ -12,6 +12,7 @@ package formatters */ import ( + "encoding/base64" "encoding/json" "fmt" "io" @@ -100,7 +101,8 @@ func (f *Cuke) buildCukeElements(pickles []*messages.Pickle) (res []cukeElement) cukeStep.Result.Duration = &d if stepResult.Status == undefined || stepResult.Status == pending || - stepResult.Status == skipped { + stepResult.Status == skipped || + stepResult.Status == ambiguous { cukeStep.Result.Duration = nil } @@ -139,14 +141,21 @@ type cukeMatch struct { Location string `json:"location"` } +type cukeEmbedding struct { + Name string `json:"name"` + MimeType string `json:"mime_type"` + Data string `json:"data"` +} + type cukeStep struct { - Keyword string `json:"keyword"` - Name string `json:"name"` - Line int `json:"line"` - Docstring *cukeDocstring `json:"doc_string,omitempty"` - Match cukeMatch `json:"match"` - Result cukeResult `json:"result"` - DataTable []*cukeDataTableRow `json:"rows,omitempty"` + Keyword string `json:"keyword"` + Name string `json:"name"` + Line int `json:"line"` + Docstring *cukeDocstring `json:"doc_string,omitempty"` + Match cukeMatch `json:"match"` + Result cukeResult `json:"result"` + DataTable []*cukeDataTableRow `json:"rows,omitempty"` + Embeddings []cukeEmbedding `json:"embeddings,omitempty"` } type cukeDataTableRow struct { @@ -252,10 +261,6 @@ func (f *Cuke) buildCukeStep(pickle *messages.Pickle, stepResult models.PickleSt step := feature.FindStep(pickleStep.AstNodeIds[0]) line := step.Location.Line - if len(pickle.AstNodeIds) == 2 { - _, row := feature.FindExample(pickle.AstNodeIds[1]) - line = row.Location.Line - } cukeStep.Name = pickleStep.Text cukeStep.Line = int(line) @@ -294,10 +299,25 @@ func (f *Cuke) buildCukeStep(pickle *messages.Pickle, stepResult models.PickleSt cukeStep.Result.Error = stepResult.Err.Error() } - if stepResult.Status == undefined || stepResult.Status == pending { + if stepResult.Status == undefined || stepResult.Status == pending || stepResult.Status == ambiguous { cukeStep.Match.Location = fmt.Sprintf("%s:%d", pickle.Uri, step.Location.Line) } + if stepResult.Attachments != nil { + attachments := []cukeEmbedding{} + + for _, a := range stepResult.Attachments { + attachments = append(attachments, cukeEmbedding{ + Name: a.Name, + Data: base64.StdEncoding.EncodeToString(a.Data), + MimeType: a.MimeType, + }) + } + + if len(attachments) > 0 { + cukeStep.Embeddings = attachments + } + } return cukeStep } diff --git a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_events.go b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_events.go index e264db57..c5ffcb50 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_events.go +++ b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_events.go @@ -153,6 +153,31 @@ func (f *Events) step(pickle *messages.Pickle, pickleStep *messages.PickleStep) if pickleStepResult.Err != nil { errMsg = pickleStepResult.Err.Error() } + + if pickleStepResult.Attachments != nil { + for _, attachment := range pickleStepResult.Attachments { + + f.event(&struct { + Event string `json:"event"` + Location string `json:"location"` + Timestamp int64 `json:"timestamp"` + ContentEncoding string `json:"contentEncoding"` + FileName string `json:"fileName"` + MimeType string `json:"mimeType"` + Body string `json:"body"` + }{ + "Attachment", + fmt.Sprintf("%s:%d", pickle.Uri, step.Location.Line), + utils.TimeNowFunc().UnixNano() / nanoSec, + messages.AttachmentContentEncoding_BASE64.String(), + attachment.Name, + attachment.MimeType, + string(attachment.Data), + }) + + } + } + f.event(&struct { Event string `json:"event"` Location string `json:"location"` @@ -173,7 +198,7 @@ func (f *Events) step(pickle *messages.Pickle, pickleStep *messages.PickleStep) pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pickle.Id) for _, stepResult := range pickleStepResults { switch stepResult.Status { - case passed, failed, undefined, pending: + case passed, failed, undefined, pending, ambiguous: status = stepResult.Status.String() } } @@ -293,6 +318,16 @@ func (f *Events) Pending(pickle *messages.Pickle, step *messages.PickleStep, mat f.step(pickle, step) } +// Ambiguous captures ambiguous step. +func (f *Events) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) { + f.Base.Ambiguous(pickle, step, match, err) + + f.Lock.Lock() + defer f.Lock.Unlock() + + f.step(pickle, step) +} + func (f *Events) scenarioLocation(pickle *messages.Pickle) string { feature := f.Storage.MustGetFeature(pickle.Uri) scenario := feature.FindScenario(pickle.AstNodeIds[0]) diff --git a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_junit.go b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_junit.go index bc6ed270..d7b25170 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_junit.go +++ b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_junit.go @@ -117,6 +117,12 @@ func (f *JUnit) buildJUNITPackageSuite() JunitPackageSuite { tc.Failure = &junitFailure{ Message: fmt.Sprintf("Step %s: %s", pickleStep.Text, stepResult.Err), } + case ambiguous: + tc.Status = ambiguous.String() + tc.Error = append(tc.Error, &junitError{ + Type: "ambiguous", + Message: fmt.Sprintf("Step %s", pickleStep.Text), + }) case skipped: tc.Error = append(tc.Error, &junitError{ Type: "skipped", diff --git a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_multi.go b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_multi.go index e23e6ade..001c9980 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_multi.go +++ b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_multi.go @@ -97,6 +97,13 @@ func (r repeater) Pending(pickle *messages.Pickle, step *messages.PickleStep, de } } +// Ambiguous triggers Ambiguous for all added formatters. +func (r repeater) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition, err error) { + for _, f := range r { + f.Ambiguous(pickle, step, definition, err) + } +} + // Summary triggers Summary for all added formatters. func (r repeater) Summary() { for _, f := range r { diff --git a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_pretty.go b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_pretty.go index e7b9e325..91dbc0cb 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_pretty.go +++ b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_pretty.go @@ -114,6 +114,16 @@ func (f *Pretty) Failed(pickle *messages.Pickle, step *messages.PickleStep, matc f.printStep(pickle, step) } +// Failed captures failed step. +func (f *Pretty) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) { + f.Base.Ambiguous(pickle, step, match, err) + + f.Lock.Lock() + defer f.Lock.Unlock() + + f.printStep(pickle, step) +} + // Pending captures pending step. func (f *Pretty) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) { f.Base.Pending(pickle, step, match) @@ -269,6 +279,9 @@ func (f *Pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in case result.Status == failed: errorMsg = result.Err.Error() clr = result.Status.Color() + case result.Status == ambiguous: + errorMsg = result.Err.Error() + clr = result.Status.Color() case result.Status == undefined || result.Status == pending: clr = result.Status.Color() case result.Status == skipped && clr == nil: diff --git a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_progress.go b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_progress.go index 23086963..9722ef7a 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_progress.go +++ b/backend/vendor/github.com/cucumber/godog/internal/formatters/fmt_progress.go @@ -98,6 +98,8 @@ func (f *Progress) step(pickleStepID string) { fmt.Fprint(f.out, red("F")) case undefined: fmt.Fprint(f.out, yellow("U")) + case ambiguous: + fmt.Fprint(f.out, yellow("A")) case pending: fmt.Fprint(f.out, yellow("P")) } @@ -149,6 +151,16 @@ func (f *Progress) Failed(pickle *messages.Pickle, step *messages.PickleStep, ma f.step(step.Id) } +// Ambiguous steps. +func (f *Progress) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) { + f.Base.Ambiguous(pickle, step, match, err) + + f.Lock.Lock() + defer f.Lock.Unlock() + + f.step(step.Id) +} + // Pending captures pending step. func (f *Progress) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) { f.Base.Pending(pickle, step, match) diff --git a/backend/vendor/github.com/cucumber/godog/internal/models/results.go b/backend/vendor/github.com/cucumber/godog/internal/models/results.go index 461a5b8a..9c7f98d7 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/models/results.go +++ b/backend/vendor/github.com/cucumber/godog/internal/models/results.go @@ -18,6 +18,13 @@ type PickleResult struct { StartedAt time.Time } +// PickleAttachment ... +type PickleAttachment struct { + Name string + MimeType string + Data []byte +} + // PickleStepResult ... type PickleStepResult struct { Status StepResultStatus @@ -28,11 +35,27 @@ type PickleStepResult struct { PickleStepID string Def *StepDefinition + + Attachments []PickleAttachment } // NewStepResult ... -func NewStepResult(pickleID, pickleStepID string, match *StepDefinition) PickleStepResult { - return PickleStepResult{FinishedAt: utils.TimeNowFunc(), PickleID: pickleID, PickleStepID: pickleStepID, Def: match} +func NewStepResult( + status StepResultStatus, + pickleID, pickleStepID string, + match *StepDefinition, + attachments []PickleAttachment, + err error, +) PickleStepResult { + return PickleStepResult{ + Status: status, + FinishedAt: utils.TimeNowFunc(), + Err: err, + PickleID: pickleID, + PickleStepID: pickleStepID, + Def: match, + Attachments: attachments, + } } // StepResultStatus ... @@ -49,6 +72,8 @@ const ( Undefined // Pending ... Pending + // Ambiguous ... + Ambiguous ) // Color ... @@ -78,6 +103,8 @@ func (st StepResultStatus) String() string { return "undefined" case Pending: return "pending" + case Ambiguous: + return "ambiguous" default: return "unknown" } diff --git a/backend/vendor/github.com/cucumber/godog/internal/models/stepdef.go b/backend/vendor/github.com/cucumber/godog/internal/models/stepdef.go index 497ffc7c..90ffef54 100644 --- a/backend/vendor/github.com/cucumber/godog/internal/models/stepdef.go +++ b/backend/vendor/github.com/cucumber/godog/internal/models/stepdef.go @@ -16,9 +16,9 @@ var typeOfBytes = reflect.TypeOf([]byte(nil)) // matchable errors var ( - ErrUnmatchedStepArgumentNumber = errors.New("func received more arguments than expected") + ErrUnmatchedStepArgumentNumber = errors.New("func expected more arguments than given") ErrCannotConvert = errors.New("cannot convert argument") - ErrUnsupportedArgumentType = errors.New("unsupported argument type") + ErrUnsupportedParameterType = errors.New("func has unsupported parameter type") ) // StepDefinition ... @@ -36,6 +36,9 @@ type StepDefinition struct { var typeOfContext = reflect.TypeOf((*context.Context)(nil)).Elem() // Run a step with the matched arguments using reflect +// Returns one of ... +// (context, error) +// (context, godog.Steps) func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{}) { var values []reflect.Value @@ -161,7 +164,8 @@ func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{} return ctx, fmt.Errorf(`%w %d: "%v" of type "%T" to *messages.PickleTable`, ErrCannotConvert, i, arg, arg) default: - return ctx, fmt.Errorf("%w: the argument %d type %T is not supported %s", ErrUnsupportedArgumentType, i, arg, param.Elem().String()) + // the error here is that the declared function has an unsupported param type - really this ought to be trapped at registration ti,e + return ctx, fmt.Errorf("%w: the data type of parameter %d type *%s is not supported", ErrUnsupportedParameterType, i, param.Elem().String()) } case reflect.Slice: switch param { @@ -172,10 +176,13 @@ func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{} } values = append(values, reflect.ValueOf([]byte(s))) default: - return ctx, fmt.Errorf("%w: the slice argument %d type %s is not supported", ErrUnsupportedArgumentType, i, param.Kind()) + // the problem is the function decl is not using a support slice type as the param + return ctx, fmt.Errorf("%w: the slice parameter %d type []%s is not supported", ErrUnsupportedParameterType, i, param.Elem().Kind()) } + case reflect.Struct: + return ctx, fmt.Errorf("%w: the struct parameter %d type %s is not supported", ErrUnsupportedParameterType, i, param.String()) default: - return ctx, fmt.Errorf("%w: the argument %d type %s is not supported", ErrUnsupportedArgumentType, i, param.Kind()) + return ctx, fmt.Errorf("%w: the parameter %d type %s is not supported", ErrUnsupportedParameterType, i, param.Kind()) } } @@ -184,17 +191,43 @@ func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{} return ctx, nil } + // Note that the step fn return types were validated at Initialise in test_context.go stepWithKeyword() + + // single return value may be one of ... + // error + // context.Context + // godog.Steps + result0 := res[0].Interface() if len(res) == 1 { - r := res[0].Interface() - if ctx, ok := r.(context.Context); ok { + // if the single return value is a context then just return it + if ctx, ok := result0.(context.Context); ok { return ctx, nil } - return ctx, res[0].Interface() + // return type is presumably one of nil, "error" or "Steps" so place it into second return position + return ctx, result0 + } + + // multi-value value return must be + // (context, error) and the context value must not be nil + if ctx, ok := result0.(context.Context); ok { + return ctx, res[1].Interface() + } + + result1 := res[1].Interface() + errMsg := "" + if result1 != nil { + errMsg = fmt.Sprintf(", step def also returned an error: %v", result1) + } + + text := sd.StepDefinition.Expr.String() + + if result0 == nil { + panic(fmt.Sprintf("step definition '%v' with return type (context.Context, error) must not return for the context.Context value%s", text, errMsg)) } - return res[0].Interface().(context.Context), res[1].Interface() + panic(fmt.Errorf("step definition '%v' has return type (context.Context, error), but found %v rather than a context.Context value%s", text, result0, errMsg)) } func (sd *StepDefinition) shouldBeString(idx int) (string, error) { diff --git a/backend/vendor/github.com/cucumber/godog/run.go b/backend/vendor/github.com/cucumber/godog/run.go index 09fdee07..405aaff9 100644 --- a/backend/vendor/github.com/cucumber/godog/run.go +++ b/backend/vendor/github.com/cucumber/godog/run.go @@ -361,6 +361,10 @@ func (ts TestSuite) RetrieveFeatures() ([]*models.Feature, error) { } } + if ts.Options.FS == nil { + ts.Options.FS = storage.FS{} + } + if len(opt.Paths) == 0 { inf, err := func() (fs.FileInfo, error) { file, err := opt.FS.Open("features") diff --git a/backend/vendor/github.com/cucumber/godog/suite.go b/backend/vendor/github.com/cucumber/godog/suite.go index 16bfd15e..9a387299 100644 --- a/backend/vendor/github.com/cucumber/godog/suite.go +++ b/backend/vendor/github.com/cucumber/godog/suite.go @@ -21,6 +21,9 @@ var ( contextInterface = reflect.TypeOf((*context.Context)(nil)).Elem() ) +// more than one regex matched the step text +var ErrAmbiguous = fmt.Errorf("ambiguous step definition") + // ErrUndefined is returned in case if step definition was not found var ErrUndefined = fmt.Errorf("step is undefined") @@ -45,6 +48,8 @@ const ( StepUndefined = models.Undefined // StepPending indicates step with pending implementation. StepPending = models.Pending + // StepAmbiguous indicates step text matches more than one step def + StepAmbiguous = models.Ambiguous ) type suite struct { @@ -68,32 +73,81 @@ type suite struct { afterScenarioHandlers []AfterScenarioHook } -func (s *suite) matchStep(step *messages.PickleStep) *models.StepDefinition { - def := s.matchStepTextAndType(step.Text, step.Type) +type Attachment struct { + Body []byte + FileName string + MediaType string +} + +type attachmentKey struct{} + +func Attach(ctx context.Context, attachments ...Attachment) context.Context { + existing := Attachments(ctx) + updated := append(existing, attachments...) + return context.WithValue(ctx, attachmentKey{}, updated) +} + +func Attachments(ctx context.Context) []Attachment { + v := ctx.Value(attachmentKey{}) + + if v == nil { + return []Attachment{} + } + return v.([]Attachment) +} + +func clearAttach(ctx context.Context) context.Context { + return context.WithValue(ctx, attachmentKey{}, nil) +} + +func pickleAttachments(ctx context.Context) []models.PickleAttachment { + + pickledAttachments := []models.PickleAttachment{} + attachments := Attachments(ctx) + + for _, a := range attachments { + pickledAttachments = append(pickledAttachments, models.PickleAttachment{ + Name: a.FileName, + Data: a.Body, + MimeType: a.MediaType, + }) + } + + return pickledAttachments +} + +func (s *suite) matchStep(step *messages.PickleStep) (*models.StepDefinition, error) { + def, err := s.matchStepTextAndType(step.Text, step.Type) + if err != nil { + return nil, err + } + if def != nil && step.Argument != nil { def.Args = append(def.Args, step.Argument) } - return def + return def, nil } func (s *suite) runStep(ctx context.Context, pickle *Scenario, step *Step, scenarioErr error, isFirst, isLast bool) (rctx context.Context, err error) { - var ( - match *models.StepDefinition - sr = models.NewStepResult(pickle.Id, step.Id, match) - ) + var match *models.StepDefinition rctx = ctx - sr.Status = StepUndefined // user multistep definitions may panic defer func() { if e := recover(); e != nil { - if err != nil { + pe, isErr := e.(error) + switch { + case isErr && errors.Is(pe, errStopNow): + // FailNow or SkipNow called on dogTestingT, so clear the error to let the normal + // below getTestingT(ctx).isFailed() call handle the reasons. + err = nil + case err != nil: err = &traceError{ msg: fmt.Sprintf("%s: %v", err.Error(), e), stack: callStack(), } - } else { + default: err = &traceError{ msg: fmt.Sprintf("%v", e), stack: callStack(), @@ -101,51 +155,66 @@ func (s *suite) runStep(ctx context.Context, pickle *Scenario, step *Step, scena } } - earlyReturn := scenarioErr != nil || err == ErrUndefined + earlyReturn := scenarioErr != nil || errors.Is(err, ErrUndefined) + + // Check for any calls to Fail on dogT + if err == nil { + err = getTestingT(ctx).isFailed() + } + + status := StepUndefined switch { + case errors.Is(err, ErrAmbiguous): + status = StepAmbiguous case errors.Is(err, ErrPending): - sr.Status = StepPending - case errors.Is(err, ErrSkip) || (err == nil && scenarioErr != nil): - sr.Status = StepSkipped + status = StepPending + case errors.Is(err, ErrSkip), err == nil && scenarioErr != nil: + status = StepSkipped case errors.Is(err, ErrUndefined): - sr.Status = StepUndefined + status = StepUndefined case err != nil: - sr.Status = StepFailed + status = StepFailed case err == nil && scenarioErr == nil: - sr.Status = StepPassed + status = StepPassed } // Run after step handlers. - rctx, err = s.runAfterStepHooks(ctx, step, sr.Status, err) - - shouldFail := s.shouldFail(err) + rctx, err = s.runAfterStepHooks(ctx, step, status, err) // Trigger after scenario on failing or last step to attach possible hook error to step. - if !s.shouldFail(scenarioErr) && (isLast || shouldFail) { + if !s.shouldFail(scenarioErr) && (isLast || s.shouldFail(err)) { rctx, err = s.runAfterScenarioHooks(rctx, pickle, err) } + // extract any accumulated attachments and clear them + pickledAttachments := pickleAttachments(rctx) + rctx = clearAttach(rctx) + if earlyReturn { return } - switch err { - case nil: - sr.Status = models.Passed + switch { + case err == nil: + sr := models.NewStepResult(models.Passed, pickle.Id, step.Id, match, pickledAttachments, nil) s.storage.MustInsertPickleStepResult(sr) - s.fmt.Passed(pickle, step, match.GetInternalStepDefinition()) - case ErrPending: - sr.Status = models.Pending + case errors.Is(err, ErrPending): + sr := models.NewStepResult(models.Pending, pickle.Id, step.Id, match, pickledAttachments, nil) s.storage.MustInsertPickleStepResult(sr) - s.fmt.Pending(pickle, step, match.GetInternalStepDefinition()) + case errors.Is(err, ErrSkip): + sr := models.NewStepResult(models.Skipped, pickle.Id, step.Id, match, pickledAttachments, nil) + s.storage.MustInsertPickleStepResult(sr) + s.fmt.Skipped(pickle, step, match.GetInternalStepDefinition()) + case errors.Is(err, ErrAmbiguous): + sr := models.NewStepResult(models.Ambiguous, pickle.Id, step.Id, match, pickledAttachments, err) + s.storage.MustInsertPickleStepResult(sr) + s.fmt.Ambiguous(pickle, step, match.GetInternalStepDefinition(), err) default: - sr.Status = models.Failed - sr.Err = err + sr := models.NewStepResult(models.Failed, pickle.Id, step.Id, match, pickledAttachments, err) s.storage.MustInsertPickleStepResult(sr) - s.fmt.Failed(pickle, step, match.GetInternalStepDefinition(), err) } }() @@ -158,19 +227,25 @@ func (s *suite) runStep(ctx context.Context, pickle *Scenario, step *Step, scena // run before step handlers ctx, err = s.runBeforeStepHooks(ctx, step, err) - match = s.matchStep(step) + var matchError error + match, matchError = s.matchStep(step) + s.storage.MustInsertStepDefintionMatch(step.AstNodeIds[0], match) - sr.Def = match s.fmt.Defined(pickle, step, match.GetInternalStepDefinition()) if err != nil { - sr = models.NewStepResult(pickle.Id, step.Id, match) - sr.Status = models.Failed - s.storage.MustInsertPickleStepResult(sr) + pickledAttachments := pickleAttachments(ctx) + ctx = clearAttach(ctx) + sr := models.NewStepResult(models.Failed, pickle.Id, step.Id, match, pickledAttachments, nil) + s.storage.MustInsertPickleStepResult(sr) return ctx, err } + if matchError != nil { + return ctx, matchError + } + if ctx, undef, err := s.maybeUndefined(ctx, step.Text, step.Argument, step.Type); err != nil { return ctx, err } else if len(undef) > 0 { @@ -186,11 +261,12 @@ func (s *suite) runStep(ctx context.Context, pickle *Scenario, step *Step, scena Nested: match.Nested, Undefined: undef, } - sr.Def = match } - sr = models.NewStepResult(pickle.Id, step.Id, match) - sr.Status = models.Undefined + pickledAttachments := pickleAttachments(ctx) + ctx = clearAttach(ctx) + + sr := models.NewStepResult(models.Undefined, pickle.Id, step.Id, match, pickledAttachments, nil) s.storage.MustInsertPickleStepResult(sr) s.fmt.Undefined(pickle, step, match.GetInternalStepDefinition()) @@ -198,8 +274,10 @@ func (s *suite) runStep(ctx context.Context, pickle *Scenario, step *Step, scena } if scenarioErr != nil { - sr = models.NewStepResult(pickle.Id, step.Id, match) - sr.Status = models.Skipped + pickledAttachments := pickleAttachments(ctx) + ctx = clearAttach(ctx) + + sr := models.NewStepResult(models.Skipped, pickle.Id, step.Id, match, pickledAttachments, nil) s.storage.MustInsertPickleStepResult(sr) s.fmt.Skipped(pickle, step, match.GetInternalStepDefinition()) @@ -324,12 +402,16 @@ func (s *suite) runAfterScenarioHooks(ctx context.Context, pickle *messages.Pick } func (s *suite) maybeUndefined(ctx context.Context, text string, arg interface{}, stepType messages.PickleStepType) (context.Context, []string, error) { - step := s.matchStepTextAndType(text, stepType) + var undefined []string + step, err := s.matchStepTextAndType(text, stepType) + if err != nil { + return ctx, undefined, err + } + if nil == step { return ctx, []string{text}, nil } - var undefined []string if !step.Nested { return ctx, undefined, nil } @@ -372,10 +454,13 @@ func (s *suite) maybeSubSteps(ctx context.Context, result interface{}) (context. return ctx, fmt.Errorf("unexpected error, should have been godog.Steps: %T - %+v", result, result) } - var err error - for _, text := range steps { - if def := s.matchStepTextAndType(text, messages.PickleStepType_UNKNOWN); def == nil { + def, err := s.matchStepTextAndType(text, messages.PickleStepType_UNKNOWN) + if err != nil { + return ctx, err + } + + if def == nil { return ctx, ErrUndefined } else { ctx, err = s.runSubStep(ctx, text, def) @@ -419,7 +504,10 @@ func (s *suite) runSubStep(ctx context.Context, text string, def *models.StepDef return ctx, nil } -func (s *suite) matchStepTextAndType(text string, stepType messages.PickleStepType) *models.StepDefinition { +func (s *suite) matchStepTextAndType(text string, stepType messages.PickleStepType) (*models.StepDefinition, error) { + var first *models.StepDefinition + matchingExpressions := make([]string, 0) + for _, h := range s.steps { if m := h.Expr.FindStringSubmatch(text); len(m) > 0 { if !keywordMatches(h.Keyword, stepType) { @@ -430,9 +518,11 @@ func (s *suite) matchStepTextAndType(text string, stepType messages.PickleStepTy args = append(args, m) } + matchingExpressions = append(matchingExpressions, h.Expr.String()) + // since we need to assign arguments // better to copy the step definition - return &models.StepDefinition{ + match := &models.StepDefinition{ StepDefinition: formatters.StepDefinition{ Expr: h.Expr, Handler: h.Handler, @@ -442,9 +532,21 @@ func (s *suite) matchStepTextAndType(text string, stepType messages.PickleStepTy HandlerValue: h.HandlerValue, Nested: h.Nested, } + + if first == nil { + first = match + } + } + } + + if s.strict { + if len(matchingExpressions) > 1 { + errs := "\n " + strings.Join(matchingExpressions, "\n ") + return nil, fmt.Errorf("%w, step text: %s\n matches:%s", ErrAmbiguous, text, errs) } } - return nil + + return first, nil } func keywordMatches(k formatters.Keyword, stepType messages.PickleStepType) bool { @@ -481,11 +583,11 @@ func (s *suite) runSteps(ctx context.Context, pickle *Scenario, steps []*Step) ( } func (s *suite) shouldFail(err error) bool { - if err == nil || err == ErrSkip { + if err == nil || errors.Is(err, ErrSkip) { return false } - if err == ErrUndefined || err == ErrPending { + if errors.Is(err, ErrUndefined) || errors.Is(err, ErrPending) { return s.strict } @@ -518,10 +620,15 @@ func (s *suite) runPickle(pickle *messages.Pickle) (err error) { s.fmt.Pickle(pickle) + dt := &testingT{ + name: pickle.Name, + } + ctx = setContextTestingT(ctx, dt) // scenario if s.testingT != nil { // Running scenario as a subtest. s.testingT.Run(pickle.Name, func(t *testing.T) { + dt.t = t ctx, err = s.runSteps(ctx, pickle, pickle.Steps) if s.shouldFail(err) { t.Errorf("%+v", err) diff --git a/backend/vendor/github.com/cucumber/godog/test_context.go b/backend/vendor/github.com/cucumber/godog/test_context.go index b1006415..8156c6d7 100644 --- a/backend/vendor/github.com/cucumber/godog/test_context.go +++ b/backend/vendor/github.com/cucumber/godog/test_context.go @@ -281,6 +281,7 @@ func (ctx ScenarioContext) Then(expr, stepFunc interface{}) { func (ctx ScenarioContext) stepWithKeyword(expr interface{}, stepFunc interface{}, keyword formatters.Keyword) { var regex *regexp.Regexp + // Validate the first input param is regex compatible switch t := expr.(type) { case *regexp.Regexp: regex = t @@ -289,45 +290,59 @@ func (ctx ScenarioContext) stepWithKeyword(expr interface{}, stepFunc interface{ case []byte: regex = regexp.MustCompile(string(t)) default: - panic(fmt.Sprintf("expecting expr to be a *regexp.Regexp or a string, got type: %T", expr)) + panic(fmt.Sprintf("expecting expr to be a *regexp.Regexp or a string or []byte, got type: %T", expr)) } - v := reflect.ValueOf(stepFunc) - typ := v.Type() - if typ.Kind() != reflect.Func { + // Validate that the handler is a function. + handlerType := reflect.TypeOf(stepFunc) + if handlerType.Kind() != reflect.Func { panic(fmt.Sprintf("expected handler to be func, but got: %T", stepFunc)) } - if typ.NumOut() > 2 { - panic(fmt.Sprintf("expected handler to return either zero, one or two values, but it has: %d", typ.NumOut())) + // FIXME = Validate the handler function param types here so + // that any errors are discovered early. + // StepDefinition.Run defines the supported types but fails at run time not registration time + + // Validate the function's return types. + helpPrefix := "expected handler to return one of error or context.Context or godog.Steps or (context.Context, error)" + isNested := false + + numOut := handlerType.NumOut() + switch numOut { + case 0: + // No return values. + case 1: + // One return value: should be error, Steps, or context.Context. + outType := handlerType.Out(0) + if outType == reflect.TypeOf(Steps{}) { + isNested = true + } else { + if outType != errorInterface && outType != contextInterface { + panic(fmt.Sprintf("%s, but got: %v", helpPrefix, outType)) + } + } + case 2: + // Two return values: should be (context.Context, error). + if handlerType.Out(0) != contextInterface || handlerType.Out(1) != errorInterface { + panic(fmt.Sprintf("%s, but got: %v, %v", helpPrefix, handlerType.Out(0), handlerType.Out(1))) + } + default: + // More than two return values. + panic(fmt.Sprintf("expected handler to return either zero, one or two values, but it has: %d", numOut)) } + // Register the handler def := &models.StepDefinition{ StepDefinition: formatters.StepDefinition{ Handler: stepFunc, Expr: regex, Keyword: keyword, }, - HandlerValue: v, - } - - if typ.NumOut() == 1 { - typ = typ.Out(0) - switch typ.Kind() { - case reflect.Interface: - if !typ.Implements(errorInterface) && !typ.Implements(contextInterface) { - panic(fmt.Sprintf("expected handler to return an error or context.Context, but got: %s", typ.Kind())) - } - case reflect.Slice: - if typ.Elem().Kind() != reflect.String { - panic(fmt.Sprintf("expected handler to return []string for multistep, but got: []%s", typ.Elem().Kind())) - } - def.Nested = true - default: - panic(fmt.Sprintf("expected handler to return an error or []string, but got: %s", typ.Kind())) - } + HandlerValue: reflect.ValueOf(stepFunc), + Nested: isNested, } + // stash the step ctx.suite.steps = append(ctx.suite.steps, def) } diff --git a/backend/vendor/github.com/cucumber/godog/testingt.go b/backend/vendor/github.com/cucumber/godog/testingt.go new file mode 100644 index 00000000..25981b89 --- /dev/null +++ b/backend/vendor/github.com/cucumber/godog/testingt.go @@ -0,0 +1,206 @@ +package godog + +import ( + "context" + "fmt" + "strings" + "testing" +) + +// T returns a TestingT compatible interface from the current test context. It will return nil if +// called outside the context of a test. This can be used with (for example) testify's assert and +// require packages. +func T(ctx context.Context) TestingT { + return getTestingT(ctx) +} + +// TestingT is a subset of the public methods implemented by go's testing.T. It allows assertion +// libraries to be used with godog, provided they depend only on this subset of methods. +type TestingT interface { + // Name returns the name of the current pickle under test + Name() string + // Log will log to the current testing.T log if set, otherwise it will log to stdout + Log(args ...interface{}) + // Logf will log a formatted string to the current testing.T log if set, otherwise it will log + // to stdout + Logf(format string, args ...interface{}) + // Error fails the current test and logs the provided arguments. Equivalent to calling Log then + // Fail. + Error(args ...interface{}) + // Errorf fails the current test and logs the formatted message. Equivalent to calling Logf then + // Fail. + Errorf(format string, args ...interface{}) + // Fail marks the current test as failed, but does not halt execution of the step. + Fail() + // FailNow marks the current test as failed and halts execution of the step. + FailNow() + // Fatal logs the provided arguments, marks the test as failed and halts execution of the step. + Fatal(args ...interface{}) + // Fatal logs the formatted message, marks the test as failed and halts execution of the step. + Fatalf(format string, args ...interface{}) + // Skip logs the provided arguments and marks the test as skipped but does not halt execution + // of the step. + Skip(args ...interface{}) + // Skipf logs the formatted message and marks the test as skipped but does not halt execution + // of the step. + Skipf(format string, args ...interface{}) + // SkipNow marks the current test as skipped and halts execution of the step. + SkipNow() + // Skipped returns true if the test has been marked as skipped. + Skipped() bool +} + +// Logf will log test output. If called in the context of a test and testing.T has been registered, +// this will log using the step's testing.T, else it will simply log to stdout. +func Logf(ctx context.Context, format string, args ...interface{}) { + if t := getTestingT(ctx); t != nil { + t.Logf(format, args...) + return + } + fmt.Printf(format+"\n", args...) +} + +// Log will log test output. If called in the context of a test and testing.T has been registered, +// this will log using the step's testing.T, else it will simply log to stdout. +func Log(ctx context.Context, args ...interface{}) { + if t := getTestingT(ctx); t != nil { + t.Log(args...) + return + } + fmt.Println(args...) +} + +// LoggedMessages returns an array of any logged messages that have been recorded during the test +// through calls to godog.Log / godog.Logf or via operations against godog.T(ctx) +func LoggedMessages(ctx context.Context) []string { + if t := getTestingT(ctx); t != nil { + return t.logMessages + } + return nil +} + +// errStopNow should be returned inside a panic within the test to immediately halt execution of that +// test +var errStopNow = fmt.Errorf("FailNow or SkipNow called") + +type testingT struct { + name string + t *testing.T + failed bool + skipped bool + failMessages []string + logMessages []string +} + +// check interface against our testingT and the upstream testing.B/F/T: +var ( + _ TestingT = &testingT{} + _ TestingT = (*testing.T)(nil) +) + +func (dt *testingT) Name() string { + if dt.t != nil { + return dt.t.Name() + } + return dt.name +} + +func (dt *testingT) Log(args ...interface{}) { + dt.logMessages = append(dt.logMessages, fmt.Sprint(args...)) + if dt.t != nil { + dt.t.Log(args...) + return + } + fmt.Println(args...) +} + +func (dt *testingT) Logf(format string, args ...interface{}) { + dt.logMessages = append(dt.logMessages, fmt.Sprintf(format, args...)) + if dt.t != nil { + dt.t.Logf(format, args...) + return + } + fmt.Printf(format+"\n", args...) +} + +func (dt *testingT) Error(args ...interface{}) { + dt.Log(args...) + dt.failMessages = append(dt.failMessages, fmt.Sprintln(args...)) + dt.Fail() +} + +func (dt *testingT) Errorf(format string, args ...interface{}) { + dt.Logf(format, args...) + dt.failMessages = append(dt.failMessages, fmt.Sprintf(format, args...)) + dt.Fail() +} + +func (dt *testingT) Fail() { + dt.failed = true +} + +func (dt *testingT) FailNow() { + dt.Fail() + panic(errStopNow) +} + +func (dt *testingT) Fatal(args ...interface{}) { + dt.Log(args...) + dt.FailNow() +} + +func (dt *testingT) Fatalf(format string, args ...interface{}) { + dt.Logf(format, args...) + dt.FailNow() +} + +func (dt *testingT) Skip(args ...interface{}) { + dt.Log(args...) + dt.skipped = true +} + +func (dt *testingT) Skipf(format string, args ...interface{}) { + dt.Logf(format, args...) + dt.skipped = true +} + +func (dt *testingT) SkipNow() { + dt.skipped = true + panic(errStopNow) +} + +func (dt *testingT) Skipped() bool { + return dt.skipped +} + +// isFailed will return an error representing the calls to Fail made during this test +func (dt *testingT) isFailed() error { + if dt.skipped { + return ErrSkip + } + if !dt.failed { + return nil + } + switch len(dt.failMessages) { + case 0: + return fmt.Errorf("fail called on TestingT") + case 1: + return fmt.Errorf(dt.failMessages[0]) + default: + return fmt.Errorf("checks failed:\n* %s", strings.Join(dt.failMessages, "\n* ")) + } +} + +type testingTCtxVal struct{} + +func setContextTestingT(ctx context.Context, dt *testingT) context.Context { + return context.WithValue(ctx, testingTCtxVal{}, dt) +} + +func getTestingT(ctx context.Context) *testingT { + dt, ok := ctx.Value(testingTCtxVal{}).(*testingT) + if !ok { + return nil + } + return dt +} diff --git a/backend/vendor/github.com/gofrs/uuid/README.md b/backend/vendor/github.com/gofrs/uuid/README.md index f5db14f0..4f73bec8 100644 --- a/backend/vendor/github.com/gofrs/uuid/README.md +++ b/backend/vendor/github.com/gofrs/uuid/README.md @@ -17,7 +17,7 @@ This package supports the following UUID versions: * Version 5, based on SHA-1 hashing of a named value (RFC-4122) This package also supports experimental Universally Unique Identifier implementations based on a -[draft RFC](https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03) that updates RFC-4122 +[draft RFC](https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html) that updates RFC-4122 * Version 6, a k-sortable id based on timestamp, and field-compatible with v1 (draft-peabody-dispatch-new-uuid-format, RFC-4122) * Version 7, a k-sortable id based on timestamp (draft-peabody-dispatch-new-uuid-format, RFC-4122) @@ -114,4 +114,4 @@ func main() { * [RFC-4122](https://tools.ietf.org/html/rfc4122) * [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01) -* [New UUID Formats RFC Draft (Peabody) Rev 03](https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03) +* [New UUID Formats RFC Draft (Peabody) Rev 04](https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html#) diff --git a/backend/vendor/github.com/gofrs/uuid/codec.go b/backend/vendor/github.com/gofrs/uuid/codec.go index e3014c68..66502641 100644 --- a/backend/vendor/github.com/gofrs/uuid/codec.go +++ b/backend/vendor/github.com/gofrs/uuid/codec.go @@ -22,8 +22,7 @@ package uuid import ( - "bytes" - "encoding/hex" + "errors" "fmt" ) @@ -45,11 +44,77 @@ func FromBytesOrNil(input []byte) UUID { return uuid } +var errInvalidFormat = errors.New("uuid: invalid UUID format") + +func fromHexChar(c byte) byte { + switch { + case '0' <= c && c <= '9': + return c - '0' + case 'a' <= c && c <= 'f': + return c - 'a' + 10 + case 'A' <= c && c <= 'F': + return c - 'A' + 10 + } + return 255 +} + +// Parse parses the UUID stored in the string text. Parsing and supported +// formats are the same as UnmarshalText. +func (u *UUID) Parse(s string) error { + switch len(s) { + case 32: // hash + case 36: // canonical + case 34, 38: + if s[0] != '{' || s[len(s)-1] != '}' { + return fmt.Errorf("uuid: incorrect UUID format in string %q", s) + } + s = s[1 : len(s)-1] + case 41, 45: + if s[:9] != "urn:uuid:" { + return fmt.Errorf("uuid: incorrect UUID format in string %q", s[:9]) + } + s = s[9:] + default: + return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(s), s) + } + // canonical + if len(s) == 36 { + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return fmt.Errorf("uuid: incorrect UUID format in string %q", s) + } + for i, x := range [16]byte{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34, + } { + v1 := fromHexChar(s[x]) + v2 := fromHexChar(s[x+1]) + if v1|v2 == 255 { + return errInvalidFormat + } + u[i] = (v1 << 4) | v2 + } + return nil + } + // hash like + for i := 0; i < 32; i += 2 { + v1 := fromHexChar(s[i]) + v2 := fromHexChar(s[i+1]) + if v1|v2 == 255 { + return errInvalidFormat + } + u[i/2] = (v1 << 4) | v2 + } + return nil +} + // FromString returns a UUID parsed from the input string. // Input is expected in a form accepted by UnmarshalText. -func FromString(input string) (UUID, error) { - u := UUID{} - err := u.UnmarshalText([]byte(input)) +func FromString(text string) (UUID, error) { + var u UUID + err := u.Parse(text) return u, err } @@ -66,133 +131,90 @@ func FromStringOrNil(input string) UUID { // MarshalText implements the encoding.TextMarshaler interface. // The encoding is the same as returned by the String() method. func (u UUID) MarshalText() ([]byte, error) { - return []byte(u.String()), nil + var buf [36]byte + encodeCanonical(buf[:], u) + return buf[:], nil } // UnmarshalText implements the encoding.TextUnmarshaler interface. // Following formats are supported: // -// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", -// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", -// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" -// "6ba7b8109dad11d180b400c04fd430c8" -// "{6ba7b8109dad11d180b400c04fd430c8}", -// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8" +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", +// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", +// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" +// "6ba7b8109dad11d180b400c04fd430c8" +// "{6ba7b8109dad11d180b400c04fd430c8}", +// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8" // // ABNF for supported UUID text representation follows: // -// URN := 'urn' -// UUID-NID := 'uuid' -// -// hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | -// 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | -// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' +// URN := 'urn' +// UUID-NID := 'uuid' // -// hexoct := hexdig hexdig -// 2hexoct := hexoct hexoct -// 4hexoct := 2hexoct 2hexoct -// 6hexoct := 4hexoct 2hexoct -// 12hexoct := 6hexoct 6hexoct +// hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | +// 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | +// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' // -// hashlike := 12hexoct -// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct +// hexoct := hexdig hexdig +// 2hexoct := hexoct hexoct +// 4hexoct := 2hexoct 2hexoct +// 6hexoct := 4hexoct 2hexoct +// 12hexoct := 6hexoct 6hexoct // -// plain := canonical | hashlike -// uuid := canonical | hashlike | braced | urn +// hashlike := 12hexoct +// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct // -// braced := '{' plain '}' | '{' hashlike '}' -// urn := URN ':' UUID-NID ':' plain +// plain := canonical | hashlike +// uuid := canonical | hashlike | braced | urn // -func (u *UUID) UnmarshalText(text []byte) error { - switch len(text) { - case 32: - return u.decodeHashLike(text) +// braced := '{' plain '}' | '{' hashlike '}' +// urn := URN ':' UUID-NID ':' plain +func (u *UUID) UnmarshalText(b []byte) error { + switch len(b) { + case 32: // hash + case 36: // canonical case 34, 38: - return u.decodeBraced(text) - case 36: - return u.decodeCanonical(text) + if b[0] != '{' || b[len(b)-1] != '}' { + return fmt.Errorf("uuid: incorrect UUID format in string %q", b) + } + b = b[1 : len(b)-1] case 41, 45: - return u.decodeURN(text) + if string(b[:9]) != "urn:uuid:" { + return fmt.Errorf("uuid: incorrect UUID format in string %q", b[:9]) + } + b = b[9:] default: - return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(text), text) - } -} - -// decodeCanonical decodes UUID strings that are formatted as defined in RFC-4122 (section 3): -// "6ba7b810-9dad-11d1-80b4-00c04fd430c8". -func (u *UUID) decodeCanonical(t []byte) error { - if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' { - return fmt.Errorf("uuid: incorrect UUID format in string %q", t) + return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(b), b) } - - src := t - dst := u[:] - - for i, byteGroup := range byteGroups { - if i > 0 { - src = src[1:] // skip dash + if len(b) == 36 { + if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { + return fmt.Errorf("uuid: incorrect UUID format in string %q", b) } - _, err := hex.Decode(dst[:byteGroup/2], src[:byteGroup]) - if err != nil { - return err + for i, x := range [16]byte{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34, + } { + v1 := fromHexChar(b[x]) + v2 := fromHexChar(b[x+1]) + if v1|v2 == 255 { + return errInvalidFormat + } + u[i] = (v1 << 4) | v2 } - src = src[byteGroup:] - dst = dst[byteGroup/2:] - } - - return nil -} - -// decodeHashLike decodes UUID strings that are using the following format: -// "6ba7b8109dad11d180b400c04fd430c8". -func (u *UUID) decodeHashLike(t []byte) error { - src := t[:] - dst := u[:] - - _, err := hex.Decode(dst, src) - return err -} - -// decodeBraced decodes UUID strings that are using the following formats: -// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" -// "{6ba7b8109dad11d180b400c04fd430c8}". -func (u *UUID) decodeBraced(t []byte) error { - l := len(t) - - if t[0] != '{' || t[l-1] != '}' { - return fmt.Errorf("uuid: incorrect UUID format in string %q", t) + return nil } - - return u.decodePlain(t[1 : l-1]) -} - -// decodeURN decodes UUID strings that are using the following formats: -// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" -// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8". -func (u *UUID) decodeURN(t []byte) error { - total := len(t) - - urnUUIDPrefix := t[:9] - - if !bytes.Equal(urnUUIDPrefix, urnPrefix) { - return fmt.Errorf("uuid: incorrect UUID format in string %q", t) - } - - return u.decodePlain(t[9:total]) -} - -// decodePlain decodes UUID strings that are using the following formats: -// "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format -// "6ba7b8109dad11d180b400c04fd430c8". -func (u *UUID) decodePlain(t []byte) error { - switch len(t) { - case 32: - return u.decodeHashLike(t) - case 36: - return u.decodeCanonical(t) - default: - return fmt.Errorf("uuid: incorrect UUID length %d in string %q", len(t), t) + for i := 0; i < 32; i += 2 { + v1 := fromHexChar(b[i]) + v2 := fromHexChar(b[i+1]) + if v1|v2 == 255 { + return errInvalidFormat + } + u[i/2] = (v1 << 4) | v2 } + return nil } // MarshalBinary implements the encoding.BinaryMarshaler interface. diff --git a/backend/vendor/github.com/gofrs/uuid/fuzz.go b/backend/vendor/github.com/gofrs/uuid/fuzz.go index afaefbc8..ccf8d4ca 100644 --- a/backend/vendor/github.com/gofrs/uuid/fuzz.go +++ b/backend/vendor/github.com/gofrs/uuid/fuzz.go @@ -19,6 +19,7 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +//go:build gofuzz // +build gofuzz package uuid @@ -27,15 +28,15 @@ package uuid // // To run: // -// $ go get github.com/dvyukov/go-fuzz/... -// $ cd $GOPATH/src/github.com/gofrs/uuid -// $ go-fuzz-build github.com/gofrs/uuid -// $ go-fuzz -bin=uuid-fuzz.zip -workdir=./testdata +// $ go get github.com/dvyukov/go-fuzz/... +// $ cd $GOPATH/src/github.com/gofrs/uuid +// $ go-fuzz-build github.com/gofrs/uuid +// $ go-fuzz -bin=uuid-fuzz.zip -workdir=./testdata // // If you make significant changes to FromString / UnmarshalText and add // new cases to fromStringTests (in codec_test.go), please run // -// $ go test -seed_fuzz_corpus +// $ go test -seed_fuzz_corpus // // to seed the corpus with the new interesting inputs, then run the fuzzer. func Fuzz(data []byte) int { diff --git a/backend/vendor/github.com/gofrs/uuid/generator.go b/backend/vendor/github.com/gofrs/uuid/generator.go index 4550bc6b..44be9e15 100644 --- a/backend/vendor/github.com/gofrs/uuid/generator.go +++ b/backend/vendor/github.com/gofrs/uuid/generator.go @@ -38,7 +38,8 @@ import ( // UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). const epochStart = 122192928000000000 -type epochFunc func() time.Time +// EpochFunc is the function type used to provide the current time. +type EpochFunc func() time.Time // HWAddrFunc is the function type used to provide hardware (MAC) addresses. type HWAddrFunc func() (net.HardwareAddr, error) @@ -80,9 +81,9 @@ func NewV6() (UUID, error) { } // NewV7 returns a k-sortable UUID based on the current millisecond precision -// UNIX epoch and 74 bits of pseudorandom data. +// UNIX epoch and 74 bits of pseudorandom data. It supports single-node batch generation (multiple UUIDs in the same timestamp) with a Monotonic Random counter. // -// This is implemented based on revision 03 of the Peabody UUID draft, and may +// This is implemented based on revision 04 of the Peabody UUID draft, and may // be subject to change pending further revisions. Until the final specification // revision is finished, changes required to implement updates to the spec will // not be considered a breaking change. They will happen as a minor version @@ -119,13 +120,16 @@ type Gen struct { rand io.Reader - epochFunc epochFunc + epochFunc EpochFunc hwAddrFunc HWAddrFunc lastTime uint64 clockSequence uint16 hardwareAddr [6]byte } +// GenOption is a function type that can be used to configure a Gen generator. +type GenOption func(*Gen) + // interface check -- build will fail if *Gen doesn't satisfy Generator var _ Generator = (*Gen)(nil) @@ -147,18 +151,82 @@ func NewGen() *Gen { // MAC address being used, you'll need to create a new generator using this // function. func NewGenWithHWAF(hwaf HWAddrFunc) *Gen { - return &Gen{ + return NewGenWithOptions(WithHWAddrFunc(hwaf)) +} + +// NewGenWithOptions returns a new instance of Gen with the options provided. +// Most people should use NewGen() or NewGenWithHWAF() instead. +// +// To customize the generator, you can pass in one or more GenOption functions. +// For example: +// +// gen := NewGenWithOptions( +// WithHWAddrFunc(myHWAddrFunc), +// WithEpochFunc(myEpochFunc), +// WithRandomReader(myRandomReader), +// ) +// +// NewGenWithOptions(WithHWAddrFunc(myHWAddrFunc)) is equivalent to calling +// NewGenWithHWAF(myHWAddrFunc) +// NewGenWithOptions() is equivalent to calling NewGen() +func NewGenWithOptions(opts ...GenOption) *Gen { + gen := &Gen{ epochFunc: time.Now, - hwAddrFunc: hwaf, + hwAddrFunc: defaultHWAddrFunc, rand: rand.Reader, } + + for _, opt := range opts { + opt(gen) + } + + return gen +} + +// WithHWAddrFunc is a GenOption that allows you to provide your own HWAddrFunc +// function. +// When this option is nil, the defaultHWAddrFunc is used. +func WithHWAddrFunc(hwaf HWAddrFunc) GenOption { + return func(gen *Gen) { + if hwaf == nil { + hwaf = defaultHWAddrFunc + } + + gen.hwAddrFunc = hwaf + } +} + +// WithEpochFunc is a GenOption that allows you to provide your own EpochFunc +// function. +// When this option is nil, time.Now is used. +func WithEpochFunc(epochf EpochFunc) GenOption { + return func(gen *Gen) { + if epochf == nil { + epochf = time.Now + } + + gen.epochFunc = epochf + } +} + +// WithRandomReader is a GenOption that allows you to provide your own random +// reader. +// When this option is nil, the default rand.Reader is used. +func WithRandomReader(reader io.Reader) GenOption { + return func(gen *Gen) { + if reader == nil { + reader = rand.Reader + } + + gen.rand = reader + } } // NewV1 returns a UUID based on the current timestamp and MAC address. func (g *Gen) NewV1() (UUID, error) { u := UUID{} - timeNow, clockSeq, err := g.getClockSequence() + timeNow, clockSeq, err := g.getClockSequence(false) if err != nil { return Nil, err } @@ -225,7 +293,7 @@ func (g *Gen) NewV6() (UUID, error) { return Nil, err } - timeNow, clockSeq, err := g.getClockSequence() + timeNow, clockSeq, err := g.getClockSequence(false) if err != nil { return Nil, err } @@ -241,8 +309,12 @@ func (g *Gen) NewV6() (UUID, error) { return u, nil } -// getClockSequence returns the epoch and clock sequence for V1 and V6 UUIDs. -func (g *Gen) getClockSequence() (uint64, uint16, error) { +// getClockSequence returns the epoch and clock sequence for V1,V6 and V7 UUIDs. +// +// When useUnixTSMs is false, it uses the Coordinated Universal Time (UTC) as a count of 100- +// +// nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of Gregorian reform to the Christian calendar). +func (g *Gen) getClockSequence(useUnixTSMs bool) (uint64, uint16, error) { var err error g.clockSequenceOnce.Do(func() { buf := make([]byte, 2) @@ -258,7 +330,12 @@ func (g *Gen) getClockSequence() (uint64, uint16, error) { g.storageMutex.Lock() defer g.storageMutex.Unlock() - timeNow := g.getEpoch() + var timeNow uint64 + if useUnixTSMs { + timeNow = uint64(g.epochFunc().UnixMilli()) + } else { + timeNow = g.getEpoch() + } // Clock didn't change since last UUID generation. // Should increase clock sequence. if timeNow <= g.lastTime { @@ -272,28 +349,51 @@ func (g *Gen) getClockSequence() (uint64, uint16, error) { // NewV7 returns a k-sortable UUID based on the current millisecond precision // UNIX epoch and 74 bits of pseudorandom data. // -// This is implemented based on revision 03 of the Peabody UUID draft, and may +// This is implemented based on revision 04 of the Peabody UUID draft, and may // be subject to change pending further revisions. Until the final specification // revision is finished, changes required to implement updates to the spec will // not be considered a breaking change. They will happen as a minor version // releases until the spec is final. func (g *Gen) NewV7() (UUID, error) { var u UUID - - if _, err := io.ReadFull(g.rand, u[6:]); err != nil { + /* https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html#name-uuid-version-7 + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | ver | rand_a | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |var| rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ + + ms, clockSeq, err := g.getClockSequence(true) + if err != nil { return Nil, err } - - tn := g.epochFunc() - ms := uint64(tn.Unix())*1e3 + uint64(tn.Nanosecond())/1e6 - u[0] = byte(ms >> 40) + //UUIDv7 features a 48 bit timestamp. First 32bit (4bytes) represents seconds since 1970, followed by 2 bytes for the ms granularity. + u[0] = byte(ms >> 40) //1-6 bytes: big-endian unsigned number of Unix epoch timestamp u[1] = byte(ms >> 32) u[2] = byte(ms >> 24) u[3] = byte(ms >> 16) u[4] = byte(ms >> 8) u[5] = byte(ms) + //support batching by using a monotonic pseudo-random sequence + //The 6th byte contains the version and partially rand_a data. + //We will lose the most significant bites from the clockSeq (with SetVersion), but it is ok, we need the least significant that contains the counter to ensure the monotonic property + binary.BigEndian.PutUint16(u[6:8], clockSeq) // set rand_a with clock seq which is random and monotonic + + //override first 4bits of u[6]. u.SetVersion(V7) + + //set rand_b 64bits of pseudo-random bits (first 2 will be overridden) + if _, err = io.ReadFull(g.rand, u[8:16]); err != nil { + return Nil, err + } + //override first 2 bits of byte[8] for the variant u.SetVariant(VariantRFC4122) return u, nil diff --git a/backend/vendor/github.com/gofrs/uuid/sql.go b/backend/vendor/github.com/gofrs/uuid/sql.go index 6f254a4f..01d5d884 100644 --- a/backend/vendor/github.com/gofrs/uuid/sql.go +++ b/backend/vendor/github.com/gofrs/uuid/sql.go @@ -22,12 +22,14 @@ package uuid import ( - "bytes" + "database/sql" "database/sql/driver" - "encoding/json" "fmt" ) +var _ driver.Valuer = UUID{} +var _ sql.Scanner = (*UUID)(nil) + // Value implements the driver.Valuer interface. func (u UUID) Value() (driver.Value, error) { return u.String(), nil @@ -49,7 +51,9 @@ func (u *UUID) Scan(src interface{}) error { return u.UnmarshalText(src) case string: - return u.UnmarshalText([]byte(src)) + uu, err := FromString(src) + *u = uu + return err } return fmt.Errorf("uuid: cannot convert %T to UUID", src) @@ -83,27 +87,30 @@ func (u *NullUUID) Scan(src interface{}) error { return u.UUID.Scan(src) } +var nullJSON = []byte("null") + // MarshalJSON marshals the NullUUID as null or the nested UUID func (u NullUUID) MarshalJSON() ([]byte, error) { if !u.Valid { - return json.Marshal(nil) + return nullJSON, nil } - - return json.Marshal(u.UUID) + var buf [38]byte + buf[0] = '"' + encodeCanonical(buf[1:37], u.UUID) + buf[37] = '"' + return buf[:], nil } // UnmarshalJSON unmarshals a NullUUID func (u *NullUUID) UnmarshalJSON(b []byte) error { - if bytes.Equal(b, []byte("null")) { + if string(b) == "null" { u.UUID, u.Valid = Nil, false return nil } - - if err := json.Unmarshal(b, &u.UUID); err != nil { - return err + if n := len(b); n >= 2 && b[0] == '"' { + b = b[1 : n-1] } - - u.Valid = true - - return nil + err := u.UUID.UnmarshalText(b) + u.Valid = (err == nil) + return err } diff --git a/backend/vendor/github.com/gofrs/uuid/uuid.go b/backend/vendor/github.com/gofrs/uuid/uuid.go index e747e541..5320fb53 100644 --- a/backend/vendor/github.com/gofrs/uuid/uuid.go +++ b/backend/vendor/github.com/gofrs/uuid/uuid.go @@ -44,8 +44,6 @@ import ( "encoding/binary" "encoding/hex" "fmt" - "io" - "strings" "time" ) @@ -133,12 +131,6 @@ func TimestampFromV6(u UUID) (Timestamp, error) { return Timestamp(uint64(low) + (uint64(mid) << 12) + (uint64(hi) << 28)), nil } -// String parse helpers. -var ( - urnPrefix = []byte("urn:uuid:") - byteGroups = []int{8, 4, 4, 4, 12} -) - // Nil is the nil UUID, as specified in RFC-4122, that has all 128 bits set to // zero. var Nil = UUID{} @@ -182,22 +174,33 @@ func (u UUID) Bytes() []byte { return u[:] } +// encodeCanonical encodes the canonical RFC-4122 form of UUID u into the +// first 36 bytes dst. +func encodeCanonical(dst []byte, u UUID) { + const hextable = "0123456789abcdef" + dst[8] = '-' + dst[13] = '-' + dst[18] = '-' + dst[23] = '-' + for i, x := range [16]byte{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34, + } { + c := u[i] + dst[x] = hextable[c>>4] + dst[x+1] = hextable[c&0x0f] + } +} + // String returns a canonical RFC-4122 string representation of the UUID: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. func (u UUID) String() string { - buf := make([]byte, 36) - - hex.Encode(buf[0:8], u[0:4]) - buf[8] = '-' - hex.Encode(buf[9:13], u[4:6]) - buf[13] = '-' - hex.Encode(buf[14:18], u[6:8]) - buf[18] = '-' - hex.Encode(buf[19:23], u[8:10]) - buf[23] = '-' - hex.Encode(buf[24:], u[10:]) - - return string(buf) + var buf [36]byte + encodeCanonical(buf[:], u) + return string(buf[:]) } // Format implements fmt.Formatter for UUID values. @@ -210,52 +213,41 @@ func (u UUID) String() string { // All other verbs not handled directly by the fmt package (like '%p') are unsupported and will return // "%!verb(uuid.UUID=value)" as recommended by the fmt package. func (u UUID) Format(f fmt.State, c rune) { + if c == 'v' && f.Flag('#') { + fmt.Fprintf(f, "%#v", [Size]byte(u)) + return + } switch c { case 'x', 'X': - s := hex.EncodeToString(u.Bytes()) + b := make([]byte, 32) + hex.Encode(b, u[:]) if c == 'X' { - s = strings.Map(toCapitalHexDigits, s) - } - _, _ = io.WriteString(f, s) - case 'v': - var s string - if f.Flag('#') { - s = fmt.Sprintf("%#v", [Size]byte(u)) - } else { - s = u.String() + toUpperHex(b) } - _, _ = io.WriteString(f, s) - case 's', 'S': - s := u.String() + _, _ = f.Write(b) + case 'v', 's', 'S': + b, _ := u.MarshalText() if c == 'S' { - s = strings.Map(toCapitalHexDigits, s) + toUpperHex(b) } - _, _ = io.WriteString(f, s) + _, _ = f.Write(b) case 'q': - _, _ = io.WriteString(f, `"`+u.String()+`"`) + b := make([]byte, 38) + b[0] = '"' + encodeCanonical(b[1:], u) + b[37] = '"' + _, _ = f.Write(b) default: // invalid/unsupported format verb fmt.Fprintf(f, "%%!%c(uuid.UUID=%s)", c, u.String()) } } -func toCapitalHexDigits(ch rune) rune { - // convert a-f hex digits to A-F - switch ch { - case 'a': - return 'A' - case 'b': - return 'B' - case 'c': - return 'C' - case 'd': - return 'D' - case 'e': - return 'E' - case 'f': - return 'F' - default: - return ch +func toUpperHex(b []byte) { + for i, c := range b { + if 'a' <= c && c <= 'f' { + b[i] = c - ('a' - 'A') + } } } @@ -283,7 +275,8 @@ func (u *UUID) SetVariant(v byte) { // Must is a helper that wraps a call to a function returning (UUID, error) // and panics if the error is non-nil. It is intended for use in variable // initializations such as -// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000")) +// +// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000")) func Must(u UUID, err error) UUID { if err != nil { panic(err) diff --git a/backend/vendor/github.com/hashicorp/go-memdb/CODEOWNERS b/backend/vendor/github.com/hashicorp/go-memdb/CODEOWNERS new file mode 100644 index 00000000..2cad39ac --- /dev/null +++ b/backend/vendor/github.com/hashicorp/go-memdb/CODEOWNERS @@ -0,0 +1,13 @@ +# Each line is a file pattern followed by one or more owners. +# More on CODEOWNERS files: https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners + +# Default owner +* @hashicorp/team-ip-compliance @hashicorp/raft-force + +# Add override rules below. Each line is a file/folder pattern followed by one or more owners. +# Being an owner means those groups or individuals will be added as reviewers to PRs affecting +# those areas of the code. +# Examples: +# /docs/ @docs-team +# *.js @js-team +# *.go @go-team diff --git a/backend/vendor/github.com/hashicorp/go-memdb/LICENSE b/backend/vendor/github.com/hashicorp/go-memdb/LICENSE index e87a115e..f4f97ee5 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/LICENSE +++ b/backend/vendor/github.com/hashicorp/go-memdb/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2015 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions diff --git a/backend/vendor/github.com/hashicorp/go-memdb/changes.go b/backend/vendor/github.com/hashicorp/go-memdb/changes.go index 35089f5c..4761e925 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/changes.go +++ b/backend/vendor/github.com/hashicorp/go-memdb/changes.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package memdb // Changes describes a set of mutations to memDB tables performed during a diff --git a/backend/vendor/github.com/hashicorp/go-memdb/filter.go b/backend/vendor/github.com/hashicorp/go-memdb/filter.go index 0071ab31..2e135216 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/filter.go +++ b/backend/vendor/github.com/hashicorp/go-memdb/filter.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package memdb // FilterFunc is a function that takes the results of an iterator and returns diff --git a/backend/vendor/github.com/hashicorp/go-memdb/index.go b/backend/vendor/github.com/hashicorp/go-memdb/index.go index 172a0e86..588e1c89 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/index.go +++ b/backend/vendor/github.com/hashicorp/go-memdb/index.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package memdb import ( diff --git a/backend/vendor/github.com/hashicorp/go-memdb/memdb.go b/backend/vendor/github.com/hashicorp/go-memdb/memdb.go index 0508d0aa..13cc6a8c 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/memdb.go +++ b/backend/vendor/github.com/hashicorp/go-memdb/memdb.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + // Package memdb provides an in-memory database that supports transactions // and MVCC. package memdb diff --git a/backend/vendor/github.com/hashicorp/go-memdb/schema.go b/backend/vendor/github.com/hashicorp/go-memdb/schema.go index e6a9b526..2d66f996 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/schema.go +++ b/backend/vendor/github.com/hashicorp/go-memdb/schema.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package memdb import "fmt" diff --git a/backend/vendor/github.com/hashicorp/go-memdb/txn.go b/backend/vendor/github.com/hashicorp/go-memdb/txn.go index 951c2a1d..f83f4fab 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/txn.go +++ b/backend/vendor/github.com/hashicorp/go-memdb/txn.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package memdb import ( diff --git a/backend/vendor/github.com/hashicorp/go-memdb/watch.go b/backend/vendor/github.com/hashicorp/go-memdb/watch.go index 13a4da14..4d9cc7ee 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/watch.go +++ b/backend/vendor/github.com/hashicorp/go-memdb/watch.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package memdb import ( diff --git a/backend/vendor/github.com/hashicorp/go-memdb/watch_few.go b/backend/vendor/github.com/hashicorp/go-memdb/watch_few.go index b211eeea..ccdbff0f 100644 --- a/backend/vendor/github.com/hashicorp/go-memdb/watch_few.go +++ b/backend/vendor/github.com/hashicorp/go-memdb/watch_few.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package memdb //go:generate sh -c "go run watch-gen/main.go >watch_few.go" diff --git a/backend/vendor/github.com/hashicorp/golang-lru/LICENSE b/backend/vendor/github.com/hashicorp/golang-lru/LICENSE index be2cc4df..0e5d580e 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/LICENSE +++ b/backend/vendor/github.com/hashicorp/golang-lru/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2014 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions diff --git a/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go index a86c8539..9233583c 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go +++ b/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go @@ -25,7 +25,7 @@ type entry struct { // NewLRU constructs an LRU of the given size func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { if size <= 0 { - return nil, errors.New("Must provide a positive size") + return nil, errors.New("must provide a positive size") } c := &LRU{ size: size, @@ -109,7 +109,7 @@ func (c *LRU) Remove(key interface{}) (present bool) { } // RemoveOldest removes the oldest item from the cache. -func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { +func (c *LRU) RemoveOldest() (key, value interface{}, ok bool) { ent := c.evictList.Back() if ent != nil { c.removeElement(ent) @@ -120,7 +120,7 @@ func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { } // GetOldest returns the oldest entry -func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { +func (c *LRU) GetOldest() (key, value interface{}, ok bool) { ent := c.evictList.Back() if ent != nil { kv := ent.Value.(*entry) diff --git a/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go index 92d70934..cb7f8caf 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go +++ b/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go @@ -1,3 +1,4 @@ +// Package simplelru provides simple LRU implementation based on build-in container/list. package simplelru // LRUCache is the interface for simple LRU cache. @@ -34,6 +35,6 @@ type LRUCache interface { // Clears all cache entries. Purge() - // Resizes cache, returning number evicted - Resize(int) int + // Resizes cache, returning number evicted + Resize(int) int } diff --git a/backend/vendor/github.com/spf13/pflag/.editorconfig b/backend/vendor/github.com/spf13/pflag/.editorconfig new file mode 100644 index 00000000..4492e9f9 --- /dev/null +++ b/backend/vendor/github.com/spf13/pflag/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.go] +indent_style = tab diff --git a/backend/vendor/github.com/spf13/pflag/.golangci.yaml b/backend/vendor/github.com/spf13/pflag/.golangci.yaml new file mode 100644 index 00000000..b274f248 --- /dev/null +++ b/backend/vendor/github.com/spf13/pflag/.golangci.yaml @@ -0,0 +1,4 @@ +linters: + disable-all: true + enable: + - nolintlint diff --git a/backend/vendor/github.com/spf13/pflag/flag.go b/backend/vendor/github.com/spf13/pflag/flag.go index 24a5036e..7c058de3 100644 --- a/backend/vendor/github.com/spf13/pflag/flag.go +++ b/backend/vendor/github.com/spf13/pflag/flag.go @@ -160,7 +160,7 @@ type FlagSet struct { args []string // arguments after flags argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no -- errorHandling ErrorHandling - output io.Writer // nil means stderr; use out() accessor + output io.Writer // nil means stderr; use Output() accessor interspersed bool // allow interspersed option/non-option args normalizeNameFunc func(f *FlagSet, name string) NormalizedName @@ -255,13 +255,20 @@ func (f *FlagSet) normalizeFlagName(name string) NormalizedName { return n(f, name) } -func (f *FlagSet) out() io.Writer { +// Output returns the destination for usage and error messages. os.Stderr is returned if +// output was not set or was set to nil. +func (f *FlagSet) Output() io.Writer { if f.output == nil { return os.Stderr } return f.output } +// Name returns the name of the flag set. +func (f *FlagSet) Name() string { + return f.name +} + // SetOutput sets the destination for usage and error messages. // If output is nil, os.Stderr is used. func (f *FlagSet) SetOutput(output io.Writer) { @@ -358,7 +365,7 @@ func (f *FlagSet) ShorthandLookup(name string) *Flag { } if len(name) > 1 { msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name) - fmt.Fprintf(f.out(), msg) + fmt.Fprintf(f.Output(), msg) panic(msg) } c := name[0] @@ -482,7 +489,7 @@ func (f *FlagSet) Set(name, value string) error { } if flag.Deprecated != "" { - fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) + fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) } return nil } @@ -523,7 +530,7 @@ func Set(name, value string) error { // otherwise, the default values of all defined flags in the set. func (f *FlagSet) PrintDefaults() { usages := f.FlagUsages() - fmt.Fprint(f.out(), usages) + fmt.Fprint(f.Output(), usages) } // defaultIsZeroValue returns true if the default value for this flag represents @@ -758,7 +765,7 @@ func PrintDefaults() { // defaultUsage is the default function to print a usage message. func defaultUsage(f *FlagSet) { - fmt.Fprintf(f.out(), "Usage of %s:\n", f.name) + fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name) f.PrintDefaults() } @@ -844,7 +851,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { _, alreadyThere := f.formal[normalizedFlagName] if alreadyThere { msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name) - fmt.Fprintln(f.out(), msg) + fmt.Fprintln(f.Output(), msg) panic(msg) // Happens only if flags are declared with identical names } if f.formal == nil { @@ -860,7 +867,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { } if len(flag.Shorthand) > 1 { msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand) - fmt.Fprintf(f.out(), msg) + fmt.Fprintf(f.Output(), msg) panic(msg) } if f.shorthands == nil { @@ -870,7 +877,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { used, alreadyThere := f.shorthands[c] if alreadyThere { msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name) - fmt.Fprintf(f.out(), msg) + fmt.Fprintf(f.Output(), msg) panic(msg) } f.shorthands[c] = flag @@ -909,7 +916,7 @@ func VarP(value Value, name, shorthand, usage string) { func (f *FlagSet) failf(format string, a ...interface{}) error { err := fmt.Errorf(format, a...) if f.errorHandling != ContinueOnError { - fmt.Fprintln(f.out(), err) + fmt.Fprintln(f.Output(), err) f.usage() } return err @@ -1060,7 +1067,7 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse } if flag.ShorthandDeprecated != "" { - fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) + fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) } err = fn(flag, value) diff --git a/backend/vendor/github.com/spf13/pflag/ip.go b/backend/vendor/github.com/spf13/pflag/ip.go index 3d414ba6..06b8bcb5 100644 --- a/backend/vendor/github.com/spf13/pflag/ip.go +++ b/backend/vendor/github.com/spf13/pflag/ip.go @@ -16,6 +16,9 @@ func newIPValue(val net.IP, p *net.IP) *ipValue { func (i *ipValue) String() string { return net.IP(*i).String() } func (i *ipValue) Set(s string) error { + if s == "" { + return nil + } ip := net.ParseIP(strings.TrimSpace(s)) if ip == nil { return fmt.Errorf("failed to parse IP: %q", s) diff --git a/backend/vendor/github.com/spf13/pflag/ipnet_slice.go b/backend/vendor/github.com/spf13/pflag/ipnet_slice.go new file mode 100644 index 00000000..6b541aa8 --- /dev/null +++ b/backend/vendor/github.com/spf13/pflag/ipnet_slice.go @@ -0,0 +1,147 @@ +package pflag + +import ( + "fmt" + "io" + "net" + "strings" +) + +// -- ipNetSlice Value +type ipNetSliceValue struct { + value *[]net.IPNet + changed bool +} + +func newIPNetSliceValue(val []net.IPNet, p *[]net.IPNet) *ipNetSliceValue { + ipnsv := new(ipNetSliceValue) + ipnsv.value = p + *ipnsv.value = val + return ipnsv +} + +// Set converts, and assigns, the comma-separated IPNet argument string representation as the []net.IPNet value of this flag. +// If Set is called on a flag that already has a []net.IPNet assigned, the newly converted values will be appended. +func (s *ipNetSliceValue) Set(val string) error { + + // remove all quote characters + rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "") + + // read flag arguments with CSV parser + ipNetStrSlice, err := readAsCSV(rmQuote.Replace(val)) + if err != nil && err != io.EOF { + return err + } + + // parse ip values into slice + out := make([]net.IPNet, 0, len(ipNetStrSlice)) + for _, ipNetStr := range ipNetStrSlice { + _, n, err := net.ParseCIDR(strings.TrimSpace(ipNetStr)) + if err != nil { + return fmt.Errorf("invalid string being converted to CIDR: %s", ipNetStr) + } + out = append(out, *n) + } + + if !s.changed { + *s.value = out + } else { + *s.value = append(*s.value, out...) + } + + s.changed = true + + return nil +} + +// Type returns a string that uniquely represents this flag's type. +func (s *ipNetSliceValue) Type() string { + return "ipNetSlice" +} + +// String defines a "native" format for this net.IPNet slice flag value. +func (s *ipNetSliceValue) String() string { + + ipNetStrSlice := make([]string, len(*s.value)) + for i, n := range *s.value { + ipNetStrSlice[i] = n.String() + } + + out, _ := writeAsCSV(ipNetStrSlice) + return "[" + out + "]" +} + +func ipNetSliceConv(val string) (interface{}, error) { + val = strings.Trim(val, "[]") + // Emtpy string would cause a slice with one (empty) entry + if len(val) == 0 { + return []net.IPNet{}, nil + } + ss := strings.Split(val, ",") + out := make([]net.IPNet, len(ss)) + for i, sval := range ss { + _, n, err := net.ParseCIDR(strings.TrimSpace(sval)) + if err != nil { + return nil, fmt.Errorf("invalid string being converted to CIDR: %s", sval) + } + out[i] = *n + } + return out, nil +} + +// GetIPNetSlice returns the []net.IPNet value of a flag with the given name +func (f *FlagSet) GetIPNetSlice(name string) ([]net.IPNet, error) { + val, err := f.getFlagType(name, "ipNetSlice", ipNetSliceConv) + if err != nil { + return []net.IPNet{}, err + } + return val.([]net.IPNet), nil +} + +// IPNetSliceVar defines a ipNetSlice flag with specified name, default value, and usage string. +// The argument p points to a []net.IPNet variable in which to store the value of the flag. +func (f *FlagSet) IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) { + f.VarP(newIPNetSliceValue(value, p), name, "", usage) +} + +// IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) { + f.VarP(newIPNetSliceValue(value, p), name, shorthand, usage) +} + +// IPNetSliceVar defines a []net.IPNet flag with specified name, default value, and usage string. +// The argument p points to a []net.IPNet variable in which to store the value of the flag. +func IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) { + CommandLine.VarP(newIPNetSliceValue(value, p), name, "", usage) +} + +// IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash. +func IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) { + CommandLine.VarP(newIPNetSliceValue(value, p), name, shorthand, usage) +} + +// IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string. +// The return value is the address of a []net.IPNet variable that stores the value of that flag. +func (f *FlagSet) IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet { + p := []net.IPNet{} + f.IPNetSliceVarP(&p, name, "", value, usage) + return &p +} + +// IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet { + p := []net.IPNet{} + f.IPNetSliceVarP(&p, name, shorthand, value, usage) + return &p +} + +// IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string. +// The return value is the address of a []net.IP variable that stores the value of the flag. +func IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet { + return CommandLine.IPNetSliceP(name, "", value, usage) +} + +// IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash. +func IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet { + return CommandLine.IPNetSliceP(name, shorthand, value, usage) +} diff --git a/backend/vendor/github.com/spf13/pflag/string_array.go b/backend/vendor/github.com/spf13/pflag/string_array.go index 4894af81..d1ff0a96 100644 --- a/backend/vendor/github.com/spf13/pflag/string_array.go +++ b/backend/vendor/github.com/spf13/pflag/string_array.go @@ -31,11 +31,7 @@ func (s *stringArrayValue) Append(val string) error { func (s *stringArrayValue) Replace(val []string) error { out := make([]string, len(val)) for i, d := range val { - var err error out[i] = d - if err != nil { - return err - } } *s.value = out return nil diff --git a/backend/vendor/github.com/valyala/fasthttp/coarseTime.go b/backend/vendor/github.com/valyala/fasthttp/coarsetime.go similarity index 100% rename from backend/vendor/github.com/valyala/fasthttp/coarseTime.go rename to backend/vendor/github.com/valyala/fasthttp/coarsetime.go diff --git a/backend/vendor/golang.org/x/sys/cpu/cpu.go b/backend/vendor/golang.org/x/sys/cpu/cpu.go index 2e73ee19..63541994 100644 --- a/backend/vendor/golang.org/x/sys/cpu/cpu.go +++ b/backend/vendor/golang.org/x/sys/cpu/cpu.go @@ -232,6 +232,17 @@ var RISCV64 struct { HasZba bool // Address generation instructions extension HasZbb bool // Basic bit-manipulation extension HasZbs bool // Single-bit instructions extension + HasZvbb bool // Vector Basic Bit-manipulation + HasZvbc bool // Vector Carryless Multiplication + HasZvkb bool // Vector Cryptography Bit-manipulation + HasZvkt bool // Vector Data-Independent Execution Latency + HasZvkg bool // Vector GCM/GMAC + HasZvkn bool // NIST Algorithm Suite (AES/SHA256/SHA512) + HasZvknc bool // NIST Algorithm Suite with carryless multiply + HasZvkng bool // NIST Algorithm Suite with GCM + HasZvks bool // ShangMi Algorithm Suite + HasZvksc bool // ShangMi Algorithm Suite with carryless multiplication + HasZvksg bool // ShangMi Algorithm Suite with GCM _ CacheLinePad } diff --git a/backend/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go b/backend/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go index cb4a0c57..ad741536 100644 --- a/backend/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go +++ b/backend/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go @@ -58,6 +58,15 @@ const ( riscv_HWPROBE_EXT_ZBA = 0x8 riscv_HWPROBE_EXT_ZBB = 0x10 riscv_HWPROBE_EXT_ZBS = 0x20 + riscv_HWPROBE_EXT_ZVBB = 0x20000 + riscv_HWPROBE_EXT_ZVBC = 0x40000 + riscv_HWPROBE_EXT_ZVKB = 0x80000 + riscv_HWPROBE_EXT_ZVKG = 0x100000 + riscv_HWPROBE_EXT_ZVKNED = 0x200000 + riscv_HWPROBE_EXT_ZVKNHB = 0x800000 + riscv_HWPROBE_EXT_ZVKSED = 0x1000000 + riscv_HWPROBE_EXT_ZVKSH = 0x2000000 + riscv_HWPROBE_EXT_ZVKT = 0x4000000 riscv_HWPROBE_KEY_CPUPERF_0 = 0x5 riscv_HWPROBE_MISALIGNED_FAST = 0x3 riscv_HWPROBE_MISALIGNED_MASK = 0x7 @@ -99,6 +108,20 @@ func doinit() { RISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA) RISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB) RISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS) + RISCV64.HasZvbb = isSet(v, riscv_HWPROBE_EXT_ZVBB) + RISCV64.HasZvbc = isSet(v, riscv_HWPROBE_EXT_ZVBC) + RISCV64.HasZvkb = isSet(v, riscv_HWPROBE_EXT_ZVKB) + RISCV64.HasZvkg = isSet(v, riscv_HWPROBE_EXT_ZVKG) + RISCV64.HasZvkt = isSet(v, riscv_HWPROBE_EXT_ZVKT) + // Cryptography shorthand extensions + RISCV64.HasZvkn = isSet(v, riscv_HWPROBE_EXT_ZVKNED) && + isSet(v, riscv_HWPROBE_EXT_ZVKNHB) && RISCV64.HasZvkb && RISCV64.HasZvkt + RISCV64.HasZvknc = RISCV64.HasZvkn && RISCV64.HasZvbc + RISCV64.HasZvkng = RISCV64.HasZvkn && RISCV64.HasZvkg + RISCV64.HasZvks = isSet(v, riscv_HWPROBE_EXT_ZVKSED) && + isSet(v, riscv_HWPROBE_EXT_ZVKSH) && RISCV64.HasZvkb && RISCV64.HasZvkt + RISCV64.HasZvksc = RISCV64.HasZvks && RISCV64.HasZvbc + RISCV64.HasZvksg = RISCV64.HasZvks && RISCV64.HasZvkg } if pairs[1].key != -1 { v := pairs[1].value & riscv_HWPROBE_MISALIGNED_MASK diff --git a/backend/vendor/golang.org/x/sys/cpu/cpu_riscv64.go b/backend/vendor/golang.org/x/sys/cpu/cpu_riscv64.go index aca3199c..0f617aef 100644 --- a/backend/vendor/golang.org/x/sys/cpu/cpu_riscv64.go +++ b/backend/vendor/golang.org/x/sys/cpu/cpu_riscv64.go @@ -16,5 +16,17 @@ func initOptions() { {Name: "zba", Feature: &RISCV64.HasZba}, {Name: "zbb", Feature: &RISCV64.HasZbb}, {Name: "zbs", Feature: &RISCV64.HasZbs}, + // RISC-V Cryptography Extensions + {Name: "zvbb", Feature: &RISCV64.HasZvbb}, + {Name: "zvbc", Feature: &RISCV64.HasZvbc}, + {Name: "zvkb", Feature: &RISCV64.HasZvkb}, + {Name: "zvkg", Feature: &RISCV64.HasZvkg}, + {Name: "zvkt", Feature: &RISCV64.HasZvkt}, + {Name: "zvkn", Feature: &RISCV64.HasZvkn}, + {Name: "zvknc", Feature: &RISCV64.HasZvknc}, + {Name: "zvkng", Feature: &RISCV64.HasZvkng}, + {Name: "zvks", Feature: &RISCV64.HasZvks}, + {Name: "zvksc", Feature: &RISCV64.HasZvksc}, + {Name: "zvksg", Feature: &RISCV64.HasZvksg}, } } diff --git a/backend/vendor/golang.org/x/sys/windows/security_windows.go b/backend/vendor/golang.org/x/sys/windows/security_windows.go index b6e1ab76..a8b0364c 100644 --- a/backend/vendor/golang.org/x/sys/windows/security_windows.go +++ b/backend/vendor/golang.org/x/sys/windows/security_windows.go @@ -1303,7 +1303,10 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE return nil, err } if absoluteSDSize > 0 { - absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0])) + absoluteSD = new(SECURITY_DESCRIPTOR) + if unsafe.Sizeof(*absoluteSD) < uintptr(absoluteSDSize) { + panic("sizeof(SECURITY_DESCRIPTOR) too small") + } } var ( dacl *ACL @@ -1312,19 +1315,55 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE group *SID ) if daclSize > 0 { - dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0])) + dacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, daclSize)))) } if saclSize > 0 { - sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0])) + sacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, saclSize)))) } if ownerSize > 0 { - owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0])) + owner = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, ownerSize)))) } if groupSize > 0 { - group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0])) + group = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, groupSize)))) } + // We call into Windows via makeAbsoluteSD, which sets up + // pointers within absoluteSD that point to other chunks of memory + // we pass into makeAbsoluteSD, and that happens outside the view of the GC. + // We therefore take some care here to then verify the pointers are as we expect + // and set them explicitly in view of the GC. See https://go.dev/issue/73199. + // TODO: consider weak pointers once Go 1.24 is appropriate. See suggestion in https://go.dev/cl/663575. err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize, dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize) + if err != nil { + // Don't return absoluteSD, which might be partially initialized. + return nil, err + } + // Before using any fields, verify absoluteSD is in the format we expect according to Windows. + // See https://learn.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors + absControl, _, err := absoluteSD.Control() + if err != nil { + panic("absoluteSD: " + err.Error()) + } + if absControl&SE_SELF_RELATIVE != 0 { + panic("absoluteSD not in absolute format") + } + if absoluteSD.dacl != dacl { + panic("dacl pointer mismatch") + } + if absoluteSD.sacl != sacl { + panic("sacl pointer mismatch") + } + if absoluteSD.owner != owner { + panic("owner pointer mismatch") + } + if absoluteSD.group != group { + panic("group pointer mismatch") + } + absoluteSD.dacl = dacl + absoluteSD.sacl = sacl + absoluteSD.owner = owner + absoluteSD.group = group + return } diff --git a/backend/vendor/golang.org/x/sys/windows/syscall_windows.go b/backend/vendor/golang.org/x/sys/windows/syscall_windows.go index 4a325438..640f6b15 100644 --- a/backend/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/backend/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -870,6 +870,7 @@ const socket_error = uintptr(^uint32(0)) //sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom //sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo //sys WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.WSASocketW +//sys WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) [failretval!=0] = ws2_32.WSADuplicateSocketW //sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname //sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname //sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs @@ -1698,8 +1699,9 @@ func NewNTUnicodeString(s string) (*NTUnicodeString, error) { // Slice returns a uint16 slice that aliases the data in the NTUnicodeString. func (s *NTUnicodeString) Slice() []uint16 { - slice := unsafe.Slice(s.Buffer, s.MaximumLength) - return slice[:s.Length] + // Note: this rounds the length down, if it happens + // to (incorrectly) be odd. Probably safer than rounding up. + return unsafe.Slice(s.Buffer, s.MaximumLength/2)[:s.Length/2] } func (s *NTUnicodeString) String() string { diff --git a/backend/vendor/golang.org/x/sys/windows/types_windows.go b/backend/vendor/golang.org/x/sys/windows/types_windows.go index ad67df2f..958bcf47 100644 --- a/backend/vendor/golang.org/x/sys/windows/types_windows.go +++ b/backend/vendor/golang.org/x/sys/windows/types_windows.go @@ -2700,6 +2700,8 @@ type CommTimeouts struct { // NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING. type NTUnicodeString struct { + // Note: Length and MaximumLength are in *bytes*, not uint16s. + // They should always be even. Length uint16 MaximumLength uint16 Buffer *uint16 @@ -3628,3 +3630,213 @@ const ( KLF_NOTELLSHELL = 0x00000080 KLF_SETFORPROCESS = 0x00000100 ) + +// Virtual Key codes +// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes +const ( + VK_LBUTTON = 0x01 + VK_RBUTTON = 0x02 + VK_CANCEL = 0x03 + VK_MBUTTON = 0x04 + VK_XBUTTON1 = 0x05 + VK_XBUTTON2 = 0x06 + VK_BACK = 0x08 + VK_TAB = 0x09 + VK_CLEAR = 0x0C + VK_RETURN = 0x0D + VK_SHIFT = 0x10 + VK_CONTROL = 0x11 + VK_MENU = 0x12 + VK_PAUSE = 0x13 + VK_CAPITAL = 0x14 + VK_KANA = 0x15 + VK_HANGEUL = 0x15 + VK_HANGUL = 0x15 + VK_IME_ON = 0x16 + VK_JUNJA = 0x17 + VK_FINAL = 0x18 + VK_HANJA = 0x19 + VK_KANJI = 0x19 + VK_IME_OFF = 0x1A + VK_ESCAPE = 0x1B + VK_CONVERT = 0x1C + VK_NONCONVERT = 0x1D + VK_ACCEPT = 0x1E + VK_MODECHANGE = 0x1F + VK_SPACE = 0x20 + VK_PRIOR = 0x21 + VK_NEXT = 0x22 + VK_END = 0x23 + VK_HOME = 0x24 + VK_LEFT = 0x25 + VK_UP = 0x26 + VK_RIGHT = 0x27 + VK_DOWN = 0x28 + VK_SELECT = 0x29 + VK_PRINT = 0x2A + VK_EXECUTE = 0x2B + VK_SNAPSHOT = 0x2C + VK_INSERT = 0x2D + VK_DELETE = 0x2E + VK_HELP = 0x2F + VK_LWIN = 0x5B + VK_RWIN = 0x5C + VK_APPS = 0x5D + VK_SLEEP = 0x5F + VK_NUMPAD0 = 0x60 + VK_NUMPAD1 = 0x61 + VK_NUMPAD2 = 0x62 + VK_NUMPAD3 = 0x63 + VK_NUMPAD4 = 0x64 + VK_NUMPAD5 = 0x65 + VK_NUMPAD6 = 0x66 + VK_NUMPAD7 = 0x67 + VK_NUMPAD8 = 0x68 + VK_NUMPAD9 = 0x69 + VK_MULTIPLY = 0x6A + VK_ADD = 0x6B + VK_SEPARATOR = 0x6C + VK_SUBTRACT = 0x6D + VK_DECIMAL = 0x6E + VK_DIVIDE = 0x6F + VK_F1 = 0x70 + VK_F2 = 0x71 + VK_F3 = 0x72 + VK_F4 = 0x73 + VK_F5 = 0x74 + VK_F6 = 0x75 + VK_F7 = 0x76 + VK_F8 = 0x77 + VK_F9 = 0x78 + VK_F10 = 0x79 + VK_F11 = 0x7A + VK_F12 = 0x7B + VK_F13 = 0x7C + VK_F14 = 0x7D + VK_F15 = 0x7E + VK_F16 = 0x7F + VK_F17 = 0x80 + VK_F18 = 0x81 + VK_F19 = 0x82 + VK_F20 = 0x83 + VK_F21 = 0x84 + VK_F22 = 0x85 + VK_F23 = 0x86 + VK_F24 = 0x87 + VK_NUMLOCK = 0x90 + VK_SCROLL = 0x91 + VK_OEM_NEC_EQUAL = 0x92 + VK_OEM_FJ_JISHO = 0x92 + VK_OEM_FJ_MASSHOU = 0x93 + VK_OEM_FJ_TOUROKU = 0x94 + VK_OEM_FJ_LOYA = 0x95 + VK_OEM_FJ_ROYA = 0x96 + VK_LSHIFT = 0xA0 + VK_RSHIFT = 0xA1 + VK_LCONTROL = 0xA2 + VK_RCONTROL = 0xA3 + VK_LMENU = 0xA4 + VK_RMENU = 0xA5 + VK_BROWSER_BACK = 0xA6 + VK_BROWSER_FORWARD = 0xA7 + VK_BROWSER_REFRESH = 0xA8 + VK_BROWSER_STOP = 0xA9 + VK_BROWSER_SEARCH = 0xAA + VK_BROWSER_FAVORITES = 0xAB + VK_BROWSER_HOME = 0xAC + VK_VOLUME_MUTE = 0xAD + VK_VOLUME_DOWN = 0xAE + VK_VOLUME_UP = 0xAF + VK_MEDIA_NEXT_TRACK = 0xB0 + VK_MEDIA_PREV_TRACK = 0xB1 + VK_MEDIA_STOP = 0xB2 + VK_MEDIA_PLAY_PAUSE = 0xB3 + VK_LAUNCH_MAIL = 0xB4 + VK_LAUNCH_MEDIA_SELECT = 0xB5 + VK_LAUNCH_APP1 = 0xB6 + VK_LAUNCH_APP2 = 0xB7 + VK_OEM_1 = 0xBA + VK_OEM_PLUS = 0xBB + VK_OEM_COMMA = 0xBC + VK_OEM_MINUS = 0xBD + VK_OEM_PERIOD = 0xBE + VK_OEM_2 = 0xBF + VK_OEM_3 = 0xC0 + VK_OEM_4 = 0xDB + VK_OEM_5 = 0xDC + VK_OEM_6 = 0xDD + VK_OEM_7 = 0xDE + VK_OEM_8 = 0xDF + VK_OEM_AX = 0xE1 + VK_OEM_102 = 0xE2 + VK_ICO_HELP = 0xE3 + VK_ICO_00 = 0xE4 + VK_PROCESSKEY = 0xE5 + VK_ICO_CLEAR = 0xE6 + VK_OEM_RESET = 0xE9 + VK_OEM_JUMP = 0xEA + VK_OEM_PA1 = 0xEB + VK_OEM_PA2 = 0xEC + VK_OEM_PA3 = 0xED + VK_OEM_WSCTRL = 0xEE + VK_OEM_CUSEL = 0xEF + VK_OEM_ATTN = 0xF0 + VK_OEM_FINISH = 0xF1 + VK_OEM_COPY = 0xF2 + VK_OEM_AUTO = 0xF3 + VK_OEM_ENLW = 0xF4 + VK_OEM_BACKTAB = 0xF5 + VK_ATTN = 0xF6 + VK_CRSEL = 0xF7 + VK_EXSEL = 0xF8 + VK_EREOF = 0xF9 + VK_PLAY = 0xFA + VK_ZOOM = 0xFB + VK_NONAME = 0xFC + VK_PA1 = 0xFD + VK_OEM_CLEAR = 0xFE +) + +// Mouse button constants. +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001 + RIGHTMOST_BUTTON_PRESSED = 0x0002 + FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004 + FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008 + FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010 +) + +// Control key state constaints. +// https://docs.microsoft.com/en-us/windows/console/key-event-record-str +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + CAPSLOCK_ON = 0x0080 + ENHANCED_KEY = 0x0100 + LEFT_ALT_PRESSED = 0x0002 + LEFT_CTRL_PRESSED = 0x0008 + NUMLOCK_ON = 0x0020 + RIGHT_ALT_PRESSED = 0x0001 + RIGHT_CTRL_PRESSED = 0x0004 + SCROLLLOCK_ON = 0x0040 + SHIFT_PRESSED = 0x0010 +) + +// Mouse event record event flags. +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + MOUSE_MOVED = 0x0001 + DOUBLE_CLICK = 0x0002 + MOUSE_WHEELED = 0x0004 + MOUSE_HWHEELED = 0x0008 +) + +// Input Record Event Types +// https://learn.microsoft.com/en-us/windows/console/input-record-str +const ( + FOCUS_EVENT = 0x0010 + KEY_EVENT = 0x0001 + MENU_EVENT = 0x0008 + MOUSE_EVENT = 0x0002 + WINDOW_BUFFER_SIZE_EVENT = 0x0004 +) diff --git a/backend/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/backend/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 01c0716c..a58bc48b 100644 --- a/backend/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/backend/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -511,6 +511,7 @@ var ( procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") procWSACleanup = modws2_32.NewProc("WSACleanup") + procWSADuplicateSocketW = modws2_32.NewProc("WSADuplicateSocketW") procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") procWSAIoctl = modws2_32.NewProc("WSAIoctl") @@ -4391,6 +4392,14 @@ func WSACleanup() (err error) { return } +func WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) { + r1, _, e1 := syscall.Syscall(procWSADuplicateSocketW.Addr(), 3, uintptr(s), uintptr(processID), uintptr(unsafe.Pointer(info))) + if r1 != 0 { + err = errnoErr(e1) + } + return +} + func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) n = int32(r0) diff --git a/backend/vendor/gorm.io/gorm/License b/backend/vendor/gorm.io/gorm/LICENSE similarity index 100% rename from backend/vendor/gorm.io/gorm/License rename to backend/vendor/gorm.io/gorm/LICENSE diff --git a/backend/vendor/modules.txt b/backend/vendor/modules.txt index 40f027ab..ca9c70ae 100644 --- a/backend/vendor/modules.txt +++ b/backend/vendor/modules.txt @@ -26,7 +26,7 @@ github.com/coreos/go-oidc/v3/oidc # github.com/cucumber/gherkin/go/v26 v26.2.0 ## explicit; go 1.19 github.com/cucumber/gherkin/go/v26 -# github.com/cucumber/godog v0.13.0 +# github.com/cucumber/godog v0.15.0 ## explicit; go 1.16 github.com/cucumber/godog github.com/cucumber/godog/colors @@ -123,7 +123,7 @@ github.com/gofiber/fiber/v2/utils # github.com/gofiber/swagger v1.1.1 ## explicit; go 1.18 github.com/gofiber/swagger -# github.com/gofrs/uuid v4.3.1+incompatible +# github.com/gofrs/uuid v4.4.0+incompatible ## explicit github.com/gofrs/uuid # github.com/golang-jwt/jwt/v4 v4.5.2 @@ -150,10 +150,10 @@ github.com/grpc-ecosystem/grpc-gateway/v2/utilities # github.com/hashicorp/go-immutable-radix v1.3.1 ## explicit github.com/hashicorp/go-immutable-radix -# github.com/hashicorp/go-memdb v1.3.4 +# github.com/hashicorp/go-memdb v1.3.5 ## explicit; go 1.13 github.com/hashicorp/go-memdb -# github.com/hashicorp/golang-lru v0.5.4 +# github.com/hashicorp/golang-lru v1.0.2 ## explicit; go 1.12 github.com/hashicorp/golang-lru/simplelru # github.com/heetch/confita v0.10.0 @@ -263,7 +263,7 @@ github.com/remyoudompheng/bigfft # github.com/rivo/uniseg v0.4.7 ## explicit; go 1.18 github.com/rivo/uniseg -# github.com/spf13/pflag v1.0.5 +# github.com/spf13/pflag v1.0.6 ## explicit; go 1.12 github.com/spf13/pflag # github.com/stretchr/testify v1.10.0 @@ -385,7 +385,7 @@ go.uber.org/zap/internal/exit go.uber.org/zap/internal/pool go.uber.org/zap/internal/stacktrace go.uber.org/zap/zapcore -# golang.org/x/crypto v0.37.0 +# golang.org/x/crypto v0.38.0 ## explicit; go 1.23.0 golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish @@ -413,16 +413,16 @@ golang.org/x/net/trace ## explicit; go 1.23.0 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.13.0 +# golang.org/x/sync v0.14.0 ## explicit; go 1.23.0 golang.org/x/sync/semaphore -# golang.org/x/sys v0.32.0 +# golang.org/x/sys v0.33.0 ## explicit; go 1.23.0 golang.org/x/sys/cpu golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/text v0.24.0 +# golang.org/x/text v0.25.0 ## explicit; go 1.23.0 golang.org/x/text/cases golang.org/x/text/internal