Remove gotest.tools
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @@ -68,7 +68,6 @@ require ( | ||||
| 	golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e | ||||
| 	google.golang.org/grpc v1.43.0 | ||||
| 	google.golang.org/protobuf v1.27.1 | ||||
| 	gotest.tools/v3 v3.0.3 | ||||
| 	k8s.io/api v0.22.5 | ||||
| 	k8s.io/apimachinery v0.22.5 | ||||
| 	k8s.io/apiserver v0.22.5 | ||||
| @@ -122,7 +121,6 @@ require ( | ||||
| 	golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect | ||||
| 	golang.org/x/text v0.3.7 // indirect | ||||
| 	golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect | ||||
| 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect | ||||
| 	google.golang.org/appengine v1.6.7 // indirect | ||||
| 	google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect | ||||
| 	gopkg.in/inf.v0 v0.9.1 // indirect | ||||
|   | ||||
							
								
								
									
										18
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								go.sum
									
									
									
									
									
								
							| @@ -78,7 +78,6 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3 | ||||
| github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= | ||||
| github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= | ||||
| github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= | ||||
| github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= | ||||
| github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= | ||||
| github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= | ||||
| github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY= | ||||
| @@ -99,7 +98,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF | ||||
| github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||
| github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= | ||||
| github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= | ||||
| github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= | ||||
| github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= | ||||
| github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= | ||||
| github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= | ||||
| @@ -123,7 +121,6 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb | ||||
| github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= | ||||
| github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= | ||||
| github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= | ||||
| github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= | ||||
| github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= | ||||
| github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= | ||||
| github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= | ||||
| @@ -280,7 +277,6 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc | ||||
| github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= | ||||
| github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= | ||||
| github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= | ||||
| github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= | ||||
| github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= | ||||
| github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| @@ -401,7 +397,6 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh | ||||
| github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= | ||||
| github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= | ||||
| github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | ||||
| github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= | ||||
| github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= | ||||
| github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= | ||||
| github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= | ||||
| @@ -611,7 +606,6 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx | ||||
| github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= | ||||
| github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= | ||||
| github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= | ||||
| github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= | ||||
| @@ -662,11 +656,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW | ||||
| github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | ||||
| github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= | ||||
| github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= | ||||
| github.com/networkplumbing/go-nft v0.2.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs= | ||||
| github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= | ||||
| github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | ||||
| github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= | ||||
| github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= | ||||
| github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= | ||||
| github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= | ||||
| github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| @@ -681,7 +673,6 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 | ||||
| github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= | ||||
| github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= | ||||
| github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= | ||||
| github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= | ||||
| github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= | ||||
| github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= | ||||
| github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= | ||||
| @@ -691,7 +682,6 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT | ||||
| github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= | ||||
| github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= | ||||
| github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= | ||||
| github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= | ||||
| github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= | ||||
| github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= | ||||
| github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= | ||||
| @@ -781,13 +771,11 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T | ||||
| github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= | ||||
| github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= | ||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= | ||||
| github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= | ||||
| github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= | ||||
| github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||||
| github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= | ||||
| github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= | ||||
| github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= | ||||
| github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= | ||||
| github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= | ||||
| github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= | ||||
| @@ -1045,7 +1033,6 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v | ||||
| golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
| golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= | ||||
| golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= | ||||
| golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= | ||||
| golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| @@ -1150,7 +1137,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| @@ -1167,7 +1153,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc | ||||
| golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| @@ -1255,12 +1240,10 @@ golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4X | ||||
| golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||||
| golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||||
| golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||||
| golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||||
| golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||||
| golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||||
| golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= | ||||
| golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= | ||||
| golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= | ||||
| golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= | ||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| @@ -1381,7 +1364,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v | ||||
| gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= | ||||
| gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= | ||||
| gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= | ||||
| gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= | ||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
|   | ||||
							
								
								
									
										148
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										148
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,148 +0,0 @@ | ||||
| // Copyright 2017, The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // Package cmpopts provides common options for the cmp package. | ||||
| package cmpopts | ||||
|  | ||||
| import ( | ||||
| 	"math" | ||||
| 	"reflect" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
| ) | ||||
|  | ||||
| func equateAlways(_, _ interface{}) bool { return true } | ||||
|  | ||||
| // EquateEmpty returns a Comparer option that determines all maps and slices | ||||
| // with a length of zero to be equal, regardless of whether they are nil. | ||||
| // | ||||
| // EquateEmpty can be used in conjunction with SortSlices and SortMaps. | ||||
| func EquateEmpty() cmp.Option { | ||||
| 	return cmp.FilterValues(isEmpty, cmp.Comparer(equateAlways)) | ||||
| } | ||||
|  | ||||
| func isEmpty(x, y interface{}) bool { | ||||
| 	vx, vy := reflect.ValueOf(x), reflect.ValueOf(y) | ||||
| 	return (x != nil && y != nil && vx.Type() == vy.Type()) && | ||||
| 		(vx.Kind() == reflect.Slice || vx.Kind() == reflect.Map) && | ||||
| 		(vx.Len() == 0 && vy.Len() == 0) | ||||
| } | ||||
|  | ||||
| // EquateApprox returns a Comparer option that determines float32 or float64 | ||||
| // values to be equal if they are within a relative fraction or absolute margin. | ||||
| // This option is not used when either x or y is NaN or infinite. | ||||
| // | ||||
| // The fraction determines that the difference of two values must be within the | ||||
| // smaller fraction of the two values, while the margin determines that the two | ||||
| // values must be within some absolute margin. | ||||
| // To express only a fraction or only a margin, use 0 for the other parameter. | ||||
| // The fraction and margin must be non-negative. | ||||
| // | ||||
| // The mathematical expression used is equivalent to: | ||||
| //	|x-y| ≤ max(fraction*min(|x|, |y|), margin) | ||||
| // | ||||
| // EquateApprox can be used in conjunction with EquateNaNs. | ||||
| func EquateApprox(fraction, margin float64) cmp.Option { | ||||
| 	if margin < 0 || fraction < 0 || math.IsNaN(margin) || math.IsNaN(fraction) { | ||||
| 		panic("margin or fraction must be a non-negative number") | ||||
| 	} | ||||
| 	a := approximator{fraction, margin} | ||||
| 	return cmp.Options{ | ||||
| 		cmp.FilterValues(areRealF64s, cmp.Comparer(a.compareF64)), | ||||
| 		cmp.FilterValues(areRealF32s, cmp.Comparer(a.compareF32)), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type approximator struct{ frac, marg float64 } | ||||
|  | ||||
| func areRealF64s(x, y float64) bool { | ||||
| 	return !math.IsNaN(x) && !math.IsNaN(y) && !math.IsInf(x, 0) && !math.IsInf(y, 0) | ||||
| } | ||||
| func areRealF32s(x, y float32) bool { | ||||
| 	return areRealF64s(float64(x), float64(y)) | ||||
| } | ||||
| func (a approximator) compareF64(x, y float64) bool { | ||||
| 	relMarg := a.frac * math.Min(math.Abs(x), math.Abs(y)) | ||||
| 	return math.Abs(x-y) <= math.Max(a.marg, relMarg) | ||||
| } | ||||
| func (a approximator) compareF32(x, y float32) bool { | ||||
| 	return a.compareF64(float64(x), float64(y)) | ||||
| } | ||||
|  | ||||
| // EquateNaNs returns a Comparer option that determines float32 and float64 | ||||
| // NaN values to be equal. | ||||
| // | ||||
| // EquateNaNs can be used in conjunction with EquateApprox. | ||||
| func EquateNaNs() cmp.Option { | ||||
| 	return cmp.Options{ | ||||
| 		cmp.FilterValues(areNaNsF64s, cmp.Comparer(equateAlways)), | ||||
| 		cmp.FilterValues(areNaNsF32s, cmp.Comparer(equateAlways)), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func areNaNsF64s(x, y float64) bool { | ||||
| 	return math.IsNaN(x) && math.IsNaN(y) | ||||
| } | ||||
| func areNaNsF32s(x, y float32) bool { | ||||
| 	return areNaNsF64s(float64(x), float64(y)) | ||||
| } | ||||
|  | ||||
| // EquateApproxTime returns a Comparer option that determines two non-zero | ||||
| // time.Time values to be equal if they are within some margin of one another. | ||||
| // If both times have a monotonic clock reading, then the monotonic time | ||||
| // difference will be used. The margin must be non-negative. | ||||
| func EquateApproxTime(margin time.Duration) cmp.Option { | ||||
| 	if margin < 0 { | ||||
| 		panic("margin must be a non-negative number") | ||||
| 	} | ||||
| 	a := timeApproximator{margin} | ||||
| 	return cmp.FilterValues(areNonZeroTimes, cmp.Comparer(a.compare)) | ||||
| } | ||||
|  | ||||
| func areNonZeroTimes(x, y time.Time) bool { | ||||
| 	return !x.IsZero() && !y.IsZero() | ||||
| } | ||||
|  | ||||
| type timeApproximator struct { | ||||
| 	margin time.Duration | ||||
| } | ||||
|  | ||||
| func (a timeApproximator) compare(x, y time.Time) bool { | ||||
| 	// Avoid subtracting times to avoid overflow when the | ||||
| 	// difference is larger than the largest representible duration. | ||||
| 	if x.After(y) { | ||||
| 		// Ensure x is always before y | ||||
| 		x, y = y, x | ||||
| 	} | ||||
| 	// We're within the margin if x+margin >= y. | ||||
| 	// Note: time.Time doesn't have AfterOrEqual method hence the negation. | ||||
| 	return !x.Add(a.margin).Before(y) | ||||
| } | ||||
|  | ||||
| // AnyError is an error that matches any non-nil error. | ||||
| var AnyError anyError | ||||
|  | ||||
| type anyError struct{} | ||||
|  | ||||
| func (anyError) Error() string     { return "any error" } | ||||
| func (anyError) Is(err error) bool { return err != nil } | ||||
|  | ||||
| // EquateErrors returns a Comparer option that determines errors to be equal | ||||
| // if errors.Is reports them to match. The AnyError error can be used to | ||||
| // match any non-nil error. | ||||
| func EquateErrors() cmp.Option { | ||||
| 	return cmp.FilterValues(areConcreteErrors, cmp.Comparer(compareErrors)) | ||||
| } | ||||
|  | ||||
| // areConcreteErrors reports whether x and y are types that implement error. | ||||
| // The input types are deliberately of the interface{} type rather than the | ||||
| // error type so that we can handle situations where the current type is an | ||||
| // interface{}, but the underlying concrete types both happen to implement | ||||
| // the error interface. | ||||
| func areConcreteErrors(x, y interface{}) bool { | ||||
| 	_, ok1 := x.(error) | ||||
| 	_, ok2 := y.(error) | ||||
| 	return ok1 && ok2 | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/errors_go113.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/errors_go113.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,15 +0,0 @@ | ||||
| // Copyright 2021, The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // +build go1.13 | ||||
|  | ||||
| package cmpopts | ||||
|  | ||||
| import "errors" | ||||
|  | ||||
| func compareErrors(x, y interface{}) bool { | ||||
| 	xe := x.(error) | ||||
| 	ye := y.(error) | ||||
| 	return errors.Is(xe, ye) || errors.Is(ye, xe) | ||||
| } | ||||
							
								
								
									
										18
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/errors_xerrors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/errors_xerrors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,18 +0,0 @@ | ||||
| // Copyright 2021, The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // +build !go1.13 | ||||
|  | ||||
| // TODO(≥go1.13): For support on <go1.13, we use the xerrors package. | ||||
| // Drop this file when we no longer support older Go versions. | ||||
|  | ||||
| package cmpopts | ||||
|  | ||||
| import "golang.org/x/xerrors" | ||||
|  | ||||
| func compareErrors(x, y interface{}) bool { | ||||
| 	xe := x.(error) | ||||
| 	ye := y.(error) | ||||
| 	return xerrors.Is(xe, ye) || xerrors.Is(ye, xe) | ||||
| } | ||||
							
								
								
									
										206
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										206
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,206 +0,0 @@ | ||||
| // Copyright 2017, The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package cmpopts | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"unicode" | ||||
| 	"unicode/utf8" | ||||
|  | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
| 	"github.com/google/go-cmp/cmp/internal/function" | ||||
| ) | ||||
|  | ||||
| // IgnoreFields returns an Option that ignores fields of the | ||||
| // given names on a single struct type. It respects the names of exported fields | ||||
| // that are forwarded due to struct embedding. | ||||
| // The struct type is specified by passing in a value of that type. | ||||
| // | ||||
| // The name may be a dot-delimited string (e.g., "Foo.Bar") to ignore a | ||||
| // specific sub-field that is embedded or nested within the parent struct. | ||||
| func IgnoreFields(typ interface{}, names ...string) cmp.Option { | ||||
| 	sf := newStructFilter(typ, names...) | ||||
| 	return cmp.FilterPath(sf.filter, cmp.Ignore()) | ||||
| } | ||||
|  | ||||
| // IgnoreTypes returns an Option that ignores all values assignable to | ||||
| // certain types, which are specified by passing in a value of each type. | ||||
| func IgnoreTypes(typs ...interface{}) cmp.Option { | ||||
| 	tf := newTypeFilter(typs...) | ||||
| 	return cmp.FilterPath(tf.filter, cmp.Ignore()) | ||||
| } | ||||
|  | ||||
| type typeFilter []reflect.Type | ||||
|  | ||||
| func newTypeFilter(typs ...interface{}) (tf typeFilter) { | ||||
| 	for _, typ := range typs { | ||||
| 		t := reflect.TypeOf(typ) | ||||
| 		if t == nil { | ||||
| 			// This occurs if someone tries to pass in sync.Locker(nil) | ||||
| 			panic("cannot determine type; consider using IgnoreInterfaces") | ||||
| 		} | ||||
| 		tf = append(tf, t) | ||||
| 	} | ||||
| 	return tf | ||||
| } | ||||
| func (tf typeFilter) filter(p cmp.Path) bool { | ||||
| 	if len(p) < 1 { | ||||
| 		return false | ||||
| 	} | ||||
| 	t := p.Last().Type() | ||||
| 	for _, ti := range tf { | ||||
| 		if t.AssignableTo(ti) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // IgnoreInterfaces returns an Option that ignores all values or references of | ||||
| // values assignable to certain interface types. These interfaces are specified | ||||
| // by passing in an anonymous struct with the interface types embedded in it. | ||||
| // For example, to ignore sync.Locker, pass in struct{sync.Locker}{}. | ||||
| func IgnoreInterfaces(ifaces interface{}) cmp.Option { | ||||
| 	tf := newIfaceFilter(ifaces) | ||||
| 	return cmp.FilterPath(tf.filter, cmp.Ignore()) | ||||
| } | ||||
|  | ||||
| type ifaceFilter []reflect.Type | ||||
|  | ||||
| func newIfaceFilter(ifaces interface{}) (tf ifaceFilter) { | ||||
| 	t := reflect.TypeOf(ifaces) | ||||
| 	if ifaces == nil || t.Name() != "" || t.Kind() != reflect.Struct { | ||||
| 		panic("input must be an anonymous struct") | ||||
| 	} | ||||
| 	for i := 0; i < t.NumField(); i++ { | ||||
| 		fi := t.Field(i) | ||||
| 		switch { | ||||
| 		case !fi.Anonymous: | ||||
| 			panic("struct cannot have named fields") | ||||
| 		case fi.Type.Kind() != reflect.Interface: | ||||
| 			panic("embedded field must be an interface type") | ||||
| 		case fi.Type.NumMethod() == 0: | ||||
| 			// This matches everything; why would you ever want this? | ||||
| 			panic("cannot ignore empty interface") | ||||
| 		default: | ||||
| 			tf = append(tf, fi.Type) | ||||
| 		} | ||||
| 	} | ||||
| 	return tf | ||||
| } | ||||
| func (tf ifaceFilter) filter(p cmp.Path) bool { | ||||
| 	if len(p) < 1 { | ||||
| 		return false | ||||
| 	} | ||||
| 	t := p.Last().Type() | ||||
| 	for _, ti := range tf { | ||||
| 		if t.AssignableTo(ti) { | ||||
| 			return true | ||||
| 		} | ||||
| 		if t.Kind() != reflect.Ptr && reflect.PtrTo(t).AssignableTo(ti) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // IgnoreUnexported returns an Option that only ignores the immediate unexported | ||||
| // fields of a struct, including anonymous fields of unexported types. | ||||
| // In particular, unexported fields within the struct's exported fields | ||||
| // of struct types, including anonymous fields, will not be ignored unless the | ||||
| // type of the field itself is also passed to IgnoreUnexported. | ||||
| // | ||||
| // Avoid ignoring unexported fields of a type which you do not control (i.e. a | ||||
| // type from another repository), as changes to the implementation of such types | ||||
| // may change how the comparison behaves. Prefer a custom Comparer instead. | ||||
| func IgnoreUnexported(typs ...interface{}) cmp.Option { | ||||
| 	ux := newUnexportedFilter(typs...) | ||||
| 	return cmp.FilterPath(ux.filter, cmp.Ignore()) | ||||
| } | ||||
|  | ||||
| type unexportedFilter struct{ m map[reflect.Type]bool } | ||||
|  | ||||
| func newUnexportedFilter(typs ...interface{}) unexportedFilter { | ||||
| 	ux := unexportedFilter{m: make(map[reflect.Type]bool)} | ||||
| 	for _, typ := range typs { | ||||
| 		t := reflect.TypeOf(typ) | ||||
| 		if t == nil || t.Kind() != reflect.Struct { | ||||
| 			panic(fmt.Sprintf("%T must be a non-pointer struct", typ)) | ||||
| 		} | ||||
| 		ux.m[t] = true | ||||
| 	} | ||||
| 	return ux | ||||
| } | ||||
| func (xf unexportedFilter) filter(p cmp.Path) bool { | ||||
| 	sf, ok := p.Index(-1).(cmp.StructField) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	return xf.m[p.Index(-2).Type()] && !isExported(sf.Name()) | ||||
| } | ||||
|  | ||||
| // isExported reports whether the identifier is exported. | ||||
| func isExported(id string) bool { | ||||
| 	r, _ := utf8.DecodeRuneInString(id) | ||||
| 	return unicode.IsUpper(r) | ||||
| } | ||||
|  | ||||
| // IgnoreSliceElements returns an Option that ignores elements of []V. | ||||
| // The discard function must be of the form "func(T) bool" which is used to | ||||
| // ignore slice elements of type V, where V is assignable to T. | ||||
| // Elements are ignored if the function reports true. | ||||
| func IgnoreSliceElements(discardFunc interface{}) cmp.Option { | ||||
| 	vf := reflect.ValueOf(discardFunc) | ||||
| 	if !function.IsType(vf.Type(), function.ValuePredicate) || vf.IsNil() { | ||||
| 		panic(fmt.Sprintf("invalid discard function: %T", discardFunc)) | ||||
| 	} | ||||
| 	return cmp.FilterPath(func(p cmp.Path) bool { | ||||
| 		si, ok := p.Index(-1).(cmp.SliceIndex) | ||||
| 		if !ok { | ||||
| 			return false | ||||
| 		} | ||||
| 		if !si.Type().AssignableTo(vf.Type().In(0)) { | ||||
| 			return false | ||||
| 		} | ||||
| 		vx, vy := si.Values() | ||||
| 		if vx.IsValid() && vf.Call([]reflect.Value{vx})[0].Bool() { | ||||
| 			return true | ||||
| 		} | ||||
| 		if vy.IsValid() && vf.Call([]reflect.Value{vy})[0].Bool() { | ||||
| 			return true | ||||
| 		} | ||||
| 		return false | ||||
| 	}, cmp.Ignore()) | ||||
| } | ||||
|  | ||||
| // IgnoreMapEntries returns an Option that ignores entries of map[K]V. | ||||
| // The discard function must be of the form "func(T, R) bool" which is used to | ||||
| // ignore map entries of type K and V, where K and V are assignable to T and R. | ||||
| // Entries are ignored if the function reports true. | ||||
| func IgnoreMapEntries(discardFunc interface{}) cmp.Option { | ||||
| 	vf := reflect.ValueOf(discardFunc) | ||||
| 	if !function.IsType(vf.Type(), function.KeyValuePredicate) || vf.IsNil() { | ||||
| 		panic(fmt.Sprintf("invalid discard function: %T", discardFunc)) | ||||
| 	} | ||||
| 	return cmp.FilterPath(func(p cmp.Path) bool { | ||||
| 		mi, ok := p.Index(-1).(cmp.MapIndex) | ||||
| 		if !ok { | ||||
| 			return false | ||||
| 		} | ||||
| 		if !mi.Key().Type().AssignableTo(vf.Type().In(0)) || !mi.Type().AssignableTo(vf.Type().In(1)) { | ||||
| 			return false | ||||
| 		} | ||||
| 		k := mi.Key() | ||||
| 		vx, vy := mi.Values() | ||||
| 		if vx.IsValid() && vf.Call([]reflect.Value{k, vx})[0].Bool() { | ||||
| 			return true | ||||
| 		} | ||||
| 		if vy.IsValid() && vf.Call([]reflect.Value{k, vy})[0].Bool() { | ||||
| 			return true | ||||
| 		} | ||||
| 		return false | ||||
| 	}, cmp.Ignore()) | ||||
| } | ||||
							
								
								
									
										147
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										147
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,147 +0,0 @@ | ||||
| // Copyright 2017, The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package cmpopts | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
|  | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
| 	"github.com/google/go-cmp/cmp/internal/function" | ||||
| ) | ||||
|  | ||||
| // SortSlices returns a Transformer option that sorts all []V. | ||||
| // The less function must be of the form "func(T, T) bool" which is used to | ||||
| // sort any slice with element type V that is assignable to T. | ||||
| // | ||||
| // The less function must be: | ||||
| //	• Deterministic: less(x, y) == less(x, y) | ||||
| //	• Irreflexive: !less(x, x) | ||||
| //	• Transitive: if !less(x, y) and !less(y, z), then !less(x, z) | ||||
| // | ||||
| // The less function does not have to be "total". That is, if !less(x, y) and | ||||
| // !less(y, x) for two elements x and y, their relative order is maintained. | ||||
| // | ||||
| // SortSlices can be used in conjunction with EquateEmpty. | ||||
| func SortSlices(lessFunc interface{}) cmp.Option { | ||||
| 	vf := reflect.ValueOf(lessFunc) | ||||
| 	if !function.IsType(vf.Type(), function.Less) || vf.IsNil() { | ||||
| 		panic(fmt.Sprintf("invalid less function: %T", lessFunc)) | ||||
| 	} | ||||
| 	ss := sliceSorter{vf.Type().In(0), vf} | ||||
| 	return cmp.FilterValues(ss.filter, cmp.Transformer("cmpopts.SortSlices", ss.sort)) | ||||
| } | ||||
|  | ||||
| type sliceSorter struct { | ||||
| 	in  reflect.Type  // T | ||||
| 	fnc reflect.Value // func(T, T) bool | ||||
| } | ||||
|  | ||||
| func (ss sliceSorter) filter(x, y interface{}) bool { | ||||
| 	vx, vy := reflect.ValueOf(x), reflect.ValueOf(y) | ||||
| 	if !(x != nil && y != nil && vx.Type() == vy.Type()) || | ||||
| 		!(vx.Kind() == reflect.Slice && vx.Type().Elem().AssignableTo(ss.in)) || | ||||
| 		(vx.Len() <= 1 && vy.Len() <= 1) { | ||||
| 		return false | ||||
| 	} | ||||
| 	// Check whether the slices are already sorted to avoid an infinite | ||||
| 	// recursion cycle applying the same transform to itself. | ||||
| 	ok1 := sort.SliceIsSorted(x, func(i, j int) bool { return ss.less(vx, i, j) }) | ||||
| 	ok2 := sort.SliceIsSorted(y, func(i, j int) bool { return ss.less(vy, i, j) }) | ||||
| 	return !ok1 || !ok2 | ||||
| } | ||||
| func (ss sliceSorter) sort(x interface{}) interface{} { | ||||
| 	src := reflect.ValueOf(x) | ||||
| 	dst := reflect.MakeSlice(src.Type(), src.Len(), src.Len()) | ||||
| 	for i := 0; i < src.Len(); i++ { | ||||
| 		dst.Index(i).Set(src.Index(i)) | ||||
| 	} | ||||
| 	sort.SliceStable(dst.Interface(), func(i, j int) bool { return ss.less(dst, i, j) }) | ||||
| 	ss.checkSort(dst) | ||||
| 	return dst.Interface() | ||||
| } | ||||
| func (ss sliceSorter) checkSort(v reflect.Value) { | ||||
| 	start := -1 // Start of a sequence of equal elements. | ||||
| 	for i := 1; i < v.Len(); i++ { | ||||
| 		if ss.less(v, i-1, i) { | ||||
| 			// Check that first and last elements in v[start:i] are equal. | ||||
| 			if start >= 0 && (ss.less(v, start, i-1) || ss.less(v, i-1, start)) { | ||||
| 				panic(fmt.Sprintf("incomparable values detected: want equal elements: %v", v.Slice(start, i))) | ||||
| 			} | ||||
| 			start = -1 | ||||
| 		} else if start == -1 { | ||||
| 			start = i | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| func (ss sliceSorter) less(v reflect.Value, i, j int) bool { | ||||
| 	vx, vy := v.Index(i), v.Index(j) | ||||
| 	return ss.fnc.Call([]reflect.Value{vx, vy})[0].Bool() | ||||
| } | ||||
|  | ||||
| // SortMaps returns a Transformer option that flattens map[K]V types to be a | ||||
| // sorted []struct{K, V}. The less function must be of the form | ||||
| // "func(T, T) bool" which is used to sort any map with key K that is | ||||
| // assignable to T. | ||||
| // | ||||
| // Flattening the map into a slice has the property that cmp.Equal is able to | ||||
| // use Comparers on K or the K.Equal method if it exists. | ||||
| // | ||||
| // The less function must be: | ||||
| //	• Deterministic: less(x, y) == less(x, y) | ||||
| //	• Irreflexive: !less(x, x) | ||||
| //	• Transitive: if !less(x, y) and !less(y, z), then !less(x, z) | ||||
| //	• Total: if x != y, then either less(x, y) or less(y, x) | ||||
| // | ||||
| // SortMaps can be used in conjunction with EquateEmpty. | ||||
| func SortMaps(lessFunc interface{}) cmp.Option { | ||||
| 	vf := reflect.ValueOf(lessFunc) | ||||
| 	if !function.IsType(vf.Type(), function.Less) || vf.IsNil() { | ||||
| 		panic(fmt.Sprintf("invalid less function: %T", lessFunc)) | ||||
| 	} | ||||
| 	ms := mapSorter{vf.Type().In(0), vf} | ||||
| 	return cmp.FilterValues(ms.filter, cmp.Transformer("cmpopts.SortMaps", ms.sort)) | ||||
| } | ||||
|  | ||||
| type mapSorter struct { | ||||
| 	in  reflect.Type  // T | ||||
| 	fnc reflect.Value // func(T, T) bool | ||||
| } | ||||
|  | ||||
| func (ms mapSorter) filter(x, y interface{}) bool { | ||||
| 	vx, vy := reflect.ValueOf(x), reflect.ValueOf(y) | ||||
| 	return (x != nil && y != nil && vx.Type() == vy.Type()) && | ||||
| 		(vx.Kind() == reflect.Map && vx.Type().Key().AssignableTo(ms.in)) && | ||||
| 		(vx.Len() != 0 || vy.Len() != 0) | ||||
| } | ||||
| func (ms mapSorter) sort(x interface{}) interface{} { | ||||
| 	src := reflect.ValueOf(x) | ||||
| 	outType := reflect.StructOf([]reflect.StructField{ | ||||
| 		{Name: "K", Type: src.Type().Key()}, | ||||
| 		{Name: "V", Type: src.Type().Elem()}, | ||||
| 	}) | ||||
| 	dst := reflect.MakeSlice(reflect.SliceOf(outType), src.Len(), src.Len()) | ||||
| 	for i, k := range src.MapKeys() { | ||||
| 		v := reflect.New(outType).Elem() | ||||
| 		v.Field(0).Set(k) | ||||
| 		v.Field(1).Set(src.MapIndex(k)) | ||||
| 		dst.Index(i).Set(v) | ||||
| 	} | ||||
| 	sort.Slice(dst.Interface(), func(i, j int) bool { return ms.less(dst, i, j) }) | ||||
| 	ms.checkSort(dst) | ||||
| 	return dst.Interface() | ||||
| } | ||||
| func (ms mapSorter) checkSort(v reflect.Value) { | ||||
| 	for i := 1; i < v.Len(); i++ { | ||||
| 		if !ms.less(v, i-1, i) { | ||||
| 			panic(fmt.Sprintf("partial order detected: want %v < %v", v.Index(i-1), v.Index(i))) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| func (ms mapSorter) less(v reflect.Value, i, j int) bool { | ||||
| 	vx, vy := v.Index(i).Field(0), v.Index(j).Field(0) | ||||
| 	return ms.fnc.Call([]reflect.Value{vx, vy})[0].Bool() | ||||
| } | ||||
							
								
								
									
										187
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										187
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,187 +0,0 @@ | ||||
| // Copyright 2017, The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package cmpopts | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
| ) | ||||
|  | ||||
| // filterField returns a new Option where opt is only evaluated on paths that | ||||
| // include a specific exported field on a single struct type. | ||||
| // The struct type is specified by passing in a value of that type. | ||||
| // | ||||
| // The name may be a dot-delimited string (e.g., "Foo.Bar") to select a | ||||
| // specific sub-field that is embedded or nested within the parent struct. | ||||
| func filterField(typ interface{}, name string, opt cmp.Option) cmp.Option { | ||||
| 	// TODO: This is currently unexported over concerns of how helper filters | ||||
| 	// can be composed together easily. | ||||
| 	// TODO: Add tests for FilterField. | ||||
|  | ||||
| 	sf := newStructFilter(typ, name) | ||||
| 	return cmp.FilterPath(sf.filter, opt) | ||||
| } | ||||
|  | ||||
| type structFilter struct { | ||||
| 	t  reflect.Type // The root struct type to match on | ||||
| 	ft fieldTree    // Tree of fields to match on | ||||
| } | ||||
|  | ||||
| func newStructFilter(typ interface{}, names ...string) structFilter { | ||||
| 	// TODO: Perhaps allow * as a special identifier to allow ignoring any | ||||
| 	// number of path steps until the next field match? | ||||
| 	// This could be useful when a concrete struct gets transformed into | ||||
| 	// an anonymous struct where it is not possible to specify that by type, | ||||
| 	// but the transformer happens to provide guarantees about the names of | ||||
| 	// the transformed fields. | ||||
|  | ||||
| 	t := reflect.TypeOf(typ) | ||||
| 	if t == nil || t.Kind() != reflect.Struct { | ||||
| 		panic(fmt.Sprintf("%T must be a non-pointer struct", typ)) | ||||
| 	} | ||||
| 	var ft fieldTree | ||||
| 	for _, name := range names { | ||||
| 		cname, err := canonicalName(t, name) | ||||
| 		if err != nil { | ||||
| 			panic(fmt.Sprintf("%s: %v", strings.Join(cname, "."), err)) | ||||
| 		} | ||||
| 		ft.insert(cname) | ||||
| 	} | ||||
| 	return structFilter{t, ft} | ||||
| } | ||||
|  | ||||
| func (sf structFilter) filter(p cmp.Path) bool { | ||||
| 	for i, ps := range p { | ||||
| 		if ps.Type().AssignableTo(sf.t) && sf.ft.matchPrefix(p[i+1:]) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // fieldTree represents a set of dot-separated identifiers. | ||||
| // | ||||
| // For example, inserting the following selectors: | ||||
| //	Foo | ||||
| //	Foo.Bar.Baz | ||||
| //	Foo.Buzz | ||||
| //	Nuka.Cola.Quantum | ||||
| // | ||||
| // Results in a tree of the form: | ||||
| //	{sub: { | ||||
| //		"Foo": {ok: true, sub: { | ||||
| //			"Bar": {sub: { | ||||
| //				"Baz": {ok: true}, | ||||
| //			}}, | ||||
| //			"Buzz": {ok: true}, | ||||
| //		}}, | ||||
| //		"Nuka": {sub: { | ||||
| //			"Cola": {sub: { | ||||
| //				"Quantum": {ok: true}, | ||||
| //			}}, | ||||
| //		}}, | ||||
| //	}} | ||||
| type fieldTree struct { | ||||
| 	ok  bool                 // Whether this is a specified node | ||||
| 	sub map[string]fieldTree // The sub-tree of fields under this node | ||||
| } | ||||
|  | ||||
| // insert inserts a sequence of field accesses into the tree. | ||||
| func (ft *fieldTree) insert(cname []string) { | ||||
| 	if ft.sub == nil { | ||||
| 		ft.sub = make(map[string]fieldTree) | ||||
| 	} | ||||
| 	if len(cname) == 0 { | ||||
| 		ft.ok = true | ||||
| 		return | ||||
| 	} | ||||
| 	sub := ft.sub[cname[0]] | ||||
| 	sub.insert(cname[1:]) | ||||
| 	ft.sub[cname[0]] = sub | ||||
| } | ||||
|  | ||||
| // matchPrefix reports whether any selector in the fieldTree matches | ||||
| // the start of path p. | ||||
| func (ft fieldTree) matchPrefix(p cmp.Path) bool { | ||||
| 	for _, ps := range p { | ||||
| 		switch ps := ps.(type) { | ||||
| 		case cmp.StructField: | ||||
| 			ft = ft.sub[ps.Name()] | ||||
| 			if ft.ok { | ||||
| 				return true | ||||
| 			} | ||||
| 			if len(ft.sub) == 0 { | ||||
| 				return false | ||||
| 			} | ||||
| 		case cmp.Indirect: | ||||
| 		default: | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // canonicalName returns a list of identifiers where any struct field access | ||||
| // through an embedded field is expanded to include the names of the embedded | ||||
| // types themselves. | ||||
| // | ||||
| // For example, suppose field "Foo" is not directly in the parent struct, | ||||
| // but actually from an embedded struct of type "Bar". Then, the canonical name | ||||
| // of "Foo" is actually "Bar.Foo". | ||||
| // | ||||
| // Suppose field "Foo" is not directly in the parent struct, but actually | ||||
| // a field in two different embedded structs of types "Bar" and "Baz". | ||||
| // Then the selector "Foo" causes a panic since it is ambiguous which one it | ||||
| // refers to. The user must specify either "Bar.Foo" or "Baz.Foo". | ||||
| func canonicalName(t reflect.Type, sel string) ([]string, error) { | ||||
| 	var name string | ||||
| 	sel = strings.TrimPrefix(sel, ".") | ||||
| 	if sel == "" { | ||||
| 		return nil, fmt.Errorf("name must not be empty") | ||||
| 	} | ||||
| 	if i := strings.IndexByte(sel, '.'); i < 0 { | ||||
| 		name, sel = sel, "" | ||||
| 	} else { | ||||
| 		name, sel = sel[:i], sel[i:] | ||||
| 	} | ||||
|  | ||||
| 	// Type must be a struct or pointer to struct. | ||||
| 	if t.Kind() == reflect.Ptr { | ||||
| 		t = t.Elem() | ||||
| 	} | ||||
| 	if t.Kind() != reflect.Struct { | ||||
| 		return nil, fmt.Errorf("%v must be a struct", t) | ||||
| 	} | ||||
|  | ||||
| 	// Find the canonical name for this current field name. | ||||
| 	// If the field exists in an embedded struct, then it will be expanded. | ||||
| 	sf, _ := t.FieldByName(name) | ||||
| 	if !isExported(name) { | ||||
| 		// Avoid using reflect.Type.FieldByName for unexported fields due to | ||||
| 		// buggy behavior with regard to embeddeding and unexported fields. | ||||
| 		// See https://golang.org/issue/4876 for details. | ||||
| 		sf = reflect.StructField{} | ||||
| 		for i := 0; i < t.NumField() && sf.Name == ""; i++ { | ||||
| 			if t.Field(i).Name == name { | ||||
| 				sf = t.Field(i) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if sf.Name == "" { | ||||
| 		return []string{name}, fmt.Errorf("does not exist") | ||||
| 	} | ||||
| 	var ss []string | ||||
| 	for i := range sf.Index { | ||||
| 		ss = append(ss, t.FieldByIndex(sf.Index[:i+1]).Name) | ||||
| 	} | ||||
| 	if sel == "" { | ||||
| 		return ss, nil | ||||
| 	} | ||||
| 	ssPost, err := canonicalName(sf.Type, sel) | ||||
| 	return append(ss, ssPost...), err | ||||
| } | ||||
							
								
								
									
										35
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,35 +0,0 @@ | ||||
| // Copyright 2018, The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package cmpopts | ||||
|  | ||||
| import ( | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
| ) | ||||
|  | ||||
| type xformFilter struct{ xform cmp.Option } | ||||
|  | ||||
| func (xf xformFilter) filter(p cmp.Path) bool { | ||||
| 	for _, ps := range p { | ||||
| 		if t, ok := ps.(cmp.Transform); ok && t.Option() == xf.xform { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // AcyclicTransformer returns a Transformer with a filter applied that ensures | ||||
| // that the transformer cannot be recursively applied upon its own output. | ||||
| // | ||||
| // An example use case is a transformer that splits a string by lines: | ||||
| //	AcyclicTransformer("SplitLines", func(s string) []string{ | ||||
| //		return strings.Split(s, "\n") | ||||
| //	}) | ||||
| // | ||||
| // Had this been an unfiltered Transformer instead, this would result in an | ||||
| // infinite cycle converting a string to []string to [][]string and so on. | ||||
| func AcyclicTransformer(name string, xformFunc interface{}) cmp.Option { | ||||
| 	xf := xformFilter{cmp.Transformer(name, xformFunc)} | ||||
| 	return cmp.FilterPath(xf.filter, xf.xform) | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/golang.org/x/xerrors/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/golang.org/x/xerrors/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,27 +0,0 @@ | ||||
| Copyright (c) 2019 The Go Authors. All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
|  | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										22
									
								
								vendor/golang.org/x/xerrors/PATENTS
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/golang.org/x/xerrors/PATENTS
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,22 +0,0 @@ | ||||
| Additional IP Rights Grant (Patents) | ||||
|  | ||||
| "This implementation" means the copyrightable works distributed by | ||||
| Google as part of the Go project. | ||||
|  | ||||
| Google 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, | ||||
| transfer and otherwise run, modify and propagate the contents of this | ||||
| implementation of Go, where such license applies only to those patent | ||||
| claims, both currently owned or controlled by Google and acquired in | ||||
| the future, licensable by Google that are necessarily infringed by this | ||||
| implementation of Go.  This grant does not include claims that would be | ||||
| infringed only as a consequence of further modification of this | ||||
| implementation.  If you or your agent or exclusive licensee institute or | ||||
| order or agree to the institution of patent litigation against any | ||||
| entity (including a cross-claim or counterclaim in a lawsuit) alleging | ||||
| that this implementation of Go or any code incorporated within this | ||||
| implementation of Go constitutes direct or contributory patent | ||||
| infringement, or inducement of patent infringement, then any patent | ||||
| rights granted to you under this License for this implementation of Go | ||||
| shall terminate as of the date such litigation is filed. | ||||
							
								
								
									
										2
									
								
								vendor/golang.org/x/xerrors/README
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/golang.org/x/xerrors/README
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,2 +0,0 @@ | ||||
| This repository holds the transition packages for the new Go 1.13 error values. | ||||
| See golang.org/design/29934-error-values. | ||||
							
								
								
									
										193
									
								
								vendor/golang.org/x/xerrors/adaptor.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										193
									
								
								vendor/golang.org/x/xerrors/adaptor.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,193 +0,0 @@ | ||||
| // Copyright 2018 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package xerrors | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| // FormatError calls the FormatError method of f with an errors.Printer | ||||
| // configured according to s and verb, and writes the result to s. | ||||
| func FormatError(f Formatter, s fmt.State, verb rune) { | ||||
| 	// Assuming this function is only called from the Format method, and given | ||||
| 	// that FormatError takes precedence over Format, it cannot be called from | ||||
| 	// any package that supports errors.Formatter. It is therefore safe to | ||||
| 	// disregard that State may be a specific printer implementation and use one | ||||
| 	// of our choice instead. | ||||
|  | ||||
| 	// limitations: does not support printing error as Go struct. | ||||
|  | ||||
| 	var ( | ||||
| 		sep    = " " // separator before next error | ||||
| 		p      = &state{State: s} | ||||
| 		direct = true | ||||
| 	) | ||||
|  | ||||
| 	var err error = f | ||||
|  | ||||
| 	switch verb { | ||||
| 	// Note that this switch must match the preference order | ||||
| 	// for ordinary string printing (%#v before %+v, and so on). | ||||
|  | ||||
| 	case 'v': | ||||
| 		if s.Flag('#') { | ||||
| 			if stringer, ok := err.(fmt.GoStringer); ok { | ||||
| 				io.WriteString(&p.buf, stringer.GoString()) | ||||
| 				goto exit | ||||
| 			} | ||||
| 			// proceed as if it were %v | ||||
| 		} else if s.Flag('+') { | ||||
| 			p.printDetail = true | ||||
| 			sep = "\n  - " | ||||
| 		} | ||||
| 	case 's': | ||||
| 	case 'q', 'x', 'X': | ||||
| 		// Use an intermediate buffer in the rare cases that precision, | ||||
| 		// truncation, or one of the alternative verbs (q, x, and X) are | ||||
| 		// specified. | ||||
| 		direct = false | ||||
|  | ||||
| 	default: | ||||
| 		p.buf.WriteString("%!") | ||||
| 		p.buf.WriteRune(verb) | ||||
| 		p.buf.WriteByte('(') | ||||
| 		switch { | ||||
| 		case err != nil: | ||||
| 			p.buf.WriteString(reflect.TypeOf(f).String()) | ||||
| 		default: | ||||
| 			p.buf.WriteString("<nil>") | ||||
| 		} | ||||
| 		p.buf.WriteByte(')') | ||||
| 		io.Copy(s, &p.buf) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| loop: | ||||
| 	for { | ||||
| 		switch v := err.(type) { | ||||
| 		case Formatter: | ||||
| 			err = v.FormatError((*printer)(p)) | ||||
| 		case fmt.Formatter: | ||||
| 			v.Format(p, 'v') | ||||
| 			break loop | ||||
| 		default: | ||||
| 			io.WriteString(&p.buf, v.Error()) | ||||
| 			break loop | ||||
| 		} | ||||
| 		if err == nil { | ||||
| 			break | ||||
| 		} | ||||
| 		if p.needColon || !p.printDetail { | ||||
| 			p.buf.WriteByte(':') | ||||
| 			p.needColon = false | ||||
| 		} | ||||
| 		p.buf.WriteString(sep) | ||||
| 		p.inDetail = false | ||||
| 		p.needNewline = false | ||||
| 	} | ||||
|  | ||||
| exit: | ||||
| 	width, okW := s.Width() | ||||
| 	prec, okP := s.Precision() | ||||
|  | ||||
| 	if !direct || (okW && width > 0) || okP { | ||||
| 		// Construct format string from State s. | ||||
| 		format := []byte{'%'} | ||||
| 		if s.Flag('-') { | ||||
| 			format = append(format, '-') | ||||
| 		} | ||||
| 		if s.Flag('+') { | ||||
| 			format = append(format, '+') | ||||
| 		} | ||||
| 		if s.Flag(' ') { | ||||
| 			format = append(format, ' ') | ||||
| 		} | ||||
| 		if okW { | ||||
| 			format = strconv.AppendInt(format, int64(width), 10) | ||||
| 		} | ||||
| 		if okP { | ||||
| 			format = append(format, '.') | ||||
| 			format = strconv.AppendInt(format, int64(prec), 10) | ||||
| 		} | ||||
| 		format = append(format, string(verb)...) | ||||
| 		fmt.Fprintf(s, string(format), p.buf.String()) | ||||
| 	} else { | ||||
| 		io.Copy(s, &p.buf) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var detailSep = []byte("\n    ") | ||||
|  | ||||
| // state tracks error printing state. It implements fmt.State. | ||||
| type state struct { | ||||
| 	fmt.State | ||||
| 	buf bytes.Buffer | ||||
|  | ||||
| 	printDetail bool | ||||
| 	inDetail    bool | ||||
| 	needColon   bool | ||||
| 	needNewline bool | ||||
| } | ||||
|  | ||||
| func (s *state) Write(b []byte) (n int, err error) { | ||||
| 	if s.printDetail { | ||||
| 		if len(b) == 0 { | ||||
| 			return 0, nil | ||||
| 		} | ||||
| 		if s.inDetail && s.needColon { | ||||
| 			s.needNewline = true | ||||
| 			if b[0] == '\n' { | ||||
| 				b = b[1:] | ||||
| 			} | ||||
| 		} | ||||
| 		k := 0 | ||||
| 		for i, c := range b { | ||||
| 			if s.needNewline { | ||||
| 				if s.inDetail && s.needColon { | ||||
| 					s.buf.WriteByte(':') | ||||
| 					s.needColon = false | ||||
| 				} | ||||
| 				s.buf.Write(detailSep) | ||||
| 				s.needNewline = false | ||||
| 			} | ||||
| 			if c == '\n' { | ||||
| 				s.buf.Write(b[k:i]) | ||||
| 				k = i + 1 | ||||
| 				s.needNewline = true | ||||
| 			} | ||||
| 		} | ||||
| 		s.buf.Write(b[k:]) | ||||
| 		if !s.inDetail { | ||||
| 			s.needColon = true | ||||
| 		} | ||||
| 	} else if !s.inDetail { | ||||
| 		s.buf.Write(b) | ||||
| 	} | ||||
| 	return len(b), nil | ||||
| } | ||||
|  | ||||
| // printer wraps a state to implement an xerrors.Printer. | ||||
| type printer state | ||||
|  | ||||
| func (s *printer) Print(args ...interface{}) { | ||||
| 	if !s.inDetail || s.printDetail { | ||||
| 		fmt.Fprint((*state)(s), args...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *printer) Printf(format string, args ...interface{}) { | ||||
| 	if !s.inDetail || s.printDetail { | ||||
| 		fmt.Fprintf((*state)(s), format, args...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *printer) Detail() bool { | ||||
| 	s.inDetail = true | ||||
| 	return s.printDetail | ||||
| } | ||||
							
								
								
									
										1
									
								
								vendor/golang.org/x/xerrors/codereview.cfg
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/golang.org/x/xerrors/codereview.cfg
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1 +0,0 @@ | ||||
| issuerepo: golang/go | ||||
							
								
								
									
										22
									
								
								vendor/golang.org/x/xerrors/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/golang.org/x/xerrors/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,22 +0,0 @@ | ||||
| // Copyright 2019 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // Package xerrors implements functions to manipulate errors. | ||||
| // | ||||
| // This package is based on the Go 2 proposal for error values: | ||||
| //   https://golang.org/design/29934-error-values | ||||
| // | ||||
| // These functions were incorporated into the standard library's errors package | ||||
| // in Go 1.13: | ||||
| // - Is | ||||
| // - As | ||||
| // - Unwrap | ||||
| // | ||||
| // Also, Errorf's %w verb was incorporated into fmt.Errorf. | ||||
| // | ||||
| // Use this package to get equivalent behavior in all supported Go versions. | ||||
| // | ||||
| // No other features of this package were included in Go 1.13, and at present | ||||
| // there are no plans to include any of them. | ||||
| package xerrors // import "golang.org/x/xerrors" | ||||
							
								
								
									
										33
									
								
								vendor/golang.org/x/xerrors/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/golang.org/x/xerrors/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,33 +0,0 @@ | ||||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package xerrors | ||||
|  | ||||
| import "fmt" | ||||
|  | ||||
| // errorString is a trivial implementation of error. | ||||
| type errorString struct { | ||||
| 	s     string | ||||
| 	frame Frame | ||||
| } | ||||
|  | ||||
| // New returns an error that formats as the given text. | ||||
| // | ||||
| // The returned error contains a Frame set to the caller's location and | ||||
| // implements Formatter to show this information when printed with details. | ||||
| func New(text string) error { | ||||
| 	return &errorString{text, Caller(1)} | ||||
| } | ||||
|  | ||||
| func (e *errorString) Error() string { | ||||
| 	return e.s | ||||
| } | ||||
|  | ||||
| func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) } | ||||
|  | ||||
| func (e *errorString) FormatError(p Printer) (next error) { | ||||
| 	p.Print(e.s) | ||||
| 	e.frame.Format(p) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										187
									
								
								vendor/golang.org/x/xerrors/fmt.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										187
									
								
								vendor/golang.org/x/xerrors/fmt.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,187 +0,0 @@ | ||||
| // Copyright 2018 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package xerrors | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"unicode" | ||||
| 	"unicode/utf8" | ||||
|  | ||||
| 	"golang.org/x/xerrors/internal" | ||||
| ) | ||||
|  | ||||
| const percentBangString = "%!" | ||||
|  | ||||
| // Errorf formats according to a format specifier and returns the string as a | ||||
| // value that satisfies error. | ||||
| // | ||||
| // The returned error includes the file and line number of the caller when | ||||
| // formatted with additional detail enabled. If the last argument is an error | ||||
| // the returned error's Format method will return it if the format string ends | ||||
| // with ": %s", ": %v", or ": %w". If the last argument is an error and the | ||||
| // format string ends with ": %w", the returned error implements an Unwrap | ||||
| // method returning it. | ||||
| // | ||||
| // If the format specifier includes a %w verb with an error operand in a | ||||
| // position other than at the end, the returned error will still implement an | ||||
| // Unwrap method returning the operand, but the error's Format method will not | ||||
| // return the wrapped error. | ||||
| // | ||||
| // It is invalid to include more than one %w verb or to supply it with an | ||||
| // operand that does not implement the error interface. The %w verb is otherwise | ||||
| // a synonym for %v. | ||||
| func Errorf(format string, a ...interface{}) error { | ||||
| 	format = formatPlusW(format) | ||||
| 	// Support a ": %[wsv]" suffix, which works well with xerrors.Formatter. | ||||
| 	wrap := strings.HasSuffix(format, ": %w") | ||||
| 	idx, format2, ok := parsePercentW(format) | ||||
| 	percentWElsewhere := !wrap && idx >= 0 | ||||
| 	if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) { | ||||
| 		err := errorAt(a, len(a)-1) | ||||
| 		if err == nil { | ||||
| 			return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)} | ||||
| 		} | ||||
| 		// TODO: this is not entirely correct. The error value could be | ||||
| 		// printed elsewhere in format if it mixes numbered with unnumbered | ||||
| 		// substitutions. With relatively small changes to doPrintf we can | ||||
| 		// have it optionally ignore extra arguments and pass the argument | ||||
| 		// list in its entirety. | ||||
| 		msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...) | ||||
| 		frame := Frame{} | ||||
| 		if internal.EnableTrace { | ||||
| 			frame = Caller(1) | ||||
| 		} | ||||
| 		if wrap { | ||||
| 			return &wrapError{msg, err, frame} | ||||
| 		} | ||||
| 		return &noWrapError{msg, err, frame} | ||||
| 	} | ||||
| 	// Support %w anywhere. | ||||
| 	// TODO: don't repeat the wrapped error's message when %w occurs in the middle. | ||||
| 	msg := fmt.Sprintf(format2, a...) | ||||
| 	if idx < 0 { | ||||
| 		return &noWrapError{msg, nil, Caller(1)} | ||||
| 	} | ||||
| 	err := errorAt(a, idx) | ||||
| 	if !ok || err == nil { | ||||
| 		// Too many %ws or argument of %w is not an error. Approximate the Go | ||||
| 		// 1.13 fmt.Errorf message. | ||||
| 		return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)} | ||||
| 	} | ||||
| 	frame := Frame{} | ||||
| 	if internal.EnableTrace { | ||||
| 		frame = Caller(1) | ||||
| 	} | ||||
| 	return &wrapError{msg, err, frame} | ||||
| } | ||||
|  | ||||
| func errorAt(args []interface{}, i int) error { | ||||
| 	if i < 0 || i >= len(args) { | ||||
| 		return nil | ||||
| 	} | ||||
| 	err, ok := args[i].(error) | ||||
| 	if !ok { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // formatPlusW is used to avoid the vet check that will barf at %w. | ||||
| func formatPlusW(s string) string { | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| // Return the index of the only %w in format, or -1 if none. | ||||
| // Also return a rewritten format string with %w replaced by %v, and | ||||
| // false if there is more than one %w. | ||||
| // TODO: handle "%[N]w". | ||||
| func parsePercentW(format string) (idx int, newFormat string, ok bool) { | ||||
| 	// Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go. | ||||
| 	idx = -1 | ||||
| 	ok = true | ||||
| 	n := 0 | ||||
| 	sz := 0 | ||||
| 	var isW bool | ||||
| 	for i := 0; i < len(format); i += sz { | ||||
| 		if format[i] != '%' { | ||||
| 			sz = 1 | ||||
| 			continue | ||||
| 		} | ||||
| 		// "%%" is not a format directive. | ||||
| 		if i+1 < len(format) && format[i+1] == '%' { | ||||
| 			sz = 2 | ||||
| 			continue | ||||
| 		} | ||||
| 		sz, isW = parsePrintfVerb(format[i:]) | ||||
| 		if isW { | ||||
| 			if idx >= 0 { | ||||
| 				ok = false | ||||
| 			} else { | ||||
| 				idx = n | ||||
| 			} | ||||
| 			// "Replace" the last character, the 'w', with a 'v'. | ||||
| 			p := i + sz - 1 | ||||
| 			format = format[:p] + "v" + format[p+1:] | ||||
| 		} | ||||
| 		n++ | ||||
| 	} | ||||
| 	return idx, format, ok | ||||
| } | ||||
|  | ||||
| // Parse the printf verb starting with a % at s[0]. | ||||
| // Return how many bytes it occupies and whether the verb is 'w'. | ||||
| func parsePrintfVerb(s string) (int, bool) { | ||||
| 	// Assume only that the directive is a sequence of non-letters followed by a single letter. | ||||
| 	sz := 0 | ||||
| 	var r rune | ||||
| 	for i := 1; i < len(s); i += sz { | ||||
| 		r, sz = utf8.DecodeRuneInString(s[i:]) | ||||
| 		if unicode.IsLetter(r) { | ||||
| 			return i + sz, r == 'w' | ||||
| 		} | ||||
| 	} | ||||
| 	return len(s), false | ||||
| } | ||||
|  | ||||
| type noWrapError struct { | ||||
| 	msg   string | ||||
| 	err   error | ||||
| 	frame Frame | ||||
| } | ||||
|  | ||||
| func (e *noWrapError) Error() string { | ||||
| 	return fmt.Sprint(e) | ||||
| } | ||||
|  | ||||
| func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } | ||||
|  | ||||
| func (e *noWrapError) FormatError(p Printer) (next error) { | ||||
| 	p.Print(e.msg) | ||||
| 	e.frame.Format(p) | ||||
| 	return e.err | ||||
| } | ||||
|  | ||||
| type wrapError struct { | ||||
| 	msg   string | ||||
| 	err   error | ||||
| 	frame Frame | ||||
| } | ||||
|  | ||||
| func (e *wrapError) Error() string { | ||||
| 	return fmt.Sprint(e) | ||||
| } | ||||
|  | ||||
| func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } | ||||
|  | ||||
| func (e *wrapError) FormatError(p Printer) (next error) { | ||||
| 	p.Print(e.msg) | ||||
| 	e.frame.Format(p) | ||||
| 	return e.err | ||||
| } | ||||
|  | ||||
| func (e *wrapError) Unwrap() error { | ||||
| 	return e.err | ||||
| } | ||||
							
								
								
									
										34
									
								
								vendor/golang.org/x/xerrors/format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/golang.org/x/xerrors/format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,34 +0,0 @@ | ||||
| // Copyright 2018 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package xerrors | ||||
|  | ||||
| // A Formatter formats error messages. | ||||
| type Formatter interface { | ||||
| 	error | ||||
|  | ||||
| 	// FormatError prints the receiver's first error and returns the next error in | ||||
| 	// the error chain, if any. | ||||
| 	FormatError(p Printer) (next error) | ||||
| } | ||||
|  | ||||
| // A Printer formats error messages. | ||||
| // | ||||
| // The most common implementation of Printer is the one provided by package fmt | ||||
| // during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message | ||||
| // typically provide their own implementations. | ||||
| type Printer interface { | ||||
| 	// Print appends args to the message output. | ||||
| 	Print(args ...interface{}) | ||||
|  | ||||
| 	// Printf writes a formatted string. | ||||
| 	Printf(format string, args ...interface{}) | ||||
|  | ||||
| 	// Detail reports whether error detail is requested. | ||||
| 	// After the first call to Detail, all text written to the Printer | ||||
| 	// is formatted as additional detail, or ignored when | ||||
| 	// detail has not been requested. | ||||
| 	// If Detail returns false, the caller can avoid printing the detail at all. | ||||
| 	Detail() bool | ||||
| } | ||||
							
								
								
									
										56
									
								
								vendor/golang.org/x/xerrors/frame.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/golang.org/x/xerrors/frame.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,56 +0,0 @@ | ||||
| // Copyright 2018 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package xerrors | ||||
|  | ||||
| import ( | ||||
| 	"runtime" | ||||
| ) | ||||
|  | ||||
| // A Frame contains part of a call stack. | ||||
| type Frame struct { | ||||
| 	// Make room for three PCs: the one we were asked for, what it called, | ||||
| 	// and possibly a PC for skipPleaseUseCallersFrames. See: | ||||
| 	// https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169 | ||||
| 	frames [3]uintptr | ||||
| } | ||||
|  | ||||
| // Caller returns a Frame that describes a frame on the caller's stack. | ||||
| // The argument skip is the number of frames to skip over. | ||||
| // Caller(0) returns the frame for the caller of Caller. | ||||
| func Caller(skip int) Frame { | ||||
| 	var s Frame | ||||
| 	runtime.Callers(skip+1, s.frames[:]) | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| // location reports the file, line, and function of a frame. | ||||
| // | ||||
| // The returned function may be "" even if file and line are not. | ||||
| func (f Frame) location() (function, file string, line int) { | ||||
| 	frames := runtime.CallersFrames(f.frames[:]) | ||||
| 	if _, ok := frames.Next(); !ok { | ||||
| 		return "", "", 0 | ||||
| 	} | ||||
| 	fr, ok := frames.Next() | ||||
| 	if !ok { | ||||
| 		return "", "", 0 | ||||
| 	} | ||||
| 	return fr.Function, fr.File, fr.Line | ||||
| } | ||||
|  | ||||
| // Format prints the stack as error detail. | ||||
| // It should be called from an error's Format implementation | ||||
| // after printing any other error detail. | ||||
| func (f Frame) Format(p Printer) { | ||||
| 	if p.Detail() { | ||||
| 		function, file, line := f.location() | ||||
| 		if function != "" { | ||||
| 			p.Printf("%s\n    ", function) | ||||
| 		} | ||||
| 		if file != "" { | ||||
| 			p.Printf("%s:%d\n", file, line) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										8
									
								
								vendor/golang.org/x/xerrors/internal/internal.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/golang.org/x/xerrors/internal/internal.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,8 +0,0 @@ | ||||
| // Copyright 2018 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package internal | ||||
|  | ||||
| // EnableTrace indicates whether stack information should be recorded in errors. | ||||
| var EnableTrace = true | ||||
							
								
								
									
										106
									
								
								vendor/golang.org/x/xerrors/wrap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										106
									
								
								vendor/golang.org/x/xerrors/wrap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,106 +0,0 @@ | ||||
| // Copyright 2018 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package xerrors | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
| ) | ||||
|  | ||||
| // A Wrapper provides context around another error. | ||||
| type Wrapper interface { | ||||
| 	// Unwrap returns the next error in the error chain. | ||||
| 	// If there is no next error, Unwrap returns nil. | ||||
| 	Unwrap() error | ||||
| } | ||||
|  | ||||
| // Opaque returns an error with the same error formatting as err | ||||
| // but that does not match err and cannot be unwrapped. | ||||
| func Opaque(err error) error { | ||||
| 	return noWrapper{err} | ||||
| } | ||||
|  | ||||
| type noWrapper struct { | ||||
| 	error | ||||
| } | ||||
|  | ||||
| func (e noWrapper) FormatError(p Printer) (next error) { | ||||
| 	if f, ok := e.error.(Formatter); ok { | ||||
| 		return f.FormatError(p) | ||||
| 	} | ||||
| 	p.Print(e.error) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Unwrap returns the result of calling the Unwrap method on err, if err implements | ||||
| // Unwrap. Otherwise, Unwrap returns nil. | ||||
| func Unwrap(err error) error { | ||||
| 	u, ok := err.(Wrapper) | ||||
| 	if !ok { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return u.Unwrap() | ||||
| } | ||||
|  | ||||
| // Is reports whether any error in err's chain matches target. | ||||
| // | ||||
| // An error is considered to match a target if it is equal to that target or if | ||||
| // it implements a method Is(error) bool such that Is(target) returns true. | ||||
| func Is(err, target error) bool { | ||||
| 	if target == nil { | ||||
| 		return err == target | ||||
| 	} | ||||
|  | ||||
| 	isComparable := reflect.TypeOf(target).Comparable() | ||||
| 	for { | ||||
| 		if isComparable && err == target { | ||||
| 			return true | ||||
| 		} | ||||
| 		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { | ||||
| 			return true | ||||
| 		} | ||||
| 		// TODO: consider supporing target.Is(err). This would allow | ||||
| 		// user-definable predicates, but also may allow for coping with sloppy | ||||
| 		// APIs, thereby making it easier to get away with them. | ||||
| 		if err = Unwrap(err); err == nil { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // As finds the first error in err's chain that matches the type to which target | ||||
| // points, and if so, sets the target to its value and returns true. An error | ||||
| // matches a type if it is assignable to the target type, or if it has a method | ||||
| // As(interface{}) bool such that As(target) returns true. As will panic if target | ||||
| // is not a non-nil pointer to a type which implements error or is of interface type. | ||||
| // | ||||
| // The As method should set the target to its value and return true if err | ||||
| // matches the type to which target points. | ||||
| func As(err error, target interface{}) bool { | ||||
| 	if target == nil { | ||||
| 		panic("errors: target cannot be nil") | ||||
| 	} | ||||
| 	val := reflect.ValueOf(target) | ||||
| 	typ := val.Type() | ||||
| 	if typ.Kind() != reflect.Ptr || val.IsNil() { | ||||
| 		panic("errors: target must be a non-nil pointer") | ||||
| 	} | ||||
| 	if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) { | ||||
| 		panic("errors: *target must be interface or implement error") | ||||
| 	} | ||||
| 	targetType := typ.Elem() | ||||
| 	for err != nil { | ||||
| 		if reflect.TypeOf(err).AssignableTo(targetType) { | ||||
| 			val.Elem().Set(reflect.ValueOf(err)) | ||||
| 			return true | ||||
| 		} | ||||
| 		if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { | ||||
| 			return true | ||||
| 		} | ||||
| 		err = Unwrap(err) | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| var errorType = reflect.TypeOf((*error)(nil)).Elem() | ||||
							
								
								
									
										13
									
								
								vendor/gotest.tools/v3/LICENSE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/gotest.tools/v3/LICENSE
									
									
									
									
										vendored
									
									
								
							| @@ -1,13 +0,0 @@ | ||||
| Copyright 2018 gotest.tools authors | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
							
								
								
									
										219
									
								
								vendor/gotest.tools/v3/assert/assert.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										219
									
								
								vendor/gotest.tools/v3/assert/assert.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,219 +0,0 @@ | ||||
| /*Package assert provides assertions for comparing expected values to actual | ||||
| values. When an assertion fails a helpful error message is printed. | ||||
|  | ||||
| Assert and Check | ||||
|  | ||||
| Assert() and Check() both accept a Comparison, and fail the test when the | ||||
| comparison fails. The one difference is that Assert() will end the test execution | ||||
| immediately (using t.FailNow()) whereas Check() will fail the test (using t.Fail()), | ||||
| return the value of the comparison, then proceed with the rest of the test case. | ||||
|  | ||||
| Example usage | ||||
|  | ||||
| The example below shows assert used with some common types. | ||||
|  | ||||
|  | ||||
| 	import ( | ||||
| 	    "testing" | ||||
|  | ||||
| 	    "gotest.tools/assert" | ||||
| 	    is "gotest.tools/assert/cmp" | ||||
| 	) | ||||
|  | ||||
| 	func TestEverything(t *testing.T) { | ||||
| 	    // booleans | ||||
| 	    assert.Assert(t, ok) | ||||
| 	    assert.Assert(t, !missing) | ||||
|  | ||||
| 	    // primitives | ||||
| 	    assert.Equal(t, count, 1) | ||||
| 	    assert.Equal(t, msg, "the message") | ||||
| 	    assert.Assert(t, total != 10) // NotEqual | ||||
|  | ||||
| 	    // errors | ||||
| 	    assert.NilError(t, closer.Close()) | ||||
| 	    assert.Error(t, err, "the exact error message") | ||||
| 	    assert.ErrorContains(t, err, "includes this") | ||||
| 	    assert.ErrorType(t, err, os.IsNotExist) | ||||
|  | ||||
| 	    // complex types | ||||
| 	    assert.DeepEqual(t, result, myStruct{Name: "title"}) | ||||
| 	    assert.Assert(t, is.Len(items, 3)) | ||||
| 	    assert.Assert(t, len(sequence) != 0) // NotEmpty | ||||
| 	    assert.Assert(t, is.Contains(mapping, "key")) | ||||
|  | ||||
| 	    // pointers and interface | ||||
| 	    assert.Assert(t, is.Nil(ref)) | ||||
| 	    assert.Assert(t, ref != nil) // NotNil | ||||
| 	} | ||||
|  | ||||
| Comparisons | ||||
|  | ||||
| Package http://pkg.go.dev/gotest.tools/v3/assert/cmp provides | ||||
| many common comparisons. Additional comparisons can be written to compare | ||||
| values in other ways. See the example Assert (CustomComparison). | ||||
|  | ||||
| Automated migration from testify | ||||
|  | ||||
| gty-migrate-from-testify is a command which translates Go source code from | ||||
| testify assertions to the assertions provided by this package. | ||||
|  | ||||
| See http://pkg.go.dev/gotest.tools/v3/assert/cmd/gty-migrate-from-testify. | ||||
|  | ||||
|  | ||||
| */ | ||||
| package assert // import "gotest.tools/v3/assert" | ||||
|  | ||||
| import ( | ||||
| 	gocmp "github.com/google/go-cmp/cmp" | ||||
| 	"gotest.tools/v3/assert/cmp" | ||||
| 	"gotest.tools/v3/internal/assert" | ||||
| ) | ||||
|  | ||||
| // BoolOrComparison can be a bool, or cmp.Comparison. See Assert() for usage. | ||||
| type BoolOrComparison interface{} | ||||
|  | ||||
| // TestingT is the subset of testing.T used by the assert package. | ||||
| type TestingT interface { | ||||
| 	FailNow() | ||||
| 	Fail() | ||||
| 	Log(args ...interface{}) | ||||
| } | ||||
|  | ||||
| type helperT interface { | ||||
| 	Helper() | ||||
| } | ||||
|  | ||||
| // Assert performs a comparison. If the comparison fails, the test is marked as | ||||
| // failed, a failure message is logged, and execution is stopped immediately. | ||||
| // | ||||
| // The comparison argument may be one of three types: | ||||
| //   bool | ||||
| // True is success. False is a failure. | ||||
| // The failure message will contain the literal source code of the expression. | ||||
| //   cmp.Comparison | ||||
| // Uses cmp.Result.Success() to check for success of failure. | ||||
| // The comparison is responsible for producing a helpful failure message. | ||||
| // http://pkg.go.dev/gotest.tools/v3/assert/cmp provides many common comparisons. | ||||
| //   error | ||||
| // A nil value is considered success. | ||||
| // A non-nil error is a failure, err.Error() is used as the failure message. | ||||
| func Assert(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if !assert.Eval(t, assert.ArgsFromComparisonCall, comparison, msgAndArgs...) { | ||||
| 		t.FailNow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Check performs a comparison. If the comparison fails the test is marked as | ||||
| // failed, a failure message is logged, and Check returns false. Otherwise returns | ||||
| // true. | ||||
| // | ||||
| // See Assert for details about the comparison arg and failure messages. | ||||
| func Check(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) bool { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if !assert.Eval(t, assert.ArgsFromComparisonCall, comparison, msgAndArgs...) { | ||||
| 		t.Fail() | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // NilError fails the test immediately if err is not nil. | ||||
| // This is equivalent to Assert(t, err) | ||||
| func NilError(t TestingT, err error, msgAndArgs ...interface{}) { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if !assert.Eval(t, assert.ArgsAfterT, err, msgAndArgs...) { | ||||
| 		t.FailNow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Equal uses the == operator to assert two values are equal and fails the test | ||||
| // if they are not equal. | ||||
| // | ||||
| // If the comparison fails Equal will use the variable names for x and y as part | ||||
| // of the failure message to identify the actual and expected values. | ||||
| // | ||||
| // If either x or y are a multi-line string the failure message will include a | ||||
| // unified diff of the two values. If the values only differ by whitespace | ||||
| // the unified diff will be augmented by replacing whitespace characters with | ||||
| // visible characters to identify the whitespace difference. | ||||
| // | ||||
| // This is equivalent to Assert(t, cmp.Equal(x, y)). | ||||
| func Equal(t TestingT, x, y interface{}, msgAndArgs ...interface{}) { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if !assert.Eval(t, assert.ArgsAfterT, cmp.Equal(x, y), msgAndArgs...) { | ||||
| 		t.FailNow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // DeepEqual uses google/go-cmp (https://godoc.org/github.com/google/go-cmp/cmp) | ||||
| // to assert two values are equal and fails the test if they are not equal. | ||||
| // | ||||
| // Package http://pkg.go.dev/gotest.tools/v3/assert/opt provides some additional | ||||
| // commonly used Options. | ||||
| // | ||||
| // This is equivalent to Assert(t, cmp.DeepEqual(x, y)). | ||||
| func DeepEqual(t TestingT, x, y interface{}, opts ...gocmp.Option) { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if !assert.Eval(t, assert.ArgsAfterT, cmp.DeepEqual(x, y, opts...)) { | ||||
| 		t.FailNow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Error fails the test if err is nil, or the error message is not the expected | ||||
| // message. | ||||
| // Equivalent to Assert(t, cmp.Error(err, message)). | ||||
| func Error(t TestingT, err error, message string, msgAndArgs ...interface{}) { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if !assert.Eval(t, assert.ArgsAfterT, cmp.Error(err, message), msgAndArgs...) { | ||||
| 		t.FailNow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ErrorContains fails the test if err is nil, or the error message does not | ||||
| // contain the expected substring. | ||||
| // Equivalent to Assert(t, cmp.ErrorContains(err, substring)). | ||||
| func ErrorContains(t TestingT, err error, substring string, msgAndArgs ...interface{}) { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if !assert.Eval(t, assert.ArgsAfterT, cmp.ErrorContains(err, substring), msgAndArgs...) { | ||||
| 		t.FailNow() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ErrorType fails the test if err is nil, or err is not the expected type. | ||||
| // Equivalent to Assert(t, cmp.ErrorType(err, expected)). | ||||
| // | ||||
| // Expected can be one of: | ||||
| //   func(error) bool | ||||
| // Function should return true if the error is the expected type. | ||||
| //   type struct{}, type &struct{} | ||||
| // A struct or a pointer to a struct. | ||||
| // Fails if the error is not of the same type as expected. | ||||
| //   type &interface{} | ||||
| // A pointer to an interface type. | ||||
| // Fails if err does not implement the interface. | ||||
| //   reflect.Type | ||||
| // Fails if err does not implement the reflect.Type | ||||
| func ErrorType(t TestingT, err error, expected interface{}, msgAndArgs ...interface{}) { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if !assert.Eval(t, assert.ArgsAfterT, cmp.ErrorType(err, expected), msgAndArgs...) { | ||||
| 		t.FailNow() | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										365
									
								
								vendor/gotest.tools/v3/assert/cmp/compare.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										365
									
								
								vendor/gotest.tools/v3/assert/cmp/compare.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,365 +0,0 @@ | ||||
| /*Package cmp provides Comparisons for Assert and Check*/ | ||||
| package cmp // import "gotest.tools/v3/assert/cmp" | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
| 	"gotest.tools/v3/internal/format" | ||||
| ) | ||||
|  | ||||
| // Comparison is a function which compares values and returns ResultSuccess if | ||||
| // the actual value matches the expected value. If the values do not match the | ||||
| // Result will contain a message about why it failed. | ||||
| type Comparison func() Result | ||||
|  | ||||
| // DeepEqual compares two values using google/go-cmp | ||||
| // (https://godoc.org/github.com/google/go-cmp/cmp) | ||||
| // and succeeds if the values are equal. | ||||
| // | ||||
| // The comparison can be customized using comparison Options. | ||||
| // Package http://pkg.go.dev/gotest.tools/v3/assert/opt provides some additional | ||||
| // commonly used Options. | ||||
| func DeepEqual(x, y interface{}, opts ...cmp.Option) Comparison { | ||||
| 	return func() (result Result) { | ||||
| 		defer func() { | ||||
| 			if panicmsg, handled := handleCmpPanic(recover()); handled { | ||||
| 				result = ResultFailure(panicmsg) | ||||
| 			} | ||||
| 		}() | ||||
| 		diff := cmp.Diff(x, y, opts...) | ||||
| 		if diff == "" { | ||||
| 			return ResultSuccess | ||||
| 		} | ||||
| 		return multiLineDiffResult(diff) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func handleCmpPanic(r interface{}) (string, bool) { | ||||
| 	if r == nil { | ||||
| 		return "", false | ||||
| 	} | ||||
| 	panicmsg, ok := r.(string) | ||||
| 	if !ok { | ||||
| 		panic(r) | ||||
| 	} | ||||
| 	switch { | ||||
| 	case strings.HasPrefix(panicmsg, "cannot handle unexported field"): | ||||
| 		return panicmsg, true | ||||
| 	} | ||||
| 	panic(r) | ||||
| } | ||||
|  | ||||
| func toResult(success bool, msg string) Result { | ||||
| 	if success { | ||||
| 		return ResultSuccess | ||||
| 	} | ||||
| 	return ResultFailure(msg) | ||||
| } | ||||
|  | ||||
| // RegexOrPattern may be either a *regexp.Regexp or a string that is a valid | ||||
| // regexp pattern. | ||||
| type RegexOrPattern interface{} | ||||
|  | ||||
| // Regexp succeeds if value v matches regular expression re. | ||||
| // | ||||
| // Example: | ||||
| //   assert.Assert(t, cmp.Regexp("^[0-9a-f]{32}$", str)) | ||||
| //   r := regexp.MustCompile("^[0-9a-f]{32}$") | ||||
| //   assert.Assert(t, cmp.Regexp(r, str)) | ||||
| func Regexp(re RegexOrPattern, v string) Comparison { | ||||
| 	match := func(re *regexp.Regexp) Result { | ||||
| 		return toResult( | ||||
| 			re.MatchString(v), | ||||
| 			fmt.Sprintf("value %q does not match regexp %q", v, re.String())) | ||||
| 	} | ||||
|  | ||||
| 	return func() Result { | ||||
| 		switch regex := re.(type) { | ||||
| 		case *regexp.Regexp: | ||||
| 			return match(regex) | ||||
| 		case string: | ||||
| 			re, err := regexp.Compile(regex) | ||||
| 			if err != nil { | ||||
| 				return ResultFailure(err.Error()) | ||||
| 			} | ||||
| 			return match(re) | ||||
| 		default: | ||||
| 			return ResultFailure(fmt.Sprintf("invalid type %T for regex pattern", regex)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Equal succeeds if x == y. See assert.Equal for full documentation. | ||||
| func Equal(x, y interface{}) Comparison { | ||||
| 	return func() Result { | ||||
| 		switch { | ||||
| 		case x == y: | ||||
| 			return ResultSuccess | ||||
| 		case isMultiLineStringCompare(x, y): | ||||
| 			diff := format.UnifiedDiff(format.DiffConfig{A: x.(string), B: y.(string)}) | ||||
| 			return multiLineDiffResult(diff) | ||||
| 		} | ||||
| 		return ResultFailureTemplate(` | ||||
| 			{{- printf "%v" .Data.x}} ( | ||||
| 				{{- with callArg 0 }}{{ formatNode . }} {{end -}} | ||||
| 				{{- printf "%T" .Data.x -}} | ||||
| 			) != {{ printf "%v" .Data.y}} ( | ||||
| 				{{- with callArg 1 }}{{ formatNode . }} {{end -}} | ||||
| 				{{- printf "%T" .Data.y -}} | ||||
| 			)`, | ||||
| 			map[string]interface{}{"x": x, "y": y}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func isMultiLineStringCompare(x, y interface{}) bool { | ||||
| 	strX, ok := x.(string) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	strY, ok := y.(string) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	return strings.Contains(strX, "\n") || strings.Contains(strY, "\n") | ||||
| } | ||||
|  | ||||
| func multiLineDiffResult(diff string) Result { | ||||
| 	return ResultFailureTemplate(` | ||||
| --- {{ with callArg 0 }}{{ formatNode . }}{{else}}←{{end}} | ||||
| +++ {{ with callArg 1 }}{{ formatNode . }}{{else}}→{{end}} | ||||
| {{ .Data.diff }}`, | ||||
| 		map[string]interface{}{"diff": diff}) | ||||
| } | ||||
|  | ||||
| // Len succeeds if the sequence has the expected length. | ||||
| func Len(seq interface{}, expected int) Comparison { | ||||
| 	return func() (result Result) { | ||||
| 		defer func() { | ||||
| 			if e := recover(); e != nil { | ||||
| 				result = ResultFailure(fmt.Sprintf("type %T does not have a length", seq)) | ||||
| 			} | ||||
| 		}() | ||||
| 		value := reflect.ValueOf(seq) | ||||
| 		length := value.Len() | ||||
| 		if length == expected { | ||||
| 			return ResultSuccess | ||||
| 		} | ||||
| 		msg := fmt.Sprintf("expected %s (length %d) to have length %d", seq, length, expected) | ||||
| 		return ResultFailure(msg) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Contains succeeds if item is in collection. Collection may be a string, map, | ||||
| // slice, or array. | ||||
| // | ||||
| // If collection is a string, item must also be a string, and is compared using | ||||
| // strings.Contains(). | ||||
| // If collection is a Map, contains will succeed if item is a key in the map. | ||||
| // If collection is a slice or array, item is compared to each item in the | ||||
| // sequence using reflect.DeepEqual(). | ||||
| func Contains(collection interface{}, item interface{}) Comparison { | ||||
| 	return func() Result { | ||||
| 		colValue := reflect.ValueOf(collection) | ||||
| 		if !colValue.IsValid() { | ||||
| 			return ResultFailure(fmt.Sprintf("nil does not contain items")) | ||||
| 		} | ||||
| 		msg := fmt.Sprintf("%v does not contain %v", collection, item) | ||||
|  | ||||
| 		itemValue := reflect.ValueOf(item) | ||||
| 		switch colValue.Type().Kind() { | ||||
| 		case reflect.String: | ||||
| 			if itemValue.Type().Kind() != reflect.String { | ||||
| 				return ResultFailure("string may only contain strings") | ||||
| 			} | ||||
| 			return toResult( | ||||
| 				strings.Contains(colValue.String(), itemValue.String()), | ||||
| 				fmt.Sprintf("string %q does not contain %q", collection, item)) | ||||
|  | ||||
| 		case reflect.Map: | ||||
| 			if itemValue.Type() != colValue.Type().Key() { | ||||
| 				return ResultFailure(fmt.Sprintf( | ||||
| 					"%v can not contain a %v key", colValue.Type(), itemValue.Type())) | ||||
| 			} | ||||
| 			return toResult(colValue.MapIndex(itemValue).IsValid(), msg) | ||||
|  | ||||
| 		case reflect.Slice, reflect.Array: | ||||
| 			for i := 0; i < colValue.Len(); i++ { | ||||
| 				if reflect.DeepEqual(colValue.Index(i).Interface(), item) { | ||||
| 					return ResultSuccess | ||||
| 				} | ||||
| 			} | ||||
| 			return ResultFailure(msg) | ||||
| 		default: | ||||
| 			return ResultFailure(fmt.Sprintf("type %T does not contain items", collection)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Panics succeeds if f() panics. | ||||
| func Panics(f func()) Comparison { | ||||
| 	return func() (result Result) { | ||||
| 		defer func() { | ||||
| 			if err := recover(); err != nil { | ||||
| 				result = ResultSuccess | ||||
| 			} | ||||
| 		}() | ||||
| 		f() | ||||
| 		return ResultFailure("did not panic") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Error succeeds if err is a non-nil error, and the error message equals the | ||||
| // expected message. | ||||
| func Error(err error, message string) Comparison { | ||||
| 	return func() Result { | ||||
| 		switch { | ||||
| 		case err == nil: | ||||
| 			return ResultFailure("expected an error, got nil") | ||||
| 		case err.Error() != message: | ||||
| 			return ResultFailure(fmt.Sprintf( | ||||
| 				"expected error %q, got %s", message, formatErrorMessage(err))) | ||||
| 		} | ||||
| 		return ResultSuccess | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ErrorContains succeeds if err is a non-nil error, and the error message contains | ||||
| // the expected substring. | ||||
| func ErrorContains(err error, substring string) Comparison { | ||||
| 	return func() Result { | ||||
| 		switch { | ||||
| 		case err == nil: | ||||
| 			return ResultFailure("expected an error, got nil") | ||||
| 		case !strings.Contains(err.Error(), substring): | ||||
| 			return ResultFailure(fmt.Sprintf( | ||||
| 				"expected error to contain %q, got %s", substring, formatErrorMessage(err))) | ||||
| 		} | ||||
| 		return ResultSuccess | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type causer interface { | ||||
| 	Cause() error | ||||
| } | ||||
|  | ||||
| func formatErrorMessage(err error) string { | ||||
| 	if _, ok := err.(causer); ok { | ||||
| 		return fmt.Sprintf("%q\n%+v", err, err) | ||||
| 	} | ||||
| 	// This error was not wrapped with github.com/pkg/errors | ||||
| 	return fmt.Sprintf("%q", err) | ||||
| } | ||||
|  | ||||
| // Nil succeeds if obj is a nil interface, pointer, or function. | ||||
| // | ||||
| // Use NilError() for comparing errors. Use Len(obj, 0) for comparing slices, | ||||
| // maps, and channels. | ||||
| func Nil(obj interface{}) Comparison { | ||||
| 	msgFunc := func(value reflect.Value) string { | ||||
| 		return fmt.Sprintf("%v (type %s) is not nil", reflect.Indirect(value), value.Type()) | ||||
| 	} | ||||
| 	return isNil(obj, msgFunc) | ||||
| } | ||||
|  | ||||
| func isNil(obj interface{}, msgFunc func(reflect.Value) string) Comparison { | ||||
| 	return func() Result { | ||||
| 		if obj == nil { | ||||
| 			return ResultSuccess | ||||
| 		} | ||||
| 		value := reflect.ValueOf(obj) | ||||
| 		kind := value.Type().Kind() | ||||
| 		if kind >= reflect.Chan && kind <= reflect.Slice { | ||||
| 			if value.IsNil() { | ||||
| 				return ResultSuccess | ||||
| 			} | ||||
| 			return ResultFailure(msgFunc(value)) | ||||
| 		} | ||||
|  | ||||
| 		return ResultFailure(fmt.Sprintf("%v (type %s) can not be nil", value, value.Type())) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ErrorType succeeds if err is not nil and is of the expected type. | ||||
| // | ||||
| // Expected can be one of: | ||||
| //   func(error) bool | ||||
| // Function should return true if the error is the expected type. | ||||
| //   type struct{}, type &struct{} | ||||
| // A struct or a pointer to a struct. | ||||
| // Fails if the error is not of the same type as expected. | ||||
| //   type &interface{} | ||||
| // A pointer to an interface type. | ||||
| // Fails if err does not implement the interface. | ||||
| //   reflect.Type | ||||
| // Fails if err does not implement the reflect.Type | ||||
| func ErrorType(err error, expected interface{}) Comparison { | ||||
| 	return func() Result { | ||||
| 		switch expectedType := expected.(type) { | ||||
| 		case func(error) bool: | ||||
| 			return cmpErrorTypeFunc(err, expectedType) | ||||
| 		case reflect.Type: | ||||
| 			if expectedType.Kind() == reflect.Interface { | ||||
| 				return cmpErrorTypeImplementsType(err, expectedType) | ||||
| 			} | ||||
| 			return cmpErrorTypeEqualType(err, expectedType) | ||||
| 		case nil: | ||||
| 			return ResultFailure(fmt.Sprintf("invalid type for expected: nil")) | ||||
| 		} | ||||
|  | ||||
| 		expectedType := reflect.TypeOf(expected) | ||||
| 		switch { | ||||
| 		case expectedType.Kind() == reflect.Struct, isPtrToStruct(expectedType): | ||||
| 			return cmpErrorTypeEqualType(err, expectedType) | ||||
| 		case isPtrToInterface(expectedType): | ||||
| 			return cmpErrorTypeImplementsType(err, expectedType.Elem()) | ||||
| 		} | ||||
| 		return ResultFailure(fmt.Sprintf("invalid type for expected: %T", expected)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func cmpErrorTypeFunc(err error, f func(error) bool) Result { | ||||
| 	if f(err) { | ||||
| 		return ResultSuccess | ||||
| 	} | ||||
| 	actual := "nil" | ||||
| 	if err != nil { | ||||
| 		actual = fmt.Sprintf("%s (%T)", err, err) | ||||
| 	} | ||||
| 	return ResultFailureTemplate(`error is {{ .Data.actual }} | ||||
| 		{{- with callArg 1 }}, not {{ formatNode . }}{{end -}}`, | ||||
| 		map[string]interface{}{"actual": actual}) | ||||
| } | ||||
|  | ||||
| func cmpErrorTypeEqualType(err error, expectedType reflect.Type) Result { | ||||
| 	if err == nil { | ||||
| 		return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType)) | ||||
| 	} | ||||
| 	errValue := reflect.ValueOf(err) | ||||
| 	if errValue.Type() == expectedType { | ||||
| 		return ResultSuccess | ||||
| 	} | ||||
| 	return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType)) | ||||
| } | ||||
|  | ||||
| func cmpErrorTypeImplementsType(err error, expectedType reflect.Type) Result { | ||||
| 	if err == nil { | ||||
| 		return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType)) | ||||
| 	} | ||||
| 	errValue := reflect.ValueOf(err) | ||||
| 	if errValue.Type().Implements(expectedType) { | ||||
| 		return ResultSuccess | ||||
| 	} | ||||
| 	return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType)) | ||||
| } | ||||
|  | ||||
| func isPtrToInterface(typ reflect.Type) bool { | ||||
| 	return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Interface | ||||
| } | ||||
|  | ||||
| func isPtrToStruct(typ reflect.Type) bool { | ||||
| 	return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct | ||||
| } | ||||
							
								
								
									
										99
									
								
								vendor/gotest.tools/v3/assert/cmp/result.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										99
									
								
								vendor/gotest.tools/v3/assert/cmp/result.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,99 +0,0 @@ | ||||
| package cmp | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"go/ast" | ||||
| 	"text/template" | ||||
|  | ||||
| 	"gotest.tools/v3/internal/source" | ||||
| ) | ||||
|  | ||||
| // A Result of a Comparison. | ||||
| type Result interface { | ||||
| 	Success() bool | ||||
| } | ||||
|  | ||||
| // StringResult is an implementation of Result that reports the error message | ||||
| // string verbatim and does not provide any templating or formatting of the | ||||
| // message. | ||||
| type StringResult struct { | ||||
| 	success bool | ||||
| 	message string | ||||
| } | ||||
|  | ||||
| // Success returns true if the comparison was successful. | ||||
| func (r StringResult) Success() bool { | ||||
| 	return r.success | ||||
| } | ||||
|  | ||||
| // FailureMessage returns the message used to provide additional information | ||||
| // about the failure. | ||||
| func (r StringResult) FailureMessage() string { | ||||
| 	return r.message | ||||
| } | ||||
|  | ||||
| // ResultSuccess is a constant which is returned by a ComparisonWithResult to | ||||
| // indicate success. | ||||
| var ResultSuccess = StringResult{success: true} | ||||
|  | ||||
| // ResultFailure returns a failed Result with a failure message. | ||||
| func ResultFailure(message string) StringResult { | ||||
| 	return StringResult{message: message} | ||||
| } | ||||
|  | ||||
| // ResultFromError returns ResultSuccess if err is nil. Otherwise ResultFailure | ||||
| // is returned with the error message as the failure message. | ||||
| func ResultFromError(err error) Result { | ||||
| 	if err == nil { | ||||
| 		return ResultSuccess | ||||
| 	} | ||||
| 	return ResultFailure(err.Error()) | ||||
| } | ||||
|  | ||||
| type templatedResult struct { | ||||
| 	template string | ||||
| 	data     map[string]interface{} | ||||
| } | ||||
|  | ||||
| func (r templatedResult) Success() bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (r templatedResult) FailureMessage(args []ast.Expr) string { | ||||
| 	msg, err := renderMessage(r, args) | ||||
| 	if err != nil { | ||||
| 		return fmt.Sprintf("failed to render failure message: %s", err) | ||||
| 	} | ||||
| 	return msg | ||||
| } | ||||
|  | ||||
| // ResultFailureTemplate returns a Result with a template string and data which | ||||
| // can be used to format a failure message. The template may access data from .Data, | ||||
| // the comparison args with the callArg function, and the formatNode function may | ||||
| // be used to format the call args. | ||||
| func ResultFailureTemplate(template string, data map[string]interface{}) Result { | ||||
| 	return templatedResult{template: template, data: data} | ||||
| } | ||||
|  | ||||
| func renderMessage(result templatedResult, args []ast.Expr) (string, error) { | ||||
| 	tmpl := template.New("failure").Funcs(template.FuncMap{ | ||||
| 		"formatNode": source.FormatNode, | ||||
| 		"callArg": func(index int) ast.Expr { | ||||
| 			if index >= len(args) { | ||||
| 				return nil | ||||
| 			} | ||||
| 			return args[index] | ||||
| 		}, | ||||
| 	}) | ||||
| 	var err error | ||||
| 	tmpl, err = tmpl.Parse(result.template) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	err = tmpl.Execute(buf, map[string]interface{}{ | ||||
| 		"Data": result.data, | ||||
| 	}) | ||||
| 	return buf.String(), err | ||||
| } | ||||
							
								
								
									
										143
									
								
								vendor/gotest.tools/v3/internal/assert/assert.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										143
									
								
								vendor/gotest.tools/v3/internal/assert/assert.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,143 +0,0 @@ | ||||
| package assert | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"go/ast" | ||||
| 	"go/token" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"gotest.tools/v3/assert/cmp" | ||||
| 	"gotest.tools/v3/internal/format" | ||||
| 	"gotest.tools/v3/internal/source" | ||||
| ) | ||||
|  | ||||
| // LogT is the subset of testing.T used by the assert package. | ||||
| type LogT interface { | ||||
| 	Log(args ...interface{}) | ||||
| } | ||||
|  | ||||
| type helperT interface { | ||||
| 	Helper() | ||||
| } | ||||
|  | ||||
| const failureMessage = "assertion failed: " | ||||
|  | ||||
| // Eval the comparison and print a failure messages if the comparison has failed. | ||||
| // nolint: gocyclo | ||||
| func Eval( | ||||
| 	t LogT, | ||||
| 	argSelector argSelector, | ||||
| 	comparison interface{}, | ||||
| 	msgAndArgs ...interface{}, | ||||
| ) bool { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	var success bool | ||||
| 	switch check := comparison.(type) { | ||||
| 	case bool: | ||||
| 		if check { | ||||
| 			return true | ||||
| 		} | ||||
| 		logFailureFromBool(t, msgAndArgs...) | ||||
|  | ||||
| 	// Undocumented legacy comparison without Result type | ||||
| 	case func() (success bool, message string): | ||||
| 		success = runCompareFunc(t, check, msgAndArgs...) | ||||
|  | ||||
| 	case nil: | ||||
| 		return true | ||||
|  | ||||
| 	case error: | ||||
| 		msg := failureMsgFromError(check) | ||||
| 		t.Log(format.WithCustomMessage(failureMessage+msg, msgAndArgs...)) | ||||
|  | ||||
| 	case cmp.Comparison: | ||||
| 		success = RunComparison(t, argSelector, check, msgAndArgs...) | ||||
|  | ||||
| 	case func() cmp.Result: | ||||
| 		success = RunComparison(t, argSelector, check, msgAndArgs...) | ||||
|  | ||||
| 	default: | ||||
| 		t.Log(fmt.Sprintf("invalid Comparison: %v (%T)", check, check)) | ||||
| 	} | ||||
| 	return success | ||||
| } | ||||
|  | ||||
| func runCompareFunc( | ||||
| 	t LogT, | ||||
| 	f func() (success bool, message string), | ||||
| 	msgAndArgs ...interface{}, | ||||
| ) bool { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	if success, message := f(); !success { | ||||
| 		t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...)) | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func logFailureFromBool(t LogT, msgAndArgs ...interface{}) { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	const stackIndex = 3 // Assert()/Check(), assert(), logFailureFromBool() | ||||
| 	args, err := source.CallExprArgs(stackIndex) | ||||
| 	if err != nil { | ||||
| 		t.Log(err.Error()) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	const comparisonArgIndex = 1 // Assert(t, comparison) | ||||
| 	if len(args) <= comparisonArgIndex { | ||||
| 		t.Log(failureMessage + "but assert failed to find the expression to print") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	msg, err := boolFailureMessage(args[comparisonArgIndex]) | ||||
| 	if err != nil { | ||||
| 		t.Log(err.Error()) | ||||
| 		msg = "expression is false" | ||||
| 	} | ||||
|  | ||||
| 	t.Log(format.WithCustomMessage(failureMessage+msg, msgAndArgs...)) | ||||
| } | ||||
|  | ||||
| func failureMsgFromError(err error) string { | ||||
| 	// Handle errors with non-nil types | ||||
| 	v := reflect.ValueOf(err) | ||||
| 	if v.Kind() == reflect.Ptr && v.IsNil() { | ||||
| 		return fmt.Sprintf("error is not nil: error has type %T", err) | ||||
| 	} | ||||
| 	return "error is not nil: " + err.Error() | ||||
| } | ||||
|  | ||||
| func boolFailureMessage(expr ast.Expr) (string, error) { | ||||
| 	if binaryExpr, ok := expr.(*ast.BinaryExpr); ok && binaryExpr.Op == token.NEQ { | ||||
| 		x, err := source.FormatNode(binaryExpr.X) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		y, err := source.FormatNode(binaryExpr.Y) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		return x + " is " + y, nil | ||||
| 	} | ||||
|  | ||||
| 	if unaryExpr, ok := expr.(*ast.UnaryExpr); ok && unaryExpr.Op == token.NOT { | ||||
| 		x, err := source.FormatNode(unaryExpr.X) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| 		return x + " is true", nil | ||||
| 	} | ||||
|  | ||||
| 	formatted, err := source.FormatNode(expr) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return "expression is false: " + formatted, nil | ||||
| } | ||||
							
								
								
									
										125
									
								
								vendor/gotest.tools/v3/internal/assert/result.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										125
									
								
								vendor/gotest.tools/v3/internal/assert/result.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,125 +0,0 @@ | ||||
| package assert | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"go/ast" | ||||
|  | ||||
| 	"gotest.tools/v3/assert/cmp" | ||||
| 	"gotest.tools/v3/internal/format" | ||||
| 	"gotest.tools/v3/internal/source" | ||||
| ) | ||||
|  | ||||
| // RunComparison and return Comparison.Success. If the comparison fails a messages | ||||
| // will be printed using t.Log. | ||||
| func RunComparison( | ||||
| 	t LogT, | ||||
| 	argSelector argSelector, | ||||
| 	f cmp.Comparison, | ||||
| 	msgAndArgs ...interface{}, | ||||
| ) bool { | ||||
| 	if ht, ok := t.(helperT); ok { | ||||
| 		ht.Helper() | ||||
| 	} | ||||
| 	result := f() | ||||
| 	if result.Success() { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	var message string | ||||
| 	switch typed := result.(type) { | ||||
| 	case resultWithComparisonArgs: | ||||
| 		const stackIndex = 3 // Assert/Check, assert, RunComparison | ||||
| 		args, err := source.CallExprArgs(stackIndex) | ||||
| 		if err != nil { | ||||
| 			t.Log(err.Error()) | ||||
| 		} | ||||
| 		message = typed.FailureMessage(filterPrintableExpr(argSelector(args))) | ||||
| 	case resultBasic: | ||||
| 		message = typed.FailureMessage() | ||||
| 	default: | ||||
| 		message = fmt.Sprintf("comparison returned invalid Result type: %T", result) | ||||
| 	} | ||||
|  | ||||
| 	t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...)) | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| type resultWithComparisonArgs interface { | ||||
| 	FailureMessage(args []ast.Expr) string | ||||
| } | ||||
|  | ||||
| type resultBasic interface { | ||||
| 	FailureMessage() string | ||||
| } | ||||
|  | ||||
| // filterPrintableExpr filters the ast.Expr slice to only include Expr that are | ||||
| // easy to read when printed and contain relevant information to an assertion. | ||||
| // | ||||
| // Ident and SelectorExpr are included because they print nicely and the variable | ||||
| // names may provide additional context to their values. | ||||
| // BasicLit and CompositeLit are excluded because their source is equivalent to | ||||
| // their value, which is already available. | ||||
| // Other types are ignored for now, but could be added if they are relevant. | ||||
| func filterPrintableExpr(args []ast.Expr) []ast.Expr { | ||||
| 	result := make([]ast.Expr, len(args)) | ||||
| 	for i, arg := range args { | ||||
| 		if isShortPrintableExpr(arg) { | ||||
| 			result[i] = arg | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if starExpr, ok := arg.(*ast.StarExpr); ok { | ||||
| 			result[i] = starExpr.X | ||||
| 			continue | ||||
| 		} | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func isShortPrintableExpr(expr ast.Expr) bool { | ||||
| 	switch expr.(type) { | ||||
| 	case *ast.Ident, *ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr: | ||||
| 		return true | ||||
| 	case *ast.BinaryExpr, *ast.UnaryExpr: | ||||
| 		return true | ||||
| 	default: | ||||
| 		// CallExpr, ParenExpr, TypeAssertExpr, KeyValueExpr, StarExpr | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type argSelector func([]ast.Expr) []ast.Expr | ||||
|  | ||||
| // ArgsAfterT selects args starting at position 1. Used when the caller has a | ||||
| // testing.T as the first argument, and the args to select should follow it. | ||||
| func ArgsAfterT(args []ast.Expr) []ast.Expr { | ||||
| 	if len(args) < 1 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return args[1:] | ||||
| } | ||||
|  | ||||
| // ArgsFromComparisonCall selects args from the CallExpression at position 1. | ||||
| // Used when the caller has a testing.T as the first argument, and the args to | ||||
| // select are passed to the cmp.Comparison at position 1. | ||||
| func ArgsFromComparisonCall(args []ast.Expr) []ast.Expr { | ||||
| 	if len(args) <= 1 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	if callExpr, ok := args[1].(*ast.CallExpr); ok { | ||||
| 		return callExpr.Args | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // ArgsAtZeroIndex selects args from the CallExpression at position 1. | ||||
| // Used when the caller accepts a single cmp.Comparison argument. | ||||
| func ArgsAtZeroIndex(args []ast.Expr) []ast.Expr { | ||||
| 	if len(args) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	if callExpr, ok := args[0].(*ast.CallExpr); ok { | ||||
| 		return callExpr.Args | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/gotest.tools/v3/internal/difflib/LICENSE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/gotest.tools/v3/internal/difflib/LICENSE
									
									
									
									
										vendored
									
									
								
							| @@ -1,27 +0,0 @@ | ||||
| Copyright (c) 2013, Patrick Mezard | ||||
| All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
|  | ||||
|     Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|     Redistributions in binary form must reproduce the above copyright | ||||
| notice, this list of conditions and the following disclaimer in the | ||||
| documentation and/or other materials provided with the distribution. | ||||
|     The names of its contributors may not be used to endorse or promote | ||||
| products derived from this software without specific prior written | ||||
| permission. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||||
| IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||||
| TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||||
| PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | ||||
| TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||||
| PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||||
| LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||||
| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										423
									
								
								vendor/gotest.tools/v3/internal/difflib/difflib.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										423
									
								
								vendor/gotest.tools/v3/internal/difflib/difflib.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,423 +0,0 @@ | ||||
| /*Package difflib is a partial port of Python difflib module. | ||||
|  | ||||
| Original source: https://github.com/pmezard/go-difflib | ||||
|  | ||||
| This file is trimmed to only the parts used by this repository. | ||||
| */ | ||||
| package difflib // import "gotest.tools/v3/internal/difflib" | ||||
|  | ||||
| func min(a, b int) int { | ||||
| 	if a < b { | ||||
| 		return a | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| func max(a, b int) int { | ||||
| 	if a > b { | ||||
| 		return a | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // Match stores line numbers of size of match | ||||
| type Match struct { | ||||
| 	A    int | ||||
| 	B    int | ||||
| 	Size int | ||||
| } | ||||
|  | ||||
| // OpCode identifies the type of diff | ||||
| type OpCode struct { | ||||
| 	Tag byte | ||||
| 	I1  int | ||||
| 	I2  int | ||||
| 	J1  int | ||||
| 	J2  int | ||||
| } | ||||
|  | ||||
| // SequenceMatcher compares sequence of strings. The basic | ||||
| // algorithm predates, and is a little fancier than, an algorithm | ||||
| // published in the late 1980's by Ratcliff and Obershelp under the | ||||
| // hyperbolic name "gestalt pattern matching".  The basic idea is to find | ||||
| // the longest contiguous matching subsequence that contains no "junk" | ||||
| // elements (R-O doesn't address junk).  The same idea is then applied | ||||
| // recursively to the pieces of the sequences to the left and to the right | ||||
| // of the matching subsequence.  This does not yield minimal edit | ||||
| // sequences, but does tend to yield matches that "look right" to people. | ||||
| // | ||||
| // SequenceMatcher tries to compute a "human-friendly diff" between two | ||||
| // sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the | ||||
| // longest *contiguous* & junk-free matching subsequence.  That's what | ||||
| // catches peoples' eyes.  The Windows(tm) windiff has another interesting | ||||
| // notion, pairing up elements that appear uniquely in each sequence. | ||||
| // That, and the method here, appear to yield more intuitive difference | ||||
| // reports than does diff.  This method appears to be the least vulnerable | ||||
| // to synching up on blocks of "junk lines", though (like blank lines in | ||||
| // ordinary text files, or maybe "<P>" lines in HTML files).  That may be | ||||
| // because this is the only method of the 3 that has a *concept* of | ||||
| // "junk" <wink>. | ||||
| // | ||||
| // Timing:  Basic R-O is cubic time worst case and quadratic time expected | ||||
| // case.  SequenceMatcher is quadratic time for the worst case and has | ||||
| // expected-case behavior dependent in a complicated way on how many | ||||
| // elements the sequences have in common; best case time is linear. | ||||
| type SequenceMatcher struct { | ||||
| 	a              []string | ||||
| 	b              []string | ||||
| 	b2j            map[string][]int | ||||
| 	IsJunk         func(string) bool | ||||
| 	autoJunk       bool | ||||
| 	bJunk          map[string]struct{} | ||||
| 	matchingBlocks []Match | ||||
| 	fullBCount     map[string]int | ||||
| 	bPopular       map[string]struct{} | ||||
| 	opCodes        []OpCode | ||||
| } | ||||
|  | ||||
| // NewMatcher returns a new SequenceMatcher | ||||
| func NewMatcher(a, b []string) *SequenceMatcher { | ||||
| 	m := SequenceMatcher{autoJunk: true} | ||||
| 	m.SetSeqs(a, b) | ||||
| 	return &m | ||||
| } | ||||
|  | ||||
| // SetSeqs sets two sequences to be compared. | ||||
| func (m *SequenceMatcher) SetSeqs(a, b []string) { | ||||
| 	m.SetSeq1(a) | ||||
| 	m.SetSeq2(b) | ||||
| } | ||||
|  | ||||
| // SetSeq1 sets the first sequence to be compared. The second sequence to be compared is | ||||
| // not changed. | ||||
| // | ||||
| // SequenceMatcher computes and caches detailed information about the second | ||||
| // sequence, so if you want to compare one sequence S against many sequences, | ||||
| // use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other | ||||
| // sequences. | ||||
| // | ||||
| // See also SetSeqs() and SetSeq2(). | ||||
| func (m *SequenceMatcher) SetSeq1(a []string) { | ||||
| 	if &a == &m.a { | ||||
| 		return | ||||
| 	} | ||||
| 	m.a = a | ||||
| 	m.matchingBlocks = nil | ||||
| 	m.opCodes = nil | ||||
| } | ||||
|  | ||||
| // SetSeq2 sets the second sequence to be compared. The first sequence to be compared is | ||||
| // not changed. | ||||
| func (m *SequenceMatcher) SetSeq2(b []string) { | ||||
| 	if &b == &m.b { | ||||
| 		return | ||||
| 	} | ||||
| 	m.b = b | ||||
| 	m.matchingBlocks = nil | ||||
| 	m.opCodes = nil | ||||
| 	m.fullBCount = nil | ||||
| 	m.chainB() | ||||
| } | ||||
|  | ||||
| func (m *SequenceMatcher) chainB() { | ||||
| 	// Populate line -> index mapping | ||||
| 	b2j := map[string][]int{} | ||||
| 	for i, s := range m.b { | ||||
| 		indices := b2j[s] | ||||
| 		indices = append(indices, i) | ||||
| 		b2j[s] = indices | ||||
| 	} | ||||
|  | ||||
| 	// Purge junk elements | ||||
| 	m.bJunk = map[string]struct{}{} | ||||
| 	if m.IsJunk != nil { | ||||
| 		junk := m.bJunk | ||||
| 		for s := range b2j { | ||||
| 			if m.IsJunk(s) { | ||||
| 				junk[s] = struct{}{} | ||||
| 			} | ||||
| 		} | ||||
| 		for s := range junk { | ||||
| 			delete(b2j, s) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Purge remaining popular elements | ||||
| 	popular := map[string]struct{}{} | ||||
| 	n := len(m.b) | ||||
| 	if m.autoJunk && n >= 200 { | ||||
| 		ntest := n/100 + 1 | ||||
| 		for s, indices := range b2j { | ||||
| 			if len(indices) > ntest { | ||||
| 				popular[s] = struct{}{} | ||||
| 			} | ||||
| 		} | ||||
| 		for s := range popular { | ||||
| 			delete(b2j, s) | ||||
| 		} | ||||
| 	} | ||||
| 	m.bPopular = popular | ||||
| 	m.b2j = b2j | ||||
| } | ||||
|  | ||||
| func (m *SequenceMatcher) isBJunk(s string) bool { | ||||
| 	_, ok := m.bJunk[s] | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
| // Find longest matching block in a[alo:ahi] and b[blo:bhi]. | ||||
| // | ||||
| // If IsJunk is not defined: | ||||
| // | ||||
| // Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where | ||||
| //     alo <= i <= i+k <= ahi | ||||
| //     blo <= j <= j+k <= bhi | ||||
| // and for all (i',j',k') meeting those conditions, | ||||
| //     k >= k' | ||||
| //     i <= i' | ||||
| //     and if i == i', j <= j' | ||||
| // | ||||
| // In other words, of all maximal matching blocks, return one that | ||||
| // starts earliest in a, and of all those maximal matching blocks that | ||||
| // start earliest in a, return the one that starts earliest in b. | ||||
| // | ||||
| // If IsJunk is defined, first the longest matching block is | ||||
| // determined as above, but with the additional restriction that no | ||||
| // junk element appears in the block.  Then that block is extended as | ||||
| // far as possible by matching (only) junk elements on both sides.  So | ||||
| // the resulting block never matches on junk except as identical junk | ||||
| // happens to be adjacent to an "interesting" match. | ||||
| // | ||||
| // If no blocks match, return (alo, blo, 0). | ||||
| func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { | ||||
| 	// CAUTION:  stripping common prefix or suffix would be incorrect. | ||||
| 	// E.g., | ||||
| 	//    ab | ||||
| 	//    acab | ||||
| 	// Longest matching block is "ab", but if common prefix is | ||||
| 	// stripped, it's "a" (tied with "b").  UNIX(tm) diff does so | ||||
| 	// strip, so ends up claiming that ab is changed to acab by | ||||
| 	// inserting "ca" in the middle.  That's minimal but unintuitive: | ||||
| 	// "it's obvious" that someone inserted "ac" at the front. | ||||
| 	// Windiff ends up at the same place as diff, but by pairing up | ||||
| 	// the unique 'b's and then matching the first two 'a's. | ||||
| 	besti, bestj, bestsize := alo, blo, 0 | ||||
|  | ||||
| 	// find longest junk-free match | ||||
| 	// during an iteration of the loop, j2len[j] = length of longest | ||||
| 	// junk-free match ending with a[i-1] and b[j] | ||||
| 	j2len := map[int]int{} | ||||
| 	for i := alo; i != ahi; i++ { | ||||
| 		// look at all instances of a[i] in b; note that because | ||||
| 		// b2j has no junk keys, the loop is skipped if a[i] is junk | ||||
| 		newj2len := map[int]int{} | ||||
| 		for _, j := range m.b2j[m.a[i]] { | ||||
| 			// a[i] matches b[j] | ||||
| 			if j < blo { | ||||
| 				continue | ||||
| 			} | ||||
| 			if j >= bhi { | ||||
| 				break | ||||
| 			} | ||||
| 			k := j2len[j-1] + 1 | ||||
| 			newj2len[j] = k | ||||
| 			if k > bestsize { | ||||
| 				besti, bestj, bestsize = i-k+1, j-k+1, k | ||||
| 			} | ||||
| 		} | ||||
| 		j2len = newj2len | ||||
| 	} | ||||
|  | ||||
| 	// Extend the best by non-junk elements on each end.  In particular, | ||||
| 	// "popular" non-junk elements aren't in b2j, which greatly speeds | ||||
| 	// the inner loop above, but also means "the best" match so far | ||||
| 	// doesn't contain any junk *or* popular non-junk elements. | ||||
| 	for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && | ||||
| 		m.a[besti-1] == m.b[bestj-1] { | ||||
| 		besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 | ||||
| 	} | ||||
| 	for besti+bestsize < ahi && bestj+bestsize < bhi && | ||||
| 		!m.isBJunk(m.b[bestj+bestsize]) && | ||||
| 		m.a[besti+bestsize] == m.b[bestj+bestsize] { | ||||
| 		bestsize += 1 | ||||
| 	} | ||||
|  | ||||
| 	// Now that we have a wholly interesting match (albeit possibly | ||||
| 	// empty!), we may as well suck up the matching junk on each | ||||
| 	// side of it too.  Can't think of a good reason not to, and it | ||||
| 	// saves post-processing the (possibly considerable) expense of | ||||
| 	// figuring out what to do with it.  In the case of an empty | ||||
| 	// interesting match, this is clearly the right thing to do, | ||||
| 	// because no other kind of match is possible in the regions. | ||||
| 	for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && | ||||
| 		m.a[besti-1] == m.b[bestj-1] { | ||||
| 		besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 | ||||
| 	} | ||||
| 	for besti+bestsize < ahi && bestj+bestsize < bhi && | ||||
| 		m.isBJunk(m.b[bestj+bestsize]) && | ||||
| 		m.a[besti+bestsize] == m.b[bestj+bestsize] { | ||||
| 		bestsize += 1 | ||||
| 	} | ||||
|  | ||||
| 	return Match{A: besti, B: bestj, Size: bestsize} | ||||
| } | ||||
|  | ||||
| // GetMatchingBlocks returns a list of triples describing matching subsequences. | ||||
| // | ||||
| // Each triple is of the form (i, j, n), and means that | ||||
| // a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in | ||||
| // i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are | ||||
| // adjacent triples in the list, and the second is not the last triple in the | ||||
| // list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe | ||||
| // adjacent equal blocks. | ||||
| // | ||||
| // The last triple is a dummy, (len(a), len(b), 0), and is the only | ||||
| // triple with n==0. | ||||
| func (m *SequenceMatcher) GetMatchingBlocks() []Match { | ||||
| 	if m.matchingBlocks != nil { | ||||
| 		return m.matchingBlocks | ||||
| 	} | ||||
|  | ||||
| 	var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match | ||||
| 	matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { | ||||
| 		match := m.findLongestMatch(alo, ahi, blo, bhi) | ||||
| 		i, j, k := match.A, match.B, match.Size | ||||
| 		if match.Size > 0 { | ||||
| 			if alo < i && blo < j { | ||||
| 				matched = matchBlocks(alo, i, blo, j, matched) | ||||
| 			} | ||||
| 			matched = append(matched, match) | ||||
| 			if i+k < ahi && j+k < bhi { | ||||
| 				matched = matchBlocks(i+k, ahi, j+k, bhi, matched) | ||||
| 			} | ||||
| 		} | ||||
| 		return matched | ||||
| 	} | ||||
| 	matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) | ||||
|  | ||||
| 	// It's possible that we have adjacent equal blocks in the | ||||
| 	// matching_blocks list now. | ||||
| 	nonAdjacent := []Match{} | ||||
| 	i1, j1, k1 := 0, 0, 0 | ||||
| 	for _, b := range matched { | ||||
| 		// Is this block adjacent to i1, j1, k1? | ||||
| 		i2, j2, k2 := b.A, b.B, b.Size | ||||
| 		if i1+k1 == i2 && j1+k1 == j2 { | ||||
| 			// Yes, so collapse them -- this just increases the length of | ||||
| 			// the first block by the length of the second, and the first | ||||
| 			// block so lengthened remains the block to compare against. | ||||
| 			k1 += k2 | ||||
| 		} else { | ||||
| 			// Not adjacent.  Remember the first block (k1==0 means it's | ||||
| 			// the dummy we started with), and make the second block the | ||||
| 			// new block to compare against. | ||||
| 			if k1 > 0 { | ||||
| 				nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) | ||||
| 			} | ||||
| 			i1, j1, k1 = i2, j2, k2 | ||||
| 		} | ||||
| 	} | ||||
| 	if k1 > 0 { | ||||
| 		nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) | ||||
| 	} | ||||
|  | ||||
| 	nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) | ||||
| 	m.matchingBlocks = nonAdjacent | ||||
| 	return m.matchingBlocks | ||||
| } | ||||
|  | ||||
| // GetOpCodes returns a list of 5-tuples describing how to turn a into b. | ||||
| // | ||||
| // Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple | ||||
| // has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the | ||||
| // tuple preceding it, and likewise for j1 == the previous j2. | ||||
| // | ||||
| // The tags are characters, with these meanings: | ||||
| // | ||||
| // 'r' (replace):  a[i1:i2] should be replaced by b[j1:j2] | ||||
| // | ||||
| // 'd' (delete):   a[i1:i2] should be deleted, j1==j2 in this case. | ||||
| // | ||||
| // 'i' (insert):   b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. | ||||
| // | ||||
| // 'e' (equal):    a[i1:i2] == b[j1:j2] | ||||
| func (m *SequenceMatcher) GetOpCodes() []OpCode { | ||||
| 	if m.opCodes != nil { | ||||
| 		return m.opCodes | ||||
| 	} | ||||
| 	i, j := 0, 0 | ||||
| 	matching := m.GetMatchingBlocks() | ||||
| 	opCodes := make([]OpCode, 0, len(matching)) | ||||
| 	for _, m := range matching { | ||||
| 		//  invariant:  we've pumped out correct diffs to change | ||||
| 		//  a[:i] into b[:j], and the next matching block is | ||||
| 		//  a[ai:ai+size] == b[bj:bj+size]. So we need to pump | ||||
| 		//  out a diff to change a[i:ai] into b[j:bj], pump out | ||||
| 		//  the matching block, and move (i,j) beyond the match | ||||
| 		ai, bj, size := m.A, m.B, m.Size | ||||
| 		tag := byte(0) | ||||
| 		if i < ai && j < bj { | ||||
| 			tag = 'r' | ||||
| 		} else if i < ai { | ||||
| 			tag = 'd' | ||||
| 		} else if j < bj { | ||||
| 			tag = 'i' | ||||
| 		} | ||||
| 		if tag > 0 { | ||||
| 			opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) | ||||
| 		} | ||||
| 		i, j = ai+size, bj+size | ||||
| 		// the list of matching blocks is terminated by a | ||||
| 		// sentinel with size 0 | ||||
| 		if size > 0 { | ||||
| 			opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) | ||||
| 		} | ||||
| 	} | ||||
| 	m.opCodes = opCodes | ||||
| 	return m.opCodes | ||||
| } | ||||
|  | ||||
| // GetGroupedOpCodes isolates change clusters by eliminating ranges with no changes. | ||||
| // | ||||
| // Return a generator of groups with up to n lines of context. | ||||
| // Each group is in the same format as returned by GetOpCodes(). | ||||
| func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { | ||||
| 	if n < 0 { | ||||
| 		n = 3 | ||||
| 	} | ||||
| 	codes := m.GetOpCodes() | ||||
| 	if len(codes) == 0 { | ||||
| 		codes = []OpCode{{'e', 0, 1, 0, 1}} | ||||
| 	} | ||||
| 	// Fixup leading and trailing groups if they show no changes. | ||||
| 	if codes[0].Tag == 'e' { | ||||
| 		c := codes[0] | ||||
| 		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 | ||||
| 		codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} | ||||
| 	} | ||||
| 	if codes[len(codes)-1].Tag == 'e' { | ||||
| 		c := codes[len(codes)-1] | ||||
| 		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 | ||||
| 		codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} | ||||
| 	} | ||||
| 	nn := n + n | ||||
| 	groups := [][]OpCode{} | ||||
| 	group := []OpCode{} | ||||
| 	for _, c := range codes { | ||||
| 		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 | ||||
| 		// End the current group and start a new one whenever | ||||
| 		// there is a large range with no changes. | ||||
| 		if c.Tag == 'e' && i2-i1 > nn { | ||||
| 			group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), | ||||
| 				j1, min(j2, j1+n)}) | ||||
| 			groups = append(groups, group) | ||||
| 			group = []OpCode{} | ||||
| 			i1, j1 = max(i1, i2-n), max(j1, j2-n) | ||||
| 		} | ||||
| 		group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) | ||||
| 	} | ||||
| 	if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { | ||||
| 		groups = append(groups, group) | ||||
| 	} | ||||
| 	return groups | ||||
| } | ||||
							
								
								
									
										161
									
								
								vendor/gotest.tools/v3/internal/format/diff.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										161
									
								
								vendor/gotest.tools/v3/internal/format/diff.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,161 +0,0 @@ | ||||
| package format | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"unicode" | ||||
|  | ||||
| 	"gotest.tools/v3/internal/difflib" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	contextLines = 2 | ||||
| ) | ||||
|  | ||||
| // DiffConfig for a unified diff | ||||
| type DiffConfig struct { | ||||
| 	A    string | ||||
| 	B    string | ||||
| 	From string | ||||
| 	To   string | ||||
| } | ||||
|  | ||||
| // UnifiedDiff is a modified version of difflib.WriteUnifiedDiff with better | ||||
| // support for showing the whitespace differences. | ||||
| func UnifiedDiff(conf DiffConfig) string { | ||||
| 	a := strings.SplitAfter(conf.A, "\n") | ||||
| 	b := strings.SplitAfter(conf.B, "\n") | ||||
| 	groups := difflib.NewMatcher(a, b).GetGroupedOpCodes(contextLines) | ||||
| 	if len(groups) == 0 { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	writeFormat := func(format string, args ...interface{}) { | ||||
| 		buf.WriteString(fmt.Sprintf(format, args...)) | ||||
| 	} | ||||
| 	writeLine := func(prefix string, s string) { | ||||
| 		buf.WriteString(prefix + s) | ||||
| 	} | ||||
| 	if hasWhitespaceDiffLines(groups, a, b) { | ||||
| 		writeLine = visibleWhitespaceLine(writeLine) | ||||
| 	} | ||||
| 	formatHeader(writeFormat, conf) | ||||
| 	for _, group := range groups { | ||||
| 		formatRangeLine(writeFormat, group) | ||||
| 		for _, opCode := range group { | ||||
| 			in, out := a[opCode.I1:opCode.I2], b[opCode.J1:opCode.J2] | ||||
| 			switch opCode.Tag { | ||||
| 			case 'e': | ||||
| 				formatLines(writeLine, " ", in) | ||||
| 			case 'r': | ||||
| 				formatLines(writeLine, "-", in) | ||||
| 				formatLines(writeLine, "+", out) | ||||
| 			case 'd': | ||||
| 				formatLines(writeLine, "-", in) | ||||
| 			case 'i': | ||||
| 				formatLines(writeLine, "+", out) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return buf.String() | ||||
| } | ||||
|  | ||||
| // hasWhitespaceDiffLines returns true if any diff groups is only different | ||||
| // because of whitespace characters. | ||||
| func hasWhitespaceDiffLines(groups [][]difflib.OpCode, a, b []string) bool { | ||||
| 	for _, group := range groups { | ||||
| 		in, out := new(bytes.Buffer), new(bytes.Buffer) | ||||
| 		for _, opCode := range group { | ||||
| 			if opCode.Tag == 'e' { | ||||
| 				continue | ||||
| 			} | ||||
| 			for _, line := range a[opCode.I1:opCode.I2] { | ||||
| 				in.WriteString(line) | ||||
| 			} | ||||
| 			for _, line := range b[opCode.J1:opCode.J2] { | ||||
| 				out.WriteString(line) | ||||
| 			} | ||||
| 		} | ||||
| 		if removeWhitespace(in.String()) == removeWhitespace(out.String()) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func removeWhitespace(s string) string { | ||||
| 	var result []rune | ||||
| 	for _, r := range s { | ||||
| 		if !unicode.IsSpace(r) { | ||||
| 			result = append(result, r) | ||||
| 		} | ||||
| 	} | ||||
| 	return string(result) | ||||
| } | ||||
|  | ||||
| func visibleWhitespaceLine(ws func(string, string)) func(string, string) { | ||||
| 	mapToVisibleSpace := func(r rune) rune { | ||||
| 		switch r { | ||||
| 		case '\n': | ||||
| 		case ' ': | ||||
| 			return '·' | ||||
| 		case '\t': | ||||
| 			return '▷' | ||||
| 		case '\v': | ||||
| 			return '▽' | ||||
| 		case '\r': | ||||
| 			return '↵' | ||||
| 		case '\f': | ||||
| 			return '↓' | ||||
| 		default: | ||||
| 			if unicode.IsSpace(r) { | ||||
| 				return '<27>' | ||||
| 			} | ||||
| 		} | ||||
| 		return r | ||||
| 	} | ||||
| 	return func(prefix, s string) { | ||||
| 		ws(prefix, strings.Map(mapToVisibleSpace, s)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func formatHeader(wf func(string, ...interface{}), conf DiffConfig) { | ||||
| 	if conf.From != "" || conf.To != "" { | ||||
| 		wf("--- %s\n", conf.From) | ||||
| 		wf("+++ %s\n", conf.To) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func formatRangeLine(wf func(string, ...interface{}), group []difflib.OpCode) { | ||||
| 	first, last := group[0], group[len(group)-1] | ||||
| 	range1 := formatRangeUnified(first.I1, last.I2) | ||||
| 	range2 := formatRangeUnified(first.J1, last.J2) | ||||
| 	wf("@@ -%s +%s @@\n", range1, range2) | ||||
| } | ||||
|  | ||||
| // Convert range to the "ed" format | ||||
| func formatRangeUnified(start, stop int) string { | ||||
| 	// Per the diff spec at http://www.unix.org/single_unix_specification/ | ||||
| 	beginning := start + 1 // lines start numbering with one | ||||
| 	length := stop - start | ||||
| 	if length == 1 { | ||||
| 		return fmt.Sprintf("%d", beginning) | ||||
| 	} | ||||
| 	if length == 0 { | ||||
| 		beginning-- // empty ranges begin at line just before the range | ||||
| 	} | ||||
| 	return fmt.Sprintf("%d,%d", beginning, length) | ||||
| } | ||||
|  | ||||
| func formatLines(writeLine func(string, string), prefix string, lines []string) { | ||||
| 	for _, line := range lines { | ||||
| 		writeLine(prefix, line) | ||||
| 	} | ||||
| 	// Add a newline if the last line is missing one so that the diff displays | ||||
| 	// properly. | ||||
| 	if !strings.HasSuffix(lines[len(lines)-1], "\n") { | ||||
| 		writeLine("", "\n") | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/gotest.tools/v3/internal/format/format.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/gotest.tools/v3/internal/format/format.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,27 +0,0 @@ | ||||
| package format // import "gotest.tools/v3/internal/format" | ||||
|  | ||||
| import "fmt" | ||||
|  | ||||
| // Message accepts a msgAndArgs varargs and formats it using fmt.Sprintf | ||||
| func Message(msgAndArgs ...interface{}) string { | ||||
| 	switch len(msgAndArgs) { | ||||
| 	case 0: | ||||
| 		return "" | ||||
| 	case 1: | ||||
| 		return fmt.Sprintf("%v", msgAndArgs[0]) | ||||
| 	default: | ||||
| 		return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WithCustomMessage accepts one or two messages and formats them appropriately | ||||
| func WithCustomMessage(source string, msgAndArgs ...interface{}) string { | ||||
| 	custom := Message(msgAndArgs...) | ||||
| 	switch { | ||||
| 	case custom == "": | ||||
| 		return source | ||||
| 	case source == "": | ||||
| 		return custom | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s: %s", source, custom) | ||||
| } | ||||
							
								
								
									
										53
									
								
								vendor/gotest.tools/v3/internal/source/defers.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								vendor/gotest.tools/v3/internal/source/defers.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,53 +0,0 @@ | ||||
| package source | ||||
|  | ||||
| import ( | ||||
| 	"go/ast" | ||||
| 	"go/token" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func scanToDeferLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node { | ||||
| 	var matchedNode ast.Node | ||||
| 	ast.Inspect(node, func(node ast.Node) bool { | ||||
| 		switch { | ||||
| 		case node == nil || matchedNode != nil: | ||||
| 			return false | ||||
| 		case fileset.Position(node.End()).Line == lineNum: | ||||
| 			if funcLit, ok := node.(*ast.FuncLit); ok { | ||||
| 				matchedNode = funcLit | ||||
| 				return false | ||||
| 			} | ||||
| 		} | ||||
| 		return true | ||||
| 	}) | ||||
| 	debug("defer line node: %s", debugFormatNode{matchedNode}) | ||||
| 	return matchedNode | ||||
| } | ||||
|  | ||||
| func guessDefer(node ast.Node) (ast.Node, error) { | ||||
| 	defers := collectDefers(node) | ||||
| 	switch len(defers) { | ||||
| 	case 0: | ||||
| 		return nil, errors.New("failed to expression in defer") | ||||
| 	case 1: | ||||
| 		return defers[0].Call, nil | ||||
| 	default: | ||||
| 		return nil, errors.Errorf( | ||||
| 			"ambiguous call expression: multiple (%d) defers in call block", | ||||
| 			len(defers)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func collectDefers(node ast.Node) []*ast.DeferStmt { | ||||
| 	var defers []*ast.DeferStmt | ||||
| 	ast.Inspect(node, func(node ast.Node) bool { | ||||
| 		if d, ok := node.(*ast.DeferStmt); ok { | ||||
| 			defers = append(defers, d) | ||||
| 			debug("defer: %s", debugFormatNode{d}) | ||||
| 			return false | ||||
| 		} | ||||
| 		return true | ||||
| 	}) | ||||
| 	return defers | ||||
| } | ||||
							
								
								
									
										181
									
								
								vendor/gotest.tools/v3/internal/source/source.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										181
									
								
								vendor/gotest.tools/v3/internal/source/source.go
									
									
									
									
										vendored
									
									
								
							| @@ -1,181 +0,0 @@ | ||||
| package source // import "gotest.tools/v3/internal/source" | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"go/ast" | ||||
| 	"go/format" | ||||
| 	"go/parser" | ||||
| 	"go/token" | ||||
| 	"os" | ||||
| 	"runtime" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| const baseStackIndex = 1 | ||||
|  | ||||
| // FormattedCallExprArg returns the argument from an ast.CallExpr at the | ||||
| // index in the call stack. The argument is formatted using FormatNode. | ||||
| func FormattedCallExprArg(stackIndex int, argPos int) (string, error) { | ||||
| 	args, err := CallExprArgs(stackIndex + 1) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	if argPos >= len(args) { | ||||
| 		return "", errors.New("failed to find expression") | ||||
| 	} | ||||
| 	return FormatNode(args[argPos]) | ||||
| } | ||||
|  | ||||
| // CallExprArgs returns the ast.Expr slice for the args of an ast.CallExpr at | ||||
| // the index in the call stack. | ||||
| func CallExprArgs(stackIndex int) ([]ast.Expr, error) { | ||||
| 	_, filename, lineNum, ok := runtime.Caller(baseStackIndex + stackIndex) | ||||
| 	if !ok { | ||||
| 		return nil, errors.New("failed to get call stack") | ||||
| 	} | ||||
| 	debug("call stack position: %s:%d", filename, lineNum) | ||||
|  | ||||
| 	node, err := getNodeAtLine(filename, lineNum) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	debug("found node: %s", debugFormatNode{node}) | ||||
|  | ||||
| 	return getCallExprArgs(node) | ||||
| } | ||||
|  | ||||
| func getNodeAtLine(filename string, lineNum int) (ast.Node, error) { | ||||
| 	fileset := token.NewFileSet() | ||||
| 	astFile, err := parser.ParseFile(fileset, filename, nil, parser.AllErrors) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrapf(err, "failed to parse source file: %s", filename) | ||||
| 	} | ||||
|  | ||||
| 	if node := scanToLine(fileset, astFile, lineNum); node != nil { | ||||
| 		return node, nil | ||||
| 	} | ||||
| 	if node := scanToDeferLine(fileset, astFile, lineNum); node != nil { | ||||
| 		node, err := guessDefer(node) | ||||
| 		if err != nil || node != nil { | ||||
| 			return node, err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil, errors.Errorf( | ||||
| 		"failed to find an expression on line %d in %s", lineNum, filename) | ||||
| } | ||||
|  | ||||
| func scanToLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node { | ||||
| 	var matchedNode ast.Node | ||||
| 	ast.Inspect(node, func(node ast.Node) bool { | ||||
| 		switch { | ||||
| 		case node == nil || matchedNode != nil: | ||||
| 			return false | ||||
| 		case nodePosition(fileset, node).Line == lineNum: | ||||
| 			matchedNode = node | ||||
| 			return false | ||||
| 		} | ||||
| 		return true | ||||
| 	}) | ||||
| 	return matchedNode | ||||
| } | ||||
|  | ||||
| // In golang 1.9 the line number changed from being the line where the statement | ||||
| // ended to the line where the statement began. | ||||
| func nodePosition(fileset *token.FileSet, node ast.Node) token.Position { | ||||
| 	if goVersionBefore19 { | ||||
| 		return fileset.Position(node.End()) | ||||
| 	} | ||||
| 	return fileset.Position(node.Pos()) | ||||
| } | ||||
|  | ||||
| // GoVersionLessThan returns true if runtime.Version() is semantically less than | ||||
| // version major.minor. Returns false if a release version can not be parsed from | ||||
| // runtime.Version(). | ||||
| func GoVersionLessThan(major, minor int64) bool { | ||||
| 	version := runtime.Version() | ||||
| 	// not a release version | ||||
| 	if !strings.HasPrefix(version, "go") { | ||||
| 		return false | ||||
| 	} | ||||
| 	version = strings.TrimPrefix(version, "go") | ||||
| 	parts := strings.Split(version, ".") | ||||
| 	if len(parts) < 2 { | ||||
| 		return false | ||||
| 	} | ||||
| 	rMajor, err := strconv.ParseInt(parts[0], 10, 32) | ||||
| 	if err != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	if rMajor != major { | ||||
| 		return rMajor < major | ||||
| 	} | ||||
| 	rMinor, err := strconv.ParseInt(parts[1], 10, 32) | ||||
| 	if err != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	return rMinor < minor | ||||
| } | ||||
|  | ||||
| var goVersionBefore19 = GoVersionLessThan(1, 9) | ||||
|  | ||||
| func getCallExprArgs(node ast.Node) ([]ast.Expr, error) { | ||||
| 	visitor := &callExprVisitor{} | ||||
| 	ast.Walk(visitor, node) | ||||
| 	if visitor.expr == nil { | ||||
| 		return nil, errors.New("failed to find call expression") | ||||
| 	} | ||||
| 	debug("callExpr: %s", debugFormatNode{visitor.expr}) | ||||
| 	return visitor.expr.Args, nil | ||||
| } | ||||
|  | ||||
| type callExprVisitor struct { | ||||
| 	expr *ast.CallExpr | ||||
| } | ||||
|  | ||||
| func (v *callExprVisitor) Visit(node ast.Node) ast.Visitor { | ||||
| 	if v.expr != nil || node == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	debug("visit: %s", debugFormatNode{node}) | ||||
|  | ||||
| 	switch typed := node.(type) { | ||||
| 	case *ast.CallExpr: | ||||
| 		v.expr = typed | ||||
| 		return nil | ||||
| 	case *ast.DeferStmt: | ||||
| 		ast.Walk(v, typed.Call.Fun) | ||||
| 		return nil | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| // FormatNode using go/format.Node and return the result as a string | ||||
| func FormatNode(node ast.Node) (string, error) { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	err := format.Node(buf, token.NewFileSet(), node) | ||||
| 	return buf.String(), err | ||||
| } | ||||
|  | ||||
| var debugEnabled = os.Getenv("GOTESTTOOLS_DEBUG") != "" | ||||
|  | ||||
| func debug(format string, args ...interface{}) { | ||||
| 	if debugEnabled { | ||||
| 		fmt.Fprintf(os.Stderr, "DEBUG: "+format+"\n", args...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type debugFormatNode struct { | ||||
| 	ast.Node | ||||
| } | ||||
|  | ||||
| func (n debugFormatNode) String() string { | ||||
| 	out, err := FormatNode(n.Node) | ||||
| 	if err != nil { | ||||
| 		return fmt.Sprintf("failed to format %s: %s", n.Node, err) | ||||
| 	} | ||||
| 	return fmt.Sprintf("(%T) %s", n.Node, out) | ||||
| } | ||||
							
								
								
									
										13
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @@ -243,7 +243,6 @@ github.com/golang/protobuf/ptypes/wrappers | ||||
| # github.com/google/go-cmp v0.5.6 | ||||
| ## explicit; go 1.8 | ||||
| github.com/google/go-cmp/cmp | ||||
| github.com/google/go-cmp/cmp/cmpopts | ||||
| github.com/google/go-cmp/cmp/internal/diff | ||||
| github.com/google/go-cmp/cmp/internal/flags | ||||
| github.com/google/go-cmp/cmp/internal/function | ||||
| @@ -513,10 +512,6 @@ golang.org/x/text/unicode/norm | ||||
| # golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac | ||||
| ## explicit | ||||
| golang.org/x/time/rate | ||||
| # golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 | ||||
| ## explicit; go 1.11 | ||||
| golang.org/x/xerrors | ||||
| golang.org/x/xerrors/internal | ||||
| # google.golang.org/appengine v1.6.7 | ||||
| ## explicit; go 1.11 | ||||
| google.golang.org/appengine/internal | ||||
| @@ -633,14 +628,6 @@ gopkg.in/yaml.v2 | ||||
| # gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b | ||||
| ## explicit | ||||
| gopkg.in/yaml.v3 | ||||
| # gotest.tools/v3 v3.0.3 | ||||
| ## explicit; go 1.11 | ||||
| gotest.tools/v3/assert | ||||
| gotest.tools/v3/assert/cmp | ||||
| gotest.tools/v3/internal/assert | ||||
| gotest.tools/v3/internal/difflib | ||||
| gotest.tools/v3/internal/format | ||||
| gotest.tools/v3/internal/source | ||||
| # k8s.io/api v0.22.5 | ||||
| ## explicit; go 1.16 | ||||
| k8s.io/api/authentication/v1 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Maksym Pavlenko
					Maksym Pavlenko