diff --git a/.fuzz/fuzz_test.go b/.fuzz/fuzz_test.go index 0ab4cda..38a3634 100644 --- a/.fuzz/fuzz_test.go +++ b/.fuzz/fuzz_test.go @@ -6,8 +6,8 @@ import ( "sync" "testing" - "github.com/bsm/redeo" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2" + "github.com/bsm/redeo/v2/resp" "github.com/go-redis/redis" ) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..f489792 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,37 @@ +name: Test +on: + push: + branches: + - main + pull_request: + branches: + - main +jobs: + go: + runs-on: ubuntu-latest + strategy: + matrix: + go-version: [1.18.x, 1.19.x] + services: + redis: + image: redis:alpine + ports: + - 6379:6379 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + cache: true + - run: make test + golangci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.x + cache: true + - uses: golangci/golangci-lint-action@v3 + with: + version: latest diff --git a/.gitignore b/.gitignore index 48b8bf9..6aa8b3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -vendor/ +*.makefile diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..0708a4d --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,4 @@ +linters-settings: + errcheck: + exclude-functions: + - (*github.com/bsm/redeo/v2/resp.CommandStream).Discard diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a960eb0..0000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go -services: - - redis -install: - - go get -u github.com/go-redis/redis -script: - - make default fuzz fuzzrace -go: - - 1.11.x - - 1.12.x -env: - - GO111MODULE=on diff --git a/LICENSE b/LICENSE index 73d55a5..1625b84 100644 --- a/LICENSE +++ b/LICENSE @@ -1,13 +1,201 @@ -Copyright 2017 Black Square Media Ltd + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - http://www.apache.org/licenses/LICENSE-2.0 + 1. Definitions. -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Black Square Media Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile index 25bac54..001b3d4 100644 --- a/Makefile +++ b/Makefile @@ -1,29 +1,10 @@ -default: vet test +default: test -test: - go test ./... +.minimal.makefile: + curl -fsSL -o $@ https://gitlab.com/bsm/misc/raw/master/make/go/minimal.makefile -vet: - go vet ./... - -bench: - go test ./... -run=NONE -bench=. -benchmem -benchtime=5s - -fuzz: - go test ./.fuzz - -fuzzrace: - go test -race ./.fuzz +include .minimal.makefile # go get -u github.com/davelondon/rebecca/cmd/becca - -doc: README.md client/README.md resp/README.md - -README.md: README.md.tpl $(wildcard *.go) - becca -package . - -client/README.md: client/README.md.tpl $(wildcard client/*.go) - cd client && becca -package . - -resp/README.md: resp/README.md.tpl $(wildcard resp/*.go) - cd resp && becca -package . +README.md: README.md.tpl + becca -package github.com/bsm/redeo/v2 diff --git a/README.md b/README.md index bc2da71..4e296fc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # Redeo -[![GoDoc](https://godoc.org/github.com/bsm/redeo?status.svg)](https://godoc.org/github.com/bsm/redeo) -[![Build Status](https://travis-ci.org/bsm/redeo.png?branch=master)](https://travis-ci.org/bsm/redeo) -[![Go Report Card](https://goreportcard.com/badge/github.com/bsm/redeo)](https://goreportcard.com/report/github.com/bsm/redeo) +[![Go Reference](https://pkg.go.dev/badge/github.com/bsm/redeo/v2)](https://pkg.go.dev/github.com/bsm/redeo/v2) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) The high-performance Swiss Army Knife for building redis-protocol compatible servers/services. @@ -32,7 +30,7 @@ package main import ( "net" - "github.com/bsm/redeo" + "github.com/bsm/redeo/v2" ) func main() { diff --git a/README.md.tpl b/README.md.tpl index ccc73b5..1f4fb34 100644 --- a/README.md.tpl +++ b/README.md.tpl @@ -1,8 +1,6 @@ # Redeo -[![GoDoc](https://godoc.org/github.com/bsm/redeo?status.svg)](https://godoc.org/github.com/bsm/redeo) -[![Build Status](https://travis-ci.org/bsm/redeo.png?branch=master)](https://travis-ci.org/bsm/redeo) -[![Go Report Card](https://goreportcard.com/badge/github.com/bsm/redeo)](https://goreportcard.com/report/github.com/bsm/redeo) +[![Go Reference](https://pkg.go.dev/badge/github.com/bsm/redeo/v2)](https://pkg.go.dev/github.com/bsm/redeo/v2) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) The high-performance Swiss Army Knife for building redis-protocol compatible servers/services. @@ -32,7 +30,7 @@ package main import ( "net" - "github.com/bsm/redeo" + "github.com/bsm/redeo/v2" ) func main() {{ "ExampleServer" | code }} diff --git a/client.go b/client.go index 87258c2..496b2a2 100644 --- a/client.go +++ b/client.go @@ -6,7 +6,7 @@ import ( "sync" "sync/atomic" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) var ( diff --git a/client/README.md b/client/README.md index 13067c7..efaa5ae 100644 --- a/client/README.md +++ b/client/README.md @@ -11,7 +11,7 @@ import ( "fmt" "strings" - "github.com/bsm/redeo/client" + "github.com/bsm/redeo/v2/client" ) func main() { diff --git a/client/README.md.tpl b/client/README.md.tpl index b552a8f..b8521e1 100644 --- a/client/README.md.tpl +++ b/client/README.md.tpl @@ -11,7 +11,7 @@ import ( "fmt" "strings" - "github.com/bsm/redeo/client" + "github.com/bsm/redeo/v2/client" ) func main() {{ "ExamplePool" | code }} diff --git a/client/conn.go b/client/conn.go index 863ffec..7259668 100644 --- a/client/conn.go +++ b/client/conn.go @@ -5,7 +5,7 @@ import ( "net" "time" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) // Conn wraps a single network connection and exposes diff --git a/client/example_test.go b/client/example_test.go index ff2fca4..04e9c68 100644 --- a/client/example_test.go +++ b/client/example_test.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/bsm/pool" - "github.com/bsm/redeo/client" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/client" + "github.com/bsm/redeo/v2/resp" ) func ExamplePool() { diff --git a/client/pool.go b/client/pool.go index 8ea59dc..45b4763 100644 --- a/client/pool.go +++ b/client/pool.go @@ -7,7 +7,7 @@ import ( "sync" "github.com/bsm/pool" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) // Pool is a minimalist redis client connection pool diff --git a/client_test.go b/client_test.go index 4245a5e..906bf58 100644 --- a/client_test.go +++ b/client_test.go @@ -1,15 +1,13 @@ package redeo import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" ) var _ = Describe("Client", func() { - It("should generate IDs", func() { a, b := newClient(&mockConn{}), newClient(&mockConn{}) Expect(b.ID() - 1).To(Equal(a.ID())) }) - }) diff --git a/cmd/redeo-server-example/main.go b/cmd/redeo-server-example/main.go index a5cc9f5..d794974 100644 --- a/cmd/redeo-server-example/main.go +++ b/cmd/redeo-server-example/main.go @@ -5,7 +5,7 @@ import ( "log" "net" - "github.com/bsm/redeo" + "github.com/bsm/redeo/v2" ) var flags struct { diff --git a/example_test.go b/example_test.go index 37bca3d..d3212d6 100644 --- a/example_test.go +++ b/example_test.go @@ -4,8 +4,8 @@ import ( "net" "sync" - "github.com/bsm/redeo" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2" + "github.com/bsm/redeo/v2/resp" ) func ExampleServer() { @@ -35,7 +35,9 @@ func ExampleServer() { defer lis.Close() // Start serving (blocking) - srv.Serve(lis) + if err := srv.Serve(lis); err != nil { + panic(err) + } } func ExampleClient() { diff --git a/go.mod b/go.mod index 9a67463..5a6578c 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,9 @@ -module github.com/bsm/redeo +module github.com/bsm/redeo/v2 + +go 1.18 require ( - github.com/bsm/pool v0.8.1 - github.com/golang/protobuf v1.3.2 // indirect - github.com/kr/pretty v0.1.0 // indirect - github.com/onsi/ginkgo v1.8.0 - github.com/onsi/gomega v1.5.0 - golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect - golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e // indirect - golang.org/x/text v0.3.2 // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect - gopkg.in/yaml.v2 v2.2.2 // indirect + github.com/bsm/ginkgo/v2 v2.5.0 + github.com/bsm/gomega v1.20.0 + github.com/bsm/pool v0.9.0 ) diff --git a/go.sum b/go.sum index 4c58560..ab5cd47 100644 --- a/go.sum +++ b/go.sum @@ -1,50 +1,6 @@ -github.com/bsm/pool v0.8.1 h1:WS5zo7o629vWBnTWOKOJfRCvWxwS3Yh7NDOk1TiPBeo= -github.com/bsm/pool v0.8.1/go.mod h1:20l4nKLbEi8m4F5GWdtu7CZh4DPWwalpLeuqwDYZ1vY= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e h1:TsjK5I7fXk8f2FQrgu6NS7i5Qih3knl2FL1htyguLRE= -golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +github.com/bsm/ginkgo/v2 v2.5.0 h1:aOAnND1T40wEdAtkGSkvSICWeQ8L3UASX7YVCqQx+eQ= +github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= +github.com/bsm/gomega v1.20.0 h1:JhAwLmtRzXFTx2AkALSLa8ijZafntmhSoU63Ok18Uq8= +github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk= +github.com/bsm/pool v0.9.0 h1:1OqGf+yjqYkkAUkBgGlet37N59wEdbHubd09giXBmX4= +github.com/bsm/pool v0.9.0/go.mod h1:rf2pi6Fs1MWF+5WCqJSd89zEVWB6qrXRfDsEJBjjgqM= diff --git a/info.go b/info.go index 401c1bd..bc6380b 100644 --- a/info.go +++ b/info.go @@ -11,7 +11,7 @@ import ( "sync" "time" - "github.com/bsm/redeo/info" + "github.com/bsm/redeo/v2/info" ) // CommandDescription describes supported commands @@ -91,11 +91,7 @@ func (i *ClientInfo) String() string { type ServerInfo struct { registry *info.Registry - startTime time.Time - port string - socket string - pid int - + startTime time.Time clients clientStats connections *info.IntValue commands *info.IntValue diff --git a/info/info.go b/info/info.go index f2115fc..03cfbd1 100644 --- a/info/info.go +++ b/info/info.go @@ -74,7 +74,7 @@ func (r *Registry) String() string { func (r *Registry) findSection(name string) *Section { for _, s := range r.sections { - if strings.ToLower(s.name) == strings.ToLower(name) { + if strings.EqualFold(s.name, name) { return s } } diff --git a/info/info_test.go b/info/info_test.go index 4117684..978eea4 100644 --- a/info/info_test.go +++ b/info/info_test.go @@ -3,8 +3,8 @@ package info import ( "testing" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" ) var _ = Describe("Registry", func() { diff --git a/info/values_test.go b/info/values_test.go index 11409e4..52cc7f4 100644 --- a/info/values_test.go +++ b/info/values_test.go @@ -1,8 +1,8 @@ package info import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" ) var _ = Describe("StaticString", func() { diff --git a/info_test.go b/info_test.go index 16ba70e..30f5bc9 100644 --- a/info_test.go +++ b/info_test.go @@ -3,8 +3,8 @@ package redeo import ( "time" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" ) var _ = Describe("ServerInfo", func() { diff --git a/pubsub.go b/pubsub.go index 54ff073..c022fc1 100644 --- a/pubsub.go +++ b/pubsub.go @@ -4,7 +4,7 @@ import ( "sync" "sync/atomic" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) // PubSubBroker can be used to emulate redis' diff --git a/pubsub_test.go b/pubsub_test.go index 05213c9..30230e4 100644 --- a/pubsub_test.go +++ b/pubsub_test.go @@ -1,10 +1,10 @@ package redeo import ( - "github.com/bsm/redeo/redeotest" - "github.com/bsm/redeo/resp" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" + "github.com/bsm/redeo/v2/redeotest" + "github.com/bsm/redeo/v2/resp" ) var _ = Describe("PubSubBroker", func() { diff --git a/redeo.go b/redeo.go index 07f80ad..99bb3af 100644 --- a/redeo.go +++ b/redeo.go @@ -4,7 +4,7 @@ import ( "errors" "strings" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) // UnknownCommand returns an unknown command error string @@ -130,17 +130,18 @@ func (f HandlerFunc) ServeRedeo(w resp.ResponseWriter, c *resp.Command) { f(w, c // WrapperFunc implements Handler, accepts a command and must return one of // the following types: -// nil -// error -// string -// []byte -// bool -// float32, float64 -// int, int8, int16, int32, int64 -// uint, uint8, uint16, uint32, uint64 -// resp.CustomResponse instances -// slices of any of the above typs -// maps containing keys and values of any of the above types +// +// nil +// error +// string +// []byte +// bool +// float32, float64 +// int, int8, int16, int32, int64 +// uint, uint8, uint16, uint32, uint64 +// resp.CustomResponse instances +// slices of any of the above typs +// maps containing keys and values of any of the above types type WrapperFunc func(c *resp.Command) interface{} // ServeRedeo implements Handler diff --git a/redeo_test.go b/redeo_test.go index 6573da9..843c926 100644 --- a/redeo_test.go +++ b/redeo_test.go @@ -6,10 +6,10 @@ import ( "testing" "time" - "github.com/bsm/redeo/redeotest" - "github.com/bsm/redeo/resp" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" + "github.com/bsm/redeo/v2/redeotest" + "github.com/bsm/redeo/v2/resp" ) var _ = Describe("Ping", func() { diff --git a/redeotest/example_test.go b/redeotest/example_test.go index bfe1569..edac941 100644 --- a/redeotest/example_test.go +++ b/redeotest/example_test.go @@ -3,9 +3,9 @@ package redeotest_test import ( "fmt" - "github.com/bsm/redeo" - "github.com/bsm/redeo/redeotest" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2" + "github.com/bsm/redeo/v2/redeotest" + "github.com/bsm/redeo/v2/resp" ) func ExampleResponseRecorder() { diff --git a/redeotest/redeotest.go b/redeotest/redeotest.go index 576eed1..48675a2 100644 --- a/redeotest/redeotest.go +++ b/redeotest/redeotest.go @@ -6,7 +6,7 @@ import ( "io" "strconv" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) // ErrorResponse is used to wrap error strings diff --git a/resp/README.md b/resp/README.md index 692f0d3..65c4d58 100644 --- a/resp/README.md +++ b/resp/README.md @@ -13,7 +13,7 @@ import ( "fmt" "strings" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) func main() { @@ -46,7 +46,7 @@ import ( "bytes" "fmt" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) func main() { @@ -90,7 +90,7 @@ import ( "fmt" "net" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) func main() { diff --git a/resp/README.md.tpl b/resp/README.md.tpl index aa3b4c0..3cac7e8 100644 --- a/resp/README.md.tpl +++ b/resp/README.md.tpl @@ -13,7 +13,7 @@ import ( "fmt" "strings" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) func main() {{ "ExampleRequestReader" | code }} @@ -28,7 +28,7 @@ import ( "bytes" "fmt" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) func main() {{ "ExampleResponseWriter" | code }} @@ -45,7 +45,7 @@ import ( "fmt" "net" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) func main() {{ "Example_client" | code }} diff --git a/resp/bufio.go b/resp/bufio.go index 12dfc23..852be08 100644 --- a/resp/bufio.go +++ b/resp/bufio.go @@ -223,7 +223,9 @@ func (b *bufioR) PeekLine(offset int) (bufioLn, error) { } // Although rarely, make sure '\n' is buffered. if (start + index + 1) >= b.w { - b.require(offset + index + 2) + if err := b.require(offset + index + 2); err != nil { + return nil, err + } start = b.r + offset } return bufioLn(b.buf[start : start+index+2]), nil @@ -264,12 +266,6 @@ func (b *bufioR) require(sz int) error { return err } -func (b *bufioR) skip(sz int) { - if b.Buffered() >= sz { - b.r += sz - } -} - // fill tries to read more data into the buffer func (b *bufioR) fill() error { b.compact() diff --git a/resp/example_test.go b/resp/example_test.go index a3cc884..9c18779 100644 --- a/resp/example_test.go +++ b/resp/example_test.go @@ -6,7 +6,7 @@ import ( "net" "strings" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) func Example_client() { @@ -185,8 +185,12 @@ func ExampleResponseWriter_CopyBulk() { b := new(bytes.Buffer) w := resp.NewResponseWriter(b) - w.CopyBulk(strings.NewReader("a streamer"), 8) - w.Flush() + if err := w.CopyBulk(strings.NewReader("a streamer"), 8); err != nil { + panic(err) + } + if err := w.Flush(); err != nil { + panic(err) + } fmt.Printf("%q\n", b.String()) // Output: @@ -199,8 +203,12 @@ func ExampleResponseWriter_CopyBulk_in_array() { w.AppendArrayLen(2) w.AppendBulkString("item 1") - w.CopyBulk(strings.NewReader("item 2"), 6) - w.Flush() + if err := w.CopyBulk(strings.NewReader("item 2"), 6); err != nil { + panic(err) + } + if err := w.Flush(); err != nil { + panic(err) + } fmt.Printf("%q\n", b.String()) // Output: diff --git a/resp/request_test.go b/resp/request_test.go index 4ab1456..1e769b0 100644 --- a/resp/request_test.go +++ b/resp/request_test.go @@ -5,10 +5,9 @@ import ( "io" "strings" - "github.com/bsm/redeo/resp" - . "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo/extensions/table" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" + "github.com/bsm/redeo/v2/resp" ) var _ = Describe("RequestReader", func() { diff --git a/resp/resp.go b/resp/resp.go index 2ae63da..50bb140 100644 --- a/resp/resp.go +++ b/resp/resp.go @@ -86,7 +86,6 @@ func IsProtocolError(err error) bool { const ( errInvalidMultiBulkLength = protoError("Protocol error: invalid multibulk length") errInvalidBulkLength = protoError("Protocol error: invalid bulk length") - errBlankBulkLength = protoError("Protocol error: expected '$', got ' '") errInlineRequestTooLong = protoError("Protocol error: too big inline request") errNotANumber = protoError("Protocol error: expected a number") errNotANilMessage = protoError("Protocol error: expected a nil") diff --git a/resp/resp_test.go b/resp/resp_test.go index afed7ab..53186d6 100644 --- a/resp/resp_test.go +++ b/resp/resp_test.go @@ -6,10 +6,10 @@ import ( "reflect" "testing" - "github.com/bsm/redeo/resp" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/onsi/gomega/types" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" + "github.com/bsm/gomega/types" + "github.com/bsm/redeo/v2/resp" ) var _ = Describe("ResponseType", func() { diff --git a/resp/response_test.go b/resp/response_test.go index 69cea7d..1a5e36e 100644 --- a/resp/response_test.go +++ b/resp/response_test.go @@ -9,10 +9,9 @@ import ( "strings" "time" - "github.com/bsm/redeo/resp" - . "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo/extensions/table" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" + "github.com/bsm/redeo/v2/resp" ) var _ = Describe("ResponseWriter", func() { @@ -99,7 +98,7 @@ var _ = Describe("ResponseWriter", func() { DescribeTable("Append", func(v interface{}, exp string) { - subject.Append(v) + Expect(subject.Append(v)).To(Succeed()) Expect(subject.Flush()).To(Succeed()) Expect(strconv.Quote(buf.String())).To(Equal(strconv.Quote(exp))) }, diff --git a/resp/util_test.go b/resp/util_test.go index c848c8b..75a79f1 100644 --- a/resp/util_test.go +++ b/resp/util_test.go @@ -1,8 +1,8 @@ package resp import ( - . "github.com/onsi/ginkgo/extensions/table" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" ) var _ = DescribeTable("appendArgument", diff --git a/resp/value.go b/resp/value.go index c8e811b..355a8ee 100644 --- a/resp/value.go +++ b/resp/value.go @@ -63,15 +63,21 @@ func (w *bufioW) Append(v interface{}) error { w.AppendArrayLen(s.Len()) for i := 0; i < s.Len(); i++ { - w.Append(s.Index(i).Interface()) + if err := w.Append(s.Index(i).Interface()); err != nil { + return err + } } case reflect.Map: s := reflect.ValueOf(v) w.AppendArrayLen(s.Len() * 2) for _, key := range s.MapKeys() { - w.Append(key.Interface()) - w.Append(s.MapIndex(key).Interface()) + if err := w.Append(key.Interface()); err != nil { + return err + } + if err := w.Append(s.MapIndex(key).Interface()); err != nil { + return err + } } default: return fmt.Errorf("resp: unsupported type %T", v) diff --git a/server.go b/server.go index 57b9b18..67ca0b3 100644 --- a/server.go +++ b/server.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "github.com/bsm/redeo/resp" + "github.com/bsm/redeo/v2/resp" ) // Server configuration @@ -69,8 +69,8 @@ func (srv *Server) Serve(lis net.Listener) error { if ka := srv.config.TCPKeepAlive; ka > 0 { if tc, ok := cn.(*net.TCPConn); ok { - tc.SetKeepAlive(true) - tc.SetKeepAlivePeriod(ka) + _ = tc.SetKeepAlive(true) + _ = tc.SetKeepAlivePeriod(ka) } } @@ -96,7 +96,7 @@ func (srv *Server) serveClient(c *Client) { for !c.closed { // set deadline if d := srv.config.Timeout; d > 0 { - c.cn.SetDeadline(time.Now().Add(d)) + _ = c.cn.SetDeadline(time.Now().Add(d)) } // perform pipeline diff --git a/server_test.go b/server_test.go index 0d1a321..50c0caf 100644 --- a/server_test.go +++ b/server_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" - "github.com/bsm/redeo/resp" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" + . "github.com/bsm/ginkgo/v2" + . "github.com/bsm/gomega" + "github.com/bsm/redeo/v2/resp" ) var _ = Describe("Server", func() { @@ -74,7 +74,7 @@ var _ = Describe("Server", func() { defer lis.Close() // start listening - go srv.Serve(lis) + go func() { _ = srv.Serve(lis) }() // connect client cn, err := net.Dial("tcp", lis.Addr().String()) @@ -338,7 +338,12 @@ func benchmarkServer(b *testing.B, pipe []byte, expN int) { w.AppendInline(cmd.Arg(0)) }) - go srv.Serve(lis) + // start listening + go func() { + defer GinkgoRecover() + + Expect(srv.Serve(lis)).To(Succeed()) + }() conn, err := net.Dial("tcp", lis.Addr().String()) if err != nil {