Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
27ce2d134b | |||
1d7e0dc701 | |||
d5b5c131e7 | |||
623bdbcded | |||
43246d257e | |||
59613e6475 | |||
a9c5c1f2cc | |||
0aada80108 | |||
0e1d0c345a | |||
cbeba830d4 | |||
c77f9dc518 | |||
930e291456 | |||
bc05c16a44 | |||
edde04f62a | |||
f967f4f4a7 | |||
b9f84035b5 | |||
6fdde885e7 | |||
642cbbabd5 | |||
fd35c0dccc | |||
b57a91bda5 | |||
21b64e658e | |||
fc1a89088a | |||
6dca2d6522 | |||
d095180eb4 | |||
17fcd55b85 |
34
.drone.yml
34
.drone.yml
@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: default
|
|
||||||
type: docker
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: fetch
|
|
||||||
image: alpine/git
|
|
||||||
commands:
|
|
||||||
- git fetch --tags
|
|
||||||
|
|
||||||
- name: test
|
|
||||||
image: golang
|
|
||||||
commands:
|
|
||||||
- make test
|
|
||||||
|
|
||||||
- name: lint
|
|
||||||
image: golangci/golangci-lint:v1.31-alpine
|
|
||||||
commands:
|
|
||||||
- apk add --no-cache make
|
|
||||||
- make lint
|
|
||||||
|
|
||||||
- name: release
|
|
||||||
image: golang
|
|
||||||
environment:
|
|
||||||
GITEA_TOKEN:
|
|
||||||
from_secret: gitea_token
|
|
||||||
commands:
|
|
||||||
- curl -sL https://git.io/goreleaser | bash
|
|
||||||
depends_on:
|
|
||||||
- test
|
|
||||||
- lint
|
|
||||||
when:
|
|
||||||
event: tag
|
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,6 @@
|
|||||||
dist/*
|
dist/*
|
||||||
.envrc
|
.envrc
|
||||||
|
coverage.out
|
||||||
|
report.xml
|
||||||
|
.gobin/*
|
||||||
|
.cache/*
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
---
|
|
||||||
gitea_urls:
|
gitea_urls:
|
||||||
api: https://git.xsfx.dev/api/v1/
|
api: https://git.xsfx.dev/api/v1/
|
||||||
|
|
||||||
changelog:
|
changelog:
|
||||||
filters:
|
filters:
|
||||||
exclude:
|
exclude:
|
||||||
- "^Bump version:"
|
- "^Bump version:"
|
||||||
- ^\[NO CHANGELOG\]
|
- ^\[NO CHANGELOG\]
|
||||||
|
- "^chore"
|
||||||
|
- "^ci"
|
||||||
|
- "^build"
|
||||||
builds:
|
builds:
|
||||||
- skip: true
|
- skip: true
|
||||||
|
26
.woodpecker.yml
Normal file
26
.woodpecker.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
pipeline:
|
||||||
|
tags:
|
||||||
|
image: alpine/git
|
||||||
|
commands:
|
||||||
|
- git fetch --tags
|
||||||
|
lint:
|
||||||
|
image: golang:1.18
|
||||||
|
commands:
|
||||||
|
- make lint
|
||||||
|
test:
|
||||||
|
image: golang:1.18
|
||||||
|
commands:
|
||||||
|
- make test
|
||||||
|
build:
|
||||||
|
image: golang:1.18
|
||||||
|
commands:
|
||||||
|
- make build
|
||||||
|
release:
|
||||||
|
image: golang:1.18
|
||||||
|
commands:
|
||||||
|
- make release
|
||||||
|
secrets:
|
||||||
|
- gitea_token
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- tag
|
48
Makefile
48
Makefile
@ -1,7 +1,49 @@
|
|||||||
.PHONY: test lint
|
GO := go
|
||||||
|
|
||||||
|
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||||
|
CACHE_DIR := $(ROOT_DIR)/.cache
|
||||||
|
|
||||||
|
export GOBIN := $(ROOT_DIR)/.gobin
|
||||||
|
export PATH := $(GOBIN):$(PATH)
|
||||||
|
|
||||||
|
GORELEASER := $(GO) run github.com/goreleaser/goreleaser@v1.7.0
|
||||||
|
GOLANGCI_LINT := $(GO) run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.45.0
|
||||||
|
|
||||||
|
GOTESTSUM_URL := gotest.tools/gotestsum@v1.7.0
|
||||||
|
GOTESTSUM := $(GO) run $(GOTESTSUM_URL)
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
go test -v ./...
|
$(GOTESTSUM) \
|
||||||
|
--junitfile report.xml \
|
||||||
|
-- \
|
||||||
|
-race \
|
||||||
|
-cover \
|
||||||
|
-coverprofile=coverage.out \
|
||||||
|
-tags=integration \
|
||||||
|
./... \
|
||||||
|
-timeout=120m
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
lint:
|
lint:
|
||||||
golangci-lint run --enable-all --disable=godox --timeout 10m
|
$(GOLANGCI_LINT) run \
|
||||||
|
--enable-all \
|
||||||
|
--disable=godox,varnamelen \
|
||||||
|
--timeout 10m
|
||||||
|
|
||||||
|
.PHONY: tidy
|
||||||
|
tidy:
|
||||||
|
$(GO) mod tidy
|
||||||
|
$(GO) mod vendor
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build:
|
||||||
|
$(GORELEASER) build --rm-dist --snapshot
|
||||||
|
|
||||||
|
.PHONY: release
|
||||||
|
release:
|
||||||
|
$(GORELEASER) release --rm-dist
|
||||||
|
|
||||||
|
.PHONY: release-snapshot
|
||||||
|
release-snapshot:
|
||||||
|
$(GORELEASER) release --rm-dist --snapshot --skip-publish
|
||||||
|
72
README.md
72
README.md
@ -6,23 +6,77 @@
|
|||||||
|
|
||||||
Just a simple zerolog based request logging http middleware. It also sets a `X-Request-ID` in the request and response headers.
|
Just a simple zerolog based request logging http middleware. It also sets a `X-Request-ID` in the request and response headers.
|
||||||
|
|
||||||
|
Powered by [github.com/rs/zerolog/hlog](https://github.com/rs/zerolog) and [github.com/justinas/alice](https://github.com/justinas/alice).
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
go get -v go.xsfx.dev/logginghandler
|
```shell
|
||||||
|
go get -v go.xsfx.dev/logginghandler
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
handler := logginghandler.Handler(http.HandlerFunc(myHandler))
|
```golang
|
||||||
http.Handle("/", handler)
|
logger := log.With().Logger()
|
||||||
log.Fatal().Msg(http.ListenAndServe(":5000", nil).Error())
|
|
||||||
|
handler := logginghandler.Handler(logger)(
|
||||||
|
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
|
||||||
|
log := logginghander.Logger(r)
|
||||||
|
log.Info().Msg("hello world")
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
|
return
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
http.Handle("/", handler)
|
||||||
|
log.Fatal().Msg(http.ListenAndServe(":5000", nil).Error())
|
||||||
|
```
|
||||||
|
|
||||||
|
or with [alice](https://github.com/justinas/alice)
|
||||||
|
|
||||||
|
```golang
|
||||||
|
logger := log.With().Logger()
|
||||||
|
chain := alice.New(logginghandler.Handler(logger)).Then(
|
||||||
|
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
|
||||||
|
log := logginghander.Logger(r)
|
||||||
|
log.Info().Msg("hello world")
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
|
return
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
http.Handle("/", chain)
|
||||||
|
|
||||||
|
log.Fatal().Err(http.ListenAndServe(":5000", nil)).Msg("goodbye")
|
||||||
|
```
|
||||||
|
|
||||||
In other handlers you can access the UUID:
|
In other handlers you can access the UUID:
|
||||||
|
|
||||||
func anotherHandler(w http.ResponseWriter, r *http.Request) {
|
```golang
|
||||||
fmt.Fprintf(w, "your uuid is: %s", logginghandler.GetUUID(r))
|
func anotherHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
log := logginghandler.FromRequest(r)
|
||||||
|
|
||||||
|
uuid, ok := logginghandler.GetUUID(r)
|
||||||
|
if !ok {
|
||||||
|
log.Error().Err(err).Msg("could not find uuid")
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(w, "your uuid is: %s", uuid)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
The already prepared logger is also available:
|
The already prepared logger is also available:
|
||||||
|
|
||||||
l := logginghandler.Logger(r)
|
```golang
|
||||||
l.Info().Msg("foo bar")
|
l := logginghandler.FromRequest(r)
|
||||||
|
l.Info().Msg("foo bar")
|
||||||
|
```
|
||||||
|
11
go.mod
11
go.mod
@ -3,7 +3,12 @@ module go.xsfx.dev/logginghandler
|
|||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.1.2
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/rs/zerolog v1.20.0
|
github.com/justinas/alice v1.2.0
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/rs/xid v1.3.0
|
||||||
|
github.com/rs/zerolog v1.26.1
|
||||||
|
github.com/stretchr/testify v1.7.0
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
)
|
)
|
||||||
|
57
go.sum
57
go.sum
@ -1,25 +1,56 @@
|
|||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
|
github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo=
|
||||||
|
github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
|
||||||
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4=
|
||||||
github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs=
|
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
|
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
|
||||||
|
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
@ -3,41 +3,105 @@
|
|||||||
package logginghandler
|
package logginghandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/justinas/alice"
|
||||||
|
"github.com/rs/xid"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/hlog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
UUIDKey = "uuid"
|
||||||
|
UUIDHeader = "X-Request-ID"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() { //nolint:gochecknoinits
|
||||||
|
zerolog.DefaultContextLogger = &log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
// GetUUID gets the requests UUID from a request.
|
// GetUUID gets the requests UUID from a request.
|
||||||
func GetUUID(r *http.Request) string {
|
func GetUUID(r *http.Request) (string, bool) {
|
||||||
return r.Header.Get("X-Request-ID")
|
uuid, ok := hlog.IDFromRequest(r)
|
||||||
|
if !ok {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuid.String(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger returns a logger with the UUID set.
|
// FromRequest returns a logger set from request.
|
||||||
func Logger(r *http.Request) zerolog.Logger {
|
// If no one could be found, it will return the global one.
|
||||||
logger := log.With().Str("uuid", GetUUID(r)).Logger()
|
func FromRequest(r *http.Request) *zerolog.Logger {
|
||||||
|
return hlog.FromRequest(r)
|
||||||
return logger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handler is the http middleware handler.
|
// FromCtx returns a logger set from ctx.
|
||||||
func Handler(next http.Handler) http.Handler {
|
// If no one could be found, it will return the global one.
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
func FromCtx(ctx context.Context) *zerolog.Logger {
|
||||||
uuid := uuid.New().String()
|
return zerolog.Ctx(ctx)
|
||||||
r.Header.Set("X-Request-ID", uuid)
|
}
|
||||||
logger := Logger(r)
|
|
||||||
logger.Info().
|
// RequestIDHandler looks in the header for an existing request id. Else it will create one.
|
||||||
Str("method", r.Method).
|
func RequestIDHandler() func(http.Handler) http.Handler {
|
||||||
Str("user-agent", r.UserAgent()).
|
return func(next http.Handler) http.Handler {
|
||||||
Str("proto", r.Proto).
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
Str("referer", r.Referer()).
|
id := r.Header.Get(UUIDHeader)
|
||||||
Str("request-url", r.URL.String()).
|
|
||||||
Str("remote", r.RemoteAddr).
|
if id != "" {
|
||||||
Msg("")
|
ctx := r.Context()
|
||||||
|
|
||||||
w.Header().Set("X-Request-ID", uuid)
|
log := zerolog.Ctx(ctx)
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
})
|
uuid, err := xid.FromString(id)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("couldnt parse uuid")
|
||||||
|
|
||||||
|
hlog.RequestIDHandler(UUIDKey, UUIDHeader)(next).ServeHTTP(w, r)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = hlog.CtxWithID(ctx, uuid)
|
||||||
|
r = r.WithContext(ctx)
|
||||||
|
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(UUIDKey, uuid.String())
|
||||||
|
})
|
||||||
|
|
||||||
|
w.Header().Set(UUIDHeader, uuid.String())
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
} else {
|
||||||
|
hlog.RequestIDHandler(UUIDKey, UUIDHeader)(next).ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handler(log zerolog.Logger) func(http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
chain := alice.New(
|
||||||
|
hlog.NewHandler(log),
|
||||||
|
hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
|
||||||
|
hlog.FromRequest(r).Info().
|
||||||
|
Str("method", r.Method).
|
||||||
|
Str("proto", r.Proto).
|
||||||
|
Stringer("request-url", r.URL).
|
||||||
|
Int("status", status).
|
||||||
|
Int("size", size).
|
||||||
|
Dur("duration", duration).
|
||||||
|
Msg("")
|
||||||
|
}),
|
||||||
|
hlog.RemoteAddrHandler("remote"),
|
||||||
|
hlog.UserAgentHandler("user-agent"),
|
||||||
|
hlog.RefererHandler("referer"),
|
||||||
|
RequestIDHandler(),
|
||||||
|
).Then(next)
|
||||||
|
|
||||||
|
return chain
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,154 @@
|
|||||||
|
//nolint:funlen
|
||||||
package logginghandler_test
|
package logginghandler_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/hlog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/require"
|
||||||
"go.xsfx.dev/logginghandler"
|
"go.xsfx.dev/logginghandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Example() {
|
func Example() {
|
||||||
handler := logginghandler.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
|
logger := log.With().Logger()
|
||||||
|
|
||||||
|
handler := logginghandler.Handler(
|
||||||
|
logger,
|
||||||
|
)(
|
||||||
|
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
logger := logginghandler.FromRequest(r)
|
||||||
|
|
||||||
|
logger.Info().Msg("this is a request")
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
http.Handle("/", handler)
|
http.Handle("/", handler)
|
||||||
log.Fatal().Msg(http.ListenAndServe(":5000", nil).Error())
|
log.Fatal().Msg(http.ListenAndServe(":5000", nil).Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
func testHandler(w http.ResponseWriter, r *http.Request) {
|
func testHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Print("got request")
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUUID(t *testing.T) {
|
func TestUUID(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
assert := assert.New(t)
|
assert := require.New(t)
|
||||||
req, err := http.NewRequestWithContext(context.Background(), "GET", "/test", nil)
|
req, err := http.NewRequestWithContext(context.Background(), "GET", "/test", nil)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
handler := logginghandler.Handler(http.HandlerFunc(testHandler))
|
handler := logginghandler.Handler(log.With().Logger())(http.HandlerFunc(testHandler))
|
||||||
|
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
|
|
||||||
assert.NotEmpty(rr.Header().Get("X-Request-ID"))
|
assert.NotEmpty(rr.Header().Get(logginghandler.UUIDHeader))
|
||||||
log.Print(rr.Header())
|
}
|
||||||
|
|
||||||
|
func TestFromCtx(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := require.New(t)
|
||||||
|
req, err := http.NewRequestWithContext(context.Background(), "GET", "/test", nil)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
// Create buffer to store output.
|
||||||
|
var output bytes.Buffer
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
handler := logginghandler.Handler(
|
||||||
|
zerolog.New(&output),
|
||||||
|
)(
|
||||||
|
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log := logginghandler.FromCtx(r.Context())
|
||||||
|
log.Info().Msg("hello world")
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
logs := strings.Split(output.String(), "\n")
|
||||||
|
assert.Len(logs, 3)
|
||||||
|
|
||||||
|
var jOut struct{ UUID string }
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(logs[0]), &jOut)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
assert.NotEmpty(jOut)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequestIDHandler(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := require.New(t)
|
||||||
|
|
||||||
|
handler := logginghandler.RequestIDHandler()(
|
||||||
|
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log := hlog.FromRequest(r)
|
||||||
|
log.Info().Msg("hello from TestRequestID")
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
id := "cfrj1ro330reqgvfpgu0"
|
||||||
|
|
||||||
|
// Create buffer to store output.
|
||||||
|
var output bytes.Buffer
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(context.Background(), "GET", "/", nil)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
h := hlog.NewHandler(zerolog.New(&output))(handler)
|
||||||
|
|
||||||
|
h.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
assert.NotEmpty(rr.Header().Get(logginghandler.UUIDHeader))
|
||||||
|
assert.NotEqual(rr.Header().Get(logginghandler.UUIDHeader), id)
|
||||||
|
|
||||||
|
// Now test with request id in header.
|
||||||
|
|
||||||
|
nr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
nReq, err := http.NewRequestWithContext(context.Background(), "GET", "/", nil)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
nReq.Header.Add(logginghandler.UUIDHeader, id)
|
||||||
|
|
||||||
|
h.ServeHTTP(nr, nReq)
|
||||||
|
|
||||||
|
assert.NotEmpty(nr.Header().Get(logginghandler.UUIDHeader))
|
||||||
|
assert.Equal(nr.Header().Get(logginghandler.UUIDHeader), id)
|
||||||
|
|
||||||
|
logs := strings.Split(output.String(), "\n")
|
||||||
|
assert.Len(logs, 3)
|
||||||
|
|
||||||
|
getUUID := func(l string) (string, error) {
|
||||||
|
var out struct{ UUID string }
|
||||||
|
|
||||||
|
err := json.Unmarshal([]byte(l), &out)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to unmarshal log: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.UUID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
uuid1, err := getUUID(logs[0])
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
assert.NotEqual(id, uuid1)
|
||||||
|
|
||||||
|
uuid2, err := getUUID(logs[1])
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(id, uuid2)
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
@ -2,7 +2,7 @@ ISC License
|
|||||||
|
|
||||||
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
copyright notice and this permission notice appear in all copies.
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
187
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
187
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
@ -16,7 +16,9 @@
|
|||||||
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
||||||
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
||||||
// tag is deprecated and thus should not be used.
|
// tag is deprecated and thus should not be used.
|
||||||
// +build !js,!appengine,!safe,!disableunsafe
|
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||||
|
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||||
|
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||||
|
|
||||||
package spew
|
package spew
|
||||||
|
|
||||||
@ -34,80 +36,49 @@ const (
|
|||||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
type flag uintptr
|
||||||
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
|
||||||
// internal reflect.Value fields. These values are valid before golang
|
|
||||||
// commit ecccf07e7f9d which changed the format. The are also valid
|
|
||||||
// after commit 82f48826c6c7 which changed the format again to mirror
|
|
||||||
// the original format. Code in the init function updates these offsets
|
|
||||||
// as necessary.
|
|
||||||
offsetPtr = uintptr(ptrSize)
|
|
||||||
offsetScalar = uintptr(0)
|
|
||||||
offsetFlag = uintptr(ptrSize * 2)
|
|
||||||
|
|
||||||
// flagKindWidth and flagKindShift indicate various bits that the
|
var (
|
||||||
// reflect package uses internally to track kind information.
|
// flagRO indicates whether the value field of a reflect.Value
|
||||||
//
|
// is read-only.
|
||||||
// flagRO indicates whether or not the value field of a reflect.Value is
|
flagRO flag
|
||||||
// read-only.
|
|
||||||
//
|
// flagAddr indicates whether the address of the reflect.Value's
|
||||||
// flagIndir indicates whether the value field of a reflect.Value is
|
// value may be taken.
|
||||||
// the actual data or a pointer to the data.
|
flagAddr flag
|
||||||
//
|
|
||||||
// These values are valid before golang commit 90a7c3c86944 which
|
|
||||||
// changed their positions. Code in the init function updates these
|
|
||||||
// flags as necessary.
|
|
||||||
flagKindWidth = uintptr(5)
|
|
||||||
flagKindShift = uintptr(flagKindWidth - 1)
|
|
||||||
flagRO = uintptr(1 << 0)
|
|
||||||
flagIndir = uintptr(1 << 1)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
// flagKindMask holds the bits that make up the kind
|
||||||
// Older versions of reflect.Value stored small integers directly in the
|
// part of the flags field. In all the supported versions,
|
||||||
// ptr field (which is named val in the older versions). Versions
|
// it is in the lower 5 bits.
|
||||||
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
const flagKindMask = flag(0x1f)
|
||||||
// scalar for this purpose which unfortunately came before the flag
|
|
||||||
// field, so the offset of the flag field is different for those
|
|
||||||
// versions.
|
|
||||||
//
|
|
||||||
// This code constructs a new reflect.Value from a known small integer
|
|
||||||
// and checks if the size of the reflect.Value struct indicates it has
|
|
||||||
// the scalar field. When it does, the offsets are updated accordingly.
|
|
||||||
vv := reflect.ValueOf(0xf00)
|
|
||||||
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
|
||||||
offsetScalar = ptrSize * 2
|
|
||||||
offsetFlag = ptrSize * 3
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit 90a7c3c86944 changed the flag positions such that the low
|
// Different versions of Go have used different
|
||||||
// order bits are the kind. This code extracts the kind from the flags
|
// bit layouts for the flags type. This table
|
||||||
// field and ensures it's the correct type. When it's not, the flag
|
// records the known combinations.
|
||||||
// order has been changed to the newer format, so the flags are updated
|
var okFlags = []struct {
|
||||||
// accordingly.
|
ro, addr flag
|
||||||
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
}{{
|
||||||
upfv := *(*uintptr)(upf)
|
// From Go 1.4 to 1.5
|
||||||
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
ro: 1 << 5,
|
||||||
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
addr: 1 << 7,
|
||||||
flagKindShift = 0
|
}, {
|
||||||
flagRO = 1 << 5
|
// Up to Go tip.
|
||||||
flagIndir = 1 << 6
|
ro: 1<<5 | 1<<6,
|
||||||
|
addr: 1 << 8,
|
||||||
|
}}
|
||||||
|
|
||||||
// Commit adf9b30e5594 modified the flags to separate the
|
var flagValOffset = func() uintptr {
|
||||||
// flagRO flag into two bits which specifies whether or not the
|
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||||
// field is embedded. This causes flagIndir to move over a bit
|
if !ok {
|
||||||
// and means that flagRO is the combination of either of the
|
panic("reflect.Value has no flag field")
|
||||||
// original flagRO bit and the new bit.
|
|
||||||
//
|
|
||||||
// This code detects the change by extracting what used to be
|
|
||||||
// the indirect bit to ensure it's set. When it's not, the flag
|
|
||||||
// order has been changed to the newer format, so the flags are
|
|
||||||
// updated accordingly.
|
|
||||||
if upfv&flagIndir == 0 {
|
|
||||||
flagRO = 3 << 5
|
|
||||||
flagIndir = 1 << 7
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return field.Offset
|
||||||
|
}()
|
||||||
|
|
||||||
|
// flagField returns a pointer to the flag field of a reflect.Value.
|
||||||
|
func flagField(v *reflect.Value) *flag {
|
||||||
|
return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||||
@ -119,34 +90,56 @@ func init() {
|
|||||||
// This allows us to check for implementations of the Stringer and error
|
// This allows us to check for implementations of the Stringer and error
|
||||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||||
// inaccessible values such as unexported struct fields.
|
// inaccessible values such as unexported struct fields.
|
||||||
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||||
indirects := 1
|
if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
|
||||||
vt := v.Type()
|
return v
|
||||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
}
|
||||||
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
flagFieldPtr := flagField(&v)
|
||||||
if rvf&flagIndir != 0 {
|
*flagFieldPtr &^= flagRO
|
||||||
vt = reflect.PtrTo(v.Type())
|
*flagFieldPtr |= flagAddr
|
||||||
indirects++
|
return v
|
||||||
} else if offsetScalar != 0 {
|
}
|
||||||
// The value is in the scalar field when it's not one of the
|
|
||||||
// reference types.
|
// Sanity checks against future reflect package changes
|
||||||
switch vt.Kind() {
|
// to the type or semantics of the Value.flag field.
|
||||||
case reflect.Uintptr:
|
func init() {
|
||||||
case reflect.Chan:
|
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||||
case reflect.Func:
|
if !ok {
|
||||||
case reflect.Map:
|
panic("reflect.Value has no flag field")
|
||||||
case reflect.Ptr:
|
}
|
||||||
case reflect.UnsafePointer:
|
if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
|
||||||
default:
|
panic("reflect.Value flag field has changed kind")
|
||||||
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
}
|
||||||
offsetScalar)
|
type t0 int
|
||||||
|
var t struct {
|
||||||
|
A t0
|
||||||
|
// t0 will have flagEmbedRO set.
|
||||||
|
t0
|
||||||
|
// a will have flagStickyRO set
|
||||||
|
a t0
|
||||||
|
}
|
||||||
|
vA := reflect.ValueOf(t).FieldByName("A")
|
||||||
|
va := reflect.ValueOf(t).FieldByName("a")
|
||||||
|
vt0 := reflect.ValueOf(t).FieldByName("t0")
|
||||||
|
|
||||||
|
// Infer flagRO from the difference between the flags
|
||||||
|
// for the (otherwise identical) fields in t.
|
||||||
|
flagPublic := *flagField(&vA)
|
||||||
|
flagWithRO := *flagField(&va) | *flagField(&vt0)
|
||||||
|
flagRO = flagPublic ^ flagWithRO
|
||||||
|
|
||||||
|
// Infer flagAddr from the difference between a value
|
||||||
|
// taken from a pointer and not.
|
||||||
|
vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
|
||||||
|
flagNoPtr := *flagField(&vA)
|
||||||
|
flagPtr := *flagField(&vPtrA)
|
||||||
|
flagAddr = flagNoPtr ^ flagPtr
|
||||||
|
|
||||||
|
// Check that the inferred flags tally with one of the known versions.
|
||||||
|
for _, f := range okFlags {
|
||||||
|
if flagRO == f.ro && flagAddr == f.addr {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
panic("reflect.Value read-only flag has changed semantics")
|
||||||
pv := reflect.NewAt(vt, upv)
|
|
||||||
rv = pv
|
|
||||||
for i := 0; i < indirects; i++ {
|
|
||||||
rv = rv.Elem()
|
|
||||||
}
|
|
||||||
return rv
|
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
@ -16,7 +16,7 @@
|
|||||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||||
// tag is deprecated and thus should not be used.
|
// tag is deprecated and thus should not be used.
|
||||||
// +build js appengine safe disableunsafe
|
// +build js appengine safe disableunsafe !go1.4
|
||||||
|
|
||||||
package spew
|
package spew
|
||||||
|
|
||||||
|
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
@ -180,7 +180,7 @@ func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
|||||||
w.Write(closeParenBytes)
|
w.Write(closeParenBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
|
// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
|
||||||
// prefix to Writer w.
|
// prefix to Writer w.
|
||||||
func printHexPtr(w io.Writer, p uintptr) {
|
func printHexPtr(w io.Writer, p uintptr) {
|
||||||
// Null pointer.
|
// Null pointer.
|
||||||
|
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
@ -35,16 +35,16 @@ var (
|
|||||||
|
|
||||||
// cCharRE is a regular expression that matches a cgo char.
|
// cCharRE is a regular expression that matches a cgo char.
|
||||||
// It is used to detect character arrays to hexdump them.
|
// It is used to detect character arrays to hexdump them.
|
||||||
cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
|
cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
|
||||||
|
|
||||||
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
||||||
// char. It is used to detect unsigned character arrays to hexdump
|
// char. It is used to detect unsigned character arrays to hexdump
|
||||||
// them.
|
// them.
|
||||||
cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
|
cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
|
||||||
|
|
||||||
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
||||||
// It is used to detect uint8_t arrays to hexdump them.
|
// It is used to detect uint8_t arrays to hexdump them.
|
||||||
cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
|
cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
// dumpState contains information about the state of a dump operation.
|
// dumpState contains information about the state of a dump operation.
|
||||||
@ -143,10 +143,10 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
|
|||||||
// Display dereferenced value.
|
// Display dereferenced value.
|
||||||
d.w.Write(openParenBytes)
|
d.w.Write(openParenBytes)
|
||||||
switch {
|
switch {
|
||||||
case nilFound == true:
|
case nilFound:
|
||||||
d.w.Write(nilAngleBytes)
|
d.w.Write(nilAngleBytes)
|
||||||
|
|
||||||
case cycleFound == true:
|
case cycleFound:
|
||||||
d.w.Write(circularBytes)
|
d.w.Write(circularBytes)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
@ -182,10 +182,10 @@ func (f *formatState) formatPtr(v reflect.Value) {
|
|||||||
|
|
||||||
// Display dereferenced value.
|
// Display dereferenced value.
|
||||||
switch {
|
switch {
|
||||||
case nilFound == true:
|
case nilFound:
|
||||||
f.fs.Write(nilAngleBytes)
|
f.fs.Write(nilAngleBytes)
|
||||||
|
|
||||||
case cycleFound == true:
|
case cycleFound:
|
||||||
f.fs.Write(circularShortBytes)
|
f.fs.Write(circularShortBytes)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
9
vendor/github.com/google/uuid/.travis.yml
generated
vendored
9
vendor/github.com/google/uuid/.travis.yml
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.4.3
|
|
||||||
- 1.5.3
|
|
||||||
- tip
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test -v ./...
|
|
10
vendor/github.com/google/uuid/CONTRIBUTING.md
generated
vendored
10
vendor/github.com/google/uuid/CONTRIBUTING.md
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
# How to contribute
|
|
||||||
|
|
||||||
We definitely welcome patches and contribution to this project!
|
|
||||||
|
|
||||||
### Legal requirements
|
|
||||||
|
|
||||||
In order to protect both you and ourselves, you will need to sign the
|
|
||||||
[Contributor License Agreement](https://cla.developers.google.com/clas).
|
|
||||||
|
|
||||||
You may have already signed it for other Google projects.
|
|
9
vendor/github.com/google/uuid/CONTRIBUTORS
generated
vendored
9
vendor/github.com/google/uuid/CONTRIBUTORS
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
Paul Borman <borman@google.com>
|
|
||||||
bmatsuo
|
|
||||||
shawnps
|
|
||||||
theory
|
|
||||||
jboverfelt
|
|
||||||
dsymonds
|
|
||||||
cd1
|
|
||||||
wallclockbuilder
|
|
||||||
dansouza
|
|
27
vendor/github.com/google/uuid/LICENSE
generated
vendored
27
vendor/github.com/google/uuid/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2009,2014 Google Inc. 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.
|
|
19
vendor/github.com/google/uuid/README.md
generated
vendored
19
vendor/github.com/google/uuid/README.md
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master)
|
|
||||||
The uuid package generates and inspects UUIDs based on
|
|
||||||
[RFC 4122](http://tools.ietf.org/html/rfc4122)
|
|
||||||
and DCE 1.1: Authentication and Security Services.
|
|
||||||
|
|
||||||
This package is based on the github.com/pborman/uuid package (previously named
|
|
||||||
code.google.com/p/go-uuid). It differs from these earlier packages in that
|
|
||||||
a UUID is a 16 byte array rather than a byte slice. One loss due to this
|
|
||||||
change is the ability to represent an invalid UUID (vs a NIL UUID).
|
|
||||||
|
|
||||||
###### Install
|
|
||||||
`go get github.com/google/uuid`
|
|
||||||
|
|
||||||
###### Documentation
|
|
||||||
[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid)
|
|
||||||
|
|
||||||
Full `go doc` style documentation for the package can be viewed online without
|
|
||||||
installing this package by using the GoDoc site here:
|
|
||||||
http://pkg.go.dev/github.com/google/uuid
|
|
80
vendor/github.com/google/uuid/dce.go
generated
vendored
80
vendor/github.com/google/uuid/dce.go
generated
vendored
@ -1,80 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Domain represents a Version 2 domain
|
|
||||||
type Domain byte
|
|
||||||
|
|
||||||
// Domain constants for DCE Security (Version 2) UUIDs.
|
|
||||||
const (
|
|
||||||
Person = Domain(0)
|
|
||||||
Group = Domain(1)
|
|
||||||
Org = Domain(2)
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewDCESecurity returns a DCE Security (Version 2) UUID.
|
|
||||||
//
|
|
||||||
// The domain should be one of Person, Group or Org.
|
|
||||||
// On a POSIX system the id should be the users UID for the Person
|
|
||||||
// domain and the users GID for the Group. The meaning of id for
|
|
||||||
// the domain Org or on non-POSIX systems is site defined.
|
|
||||||
//
|
|
||||||
// For a given domain/id pair the same token may be returned for up to
|
|
||||||
// 7 minutes and 10 seconds.
|
|
||||||
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
|
|
||||||
uuid, err := NewUUID()
|
|
||||||
if err == nil {
|
|
||||||
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
|
|
||||||
uuid[9] = byte(domain)
|
|
||||||
binary.BigEndian.PutUint32(uuid[0:], id)
|
|
||||||
}
|
|
||||||
return uuid, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
|
|
||||||
// domain with the id returned by os.Getuid.
|
|
||||||
//
|
|
||||||
// NewDCESecurity(Person, uint32(os.Getuid()))
|
|
||||||
func NewDCEPerson() (UUID, error) {
|
|
||||||
return NewDCESecurity(Person, uint32(os.Getuid()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
|
|
||||||
// domain with the id returned by os.Getgid.
|
|
||||||
//
|
|
||||||
// NewDCESecurity(Group, uint32(os.Getgid()))
|
|
||||||
func NewDCEGroup() (UUID, error) {
|
|
||||||
return NewDCESecurity(Group, uint32(os.Getgid()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Domain returns the domain for a Version 2 UUID. Domains are only defined
|
|
||||||
// for Version 2 UUIDs.
|
|
||||||
func (uuid UUID) Domain() Domain {
|
|
||||||
return Domain(uuid[9])
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
|
|
||||||
// UUIDs.
|
|
||||||
func (uuid UUID) ID() uint32 {
|
|
||||||
return binary.BigEndian.Uint32(uuid[0:4])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d Domain) String() string {
|
|
||||||
switch d {
|
|
||||||
case Person:
|
|
||||||
return "Person"
|
|
||||||
case Group:
|
|
||||||
return "Group"
|
|
||||||
case Org:
|
|
||||||
return "Org"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("Domain%d", int(d))
|
|
||||||
}
|
|
12
vendor/github.com/google/uuid/doc.go
generated
vendored
12
vendor/github.com/google/uuid/doc.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package uuid generates and inspects UUIDs.
|
|
||||||
//
|
|
||||||
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security
|
|
||||||
// Services.
|
|
||||||
//
|
|
||||||
// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to
|
|
||||||
// maps or compared directly.
|
|
||||||
package uuid
|
|
1
vendor/github.com/google/uuid/go.mod
generated
vendored
1
vendor/github.com/google/uuid/go.mod
generated
vendored
@ -1 +0,0 @@
|
|||||||
module github.com/google/uuid
|
|
53
vendor/github.com/google/uuid/hash.go
generated
vendored
53
vendor/github.com/google/uuid/hash.go
generated
vendored
@ -1,53 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"crypto/sha1"
|
|
||||||
"hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Well known namespace IDs and UUIDs
|
|
||||||
var (
|
|
||||||
NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
|
|
||||||
NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
|
|
||||||
NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
|
|
||||||
NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
|
|
||||||
Nil UUID // empty UUID, all zeros
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewHash returns a new UUID derived from the hash of space concatenated with
|
|
||||||
// data generated by h. The hash should be at least 16 byte in length. The
|
|
||||||
// first 16 bytes of the hash are used to form the UUID. The version of the
|
|
||||||
// UUID will be the lower 4 bits of version. NewHash is used to implement
|
|
||||||
// NewMD5 and NewSHA1.
|
|
||||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
|
||||||
h.Reset()
|
|
||||||
h.Write(space[:])
|
|
||||||
h.Write(data)
|
|
||||||
s := h.Sum(nil)
|
|
||||||
var uuid UUID
|
|
||||||
copy(uuid[:], s)
|
|
||||||
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
|
|
||||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMD5 returns a new MD5 (Version 3) UUID based on the
|
|
||||||
// supplied name space and data. It is the same as calling:
|
|
||||||
//
|
|
||||||
// NewHash(md5.New(), space, data, 3)
|
|
||||||
func NewMD5(space UUID, data []byte) UUID {
|
|
||||||
return NewHash(md5.New(), space, data, 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
|
|
||||||
// supplied name space and data. It is the same as calling:
|
|
||||||
//
|
|
||||||
// NewHash(sha1.New(), space, data, 5)
|
|
||||||
func NewSHA1(space UUID, data []byte) UUID {
|
|
||||||
return NewHash(sha1.New(), space, data, 5)
|
|
||||||
}
|
|
38
vendor/github.com/google/uuid/marshal.go
generated
vendored
38
vendor/github.com/google/uuid/marshal.go
generated
vendored
@ -1,38 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// MarshalText implements encoding.TextMarshaler.
|
|
||||||
func (uuid UUID) MarshalText() ([]byte, error) {
|
|
||||||
var js [36]byte
|
|
||||||
encodeHex(js[:], uuid)
|
|
||||||
return js[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
|
||||||
func (uuid *UUID) UnmarshalText(data []byte) error {
|
|
||||||
id, err := ParseBytes(data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*uuid = id
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalBinary implements encoding.BinaryMarshaler.
|
|
||||||
func (uuid UUID) MarshalBinary() ([]byte, error) {
|
|
||||||
return uuid[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
|
||||||
func (uuid *UUID) UnmarshalBinary(data []byte) error {
|
|
||||||
if len(data) != 16 {
|
|
||||||
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
|
|
||||||
}
|
|
||||||
copy(uuid[:], data)
|
|
||||||
return nil
|
|
||||||
}
|
|
90
vendor/github.com/google/uuid/node.go
generated
vendored
90
vendor/github.com/google/uuid/node.go
generated
vendored
@ -1,90 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
nodeMu sync.Mutex
|
|
||||||
ifname string // name of interface being used
|
|
||||||
nodeID [6]byte // hardware for version 1 UUIDs
|
|
||||||
zeroID [6]byte // nodeID with only 0's
|
|
||||||
)
|
|
||||||
|
|
||||||
// NodeInterface returns the name of the interface from which the NodeID was
|
|
||||||
// derived. The interface "user" is returned if the NodeID was set by
|
|
||||||
// SetNodeID.
|
|
||||||
func NodeInterface() string {
|
|
||||||
defer nodeMu.Unlock()
|
|
||||||
nodeMu.Lock()
|
|
||||||
return ifname
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
|
|
||||||
// If name is "" then the first usable interface found will be used or a random
|
|
||||||
// Node ID will be generated. If a named interface cannot be found then false
|
|
||||||
// is returned.
|
|
||||||
//
|
|
||||||
// SetNodeInterface never fails when name is "".
|
|
||||||
func SetNodeInterface(name string) bool {
|
|
||||||
defer nodeMu.Unlock()
|
|
||||||
nodeMu.Lock()
|
|
||||||
return setNodeInterface(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setNodeInterface(name string) bool {
|
|
||||||
iname, addr := getHardwareInterface(name) // null implementation for js
|
|
||||||
if iname != "" && addr != nil {
|
|
||||||
ifname = iname
|
|
||||||
copy(nodeID[:], addr)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// We found no interfaces with a valid hardware address. If name
|
|
||||||
// does not specify a specific interface generate a random Node ID
|
|
||||||
// (section 4.1.6)
|
|
||||||
if name == "" {
|
|
||||||
ifname = "random"
|
|
||||||
randomBits(nodeID[:])
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
|
|
||||||
// if not already set.
|
|
||||||
func NodeID() []byte {
|
|
||||||
defer nodeMu.Unlock()
|
|
||||||
nodeMu.Lock()
|
|
||||||
if nodeID == zeroID {
|
|
||||||
setNodeInterface("")
|
|
||||||
}
|
|
||||||
nid := nodeID
|
|
||||||
return nid[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
|
|
||||||
// of id are used. If id is less than 6 bytes then false is returned and the
|
|
||||||
// Node ID is not set.
|
|
||||||
func SetNodeID(id []byte) bool {
|
|
||||||
if len(id) < 6 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
defer nodeMu.Unlock()
|
|
||||||
nodeMu.Lock()
|
|
||||||
copy(nodeID[:], id)
|
|
||||||
ifname = "user"
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
|
|
||||||
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
|
|
||||||
func (uuid UUID) NodeID() []byte {
|
|
||||||
var node [6]byte
|
|
||||||
copy(node[:], uuid[10:])
|
|
||||||
return node[:]
|
|
||||||
}
|
|
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
// Copyright 2017 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build js
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
// getHardwareInterface returns nil values for the JS version of the code.
|
|
||||||
// This remvoves the "net" dependency, because it is not used in the browser.
|
|
||||||
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
|
|
||||||
func getHardwareInterface(name string) (string, []byte) { return "", nil }
|
|
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
// Copyright 2017 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !js
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import "net"
|
|
||||||
|
|
||||||
var interfaces []net.Interface // cached list of interfaces
|
|
||||||
|
|
||||||
// getHardwareInterface returns the name and hardware address of interface name.
|
|
||||||
// If name is "" then the name and hardware address of one of the system's
|
|
||||||
// interfaces is returned. If no interfaces are found (name does not exist or
|
|
||||||
// there are no interfaces) then "", nil is returned.
|
|
||||||
//
|
|
||||||
// Only addresses of at least 6 bytes are returned.
|
|
||||||
func getHardwareInterface(name string) (string, []byte) {
|
|
||||||
if interfaces == nil {
|
|
||||||
var err error
|
|
||||||
interfaces, err = net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, ifs := range interfaces {
|
|
||||||
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
|
|
||||||
return ifs.Name, ifs.HardwareAddr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
}
|
|
59
vendor/github.com/google/uuid/sql.go
generated
vendored
59
vendor/github.com/google/uuid/sql.go
generated
vendored
@ -1,59 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql/driver"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
|
|
||||||
// Currently, database types that map to string and []byte are supported. Please
|
|
||||||
// consult database-specific driver documentation for matching types.
|
|
||||||
func (uuid *UUID) Scan(src interface{}) error {
|
|
||||||
switch src := src.(type) {
|
|
||||||
case nil:
|
|
||||||
return nil
|
|
||||||
|
|
||||||
case string:
|
|
||||||
// if an empty UUID comes from a table, we return a null UUID
|
|
||||||
if src == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// see Parse for required string format
|
|
||||||
u, err := Parse(src)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Scan: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*uuid = u
|
|
||||||
|
|
||||||
case []byte:
|
|
||||||
// if an empty UUID comes from a table, we return a null UUID
|
|
||||||
if len(src) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// assumes a simple slice of bytes if 16 bytes
|
|
||||||
// otherwise attempts to parse
|
|
||||||
if len(src) != 16 {
|
|
||||||
return uuid.Scan(string(src))
|
|
||||||
}
|
|
||||||
copy((*uuid)[:], src)
|
|
||||||
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value implements sql.Valuer so that UUIDs can be written to databases
|
|
||||||
// transparently. Currently, UUIDs map to strings. Please consult
|
|
||||||
// database-specific driver documentation for matching types.
|
|
||||||
func (uuid UUID) Value() (driver.Value, error) {
|
|
||||||
return uuid.String(), nil
|
|
||||||
}
|
|
123
vendor/github.com/google/uuid/time.go
generated
vendored
123
vendor/github.com/google/uuid/time.go
generated
vendored
@ -1,123 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
|
|
||||||
// 1582.
|
|
||||||
type Time int64
|
|
||||||
|
|
||||||
const (
|
|
||||||
lillian = 2299160 // Julian day of 15 Oct 1582
|
|
||||||
unix = 2440587 // Julian day of 1 Jan 1970
|
|
||||||
epoch = unix - lillian // Days between epochs
|
|
||||||
g1582 = epoch * 86400 // seconds between epochs
|
|
||||||
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
timeMu sync.Mutex
|
|
||||||
lasttime uint64 // last time we returned
|
|
||||||
clockSeq uint16 // clock sequence for this run
|
|
||||||
|
|
||||||
timeNow = time.Now // for testing
|
|
||||||
)
|
|
||||||
|
|
||||||
// UnixTime converts t the number of seconds and nanoseconds using the Unix
|
|
||||||
// epoch of 1 Jan 1970.
|
|
||||||
func (t Time) UnixTime() (sec, nsec int64) {
|
|
||||||
sec = int64(t - g1582ns100)
|
|
||||||
nsec = (sec % 10000000) * 100
|
|
||||||
sec /= 10000000
|
|
||||||
return sec, nsec
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
|
|
||||||
// clock sequence as well as adjusting the clock sequence as needed. An error
|
|
||||||
// is returned if the current time cannot be determined.
|
|
||||||
func GetTime() (Time, uint16, error) {
|
|
||||||
defer timeMu.Unlock()
|
|
||||||
timeMu.Lock()
|
|
||||||
return getTime()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTime() (Time, uint16, error) {
|
|
||||||
t := timeNow()
|
|
||||||
|
|
||||||
// If we don't have a clock sequence already, set one.
|
|
||||||
if clockSeq == 0 {
|
|
||||||
setClockSequence(-1)
|
|
||||||
}
|
|
||||||
now := uint64(t.UnixNano()/100) + g1582ns100
|
|
||||||
|
|
||||||
// If time has gone backwards with this clock sequence then we
|
|
||||||
// increment the clock sequence
|
|
||||||
if now <= lasttime {
|
|
||||||
clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000
|
|
||||||
}
|
|
||||||
lasttime = now
|
|
||||||
return Time(now), clockSeq, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClockSequence returns the current clock sequence, generating one if not
|
|
||||||
// already set. The clock sequence is only used for Version 1 UUIDs.
|
|
||||||
//
|
|
||||||
// The uuid package does not use global static storage for the clock sequence or
|
|
||||||
// the last time a UUID was generated. Unless SetClockSequence is used, a new
|
|
||||||
// random clock sequence is generated the first time a clock sequence is
|
|
||||||
// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1)
|
|
||||||
func ClockSequence() int {
|
|
||||||
defer timeMu.Unlock()
|
|
||||||
timeMu.Lock()
|
|
||||||
return clockSequence()
|
|
||||||
}
|
|
||||||
|
|
||||||
func clockSequence() int {
|
|
||||||
if clockSeq == 0 {
|
|
||||||
setClockSequence(-1)
|
|
||||||
}
|
|
||||||
return int(clockSeq & 0x3fff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to
|
|
||||||
// -1 causes a new sequence to be generated.
|
|
||||||
func SetClockSequence(seq int) {
|
|
||||||
defer timeMu.Unlock()
|
|
||||||
timeMu.Lock()
|
|
||||||
setClockSequence(seq)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setClockSequence(seq int) {
|
|
||||||
if seq == -1 {
|
|
||||||
var b [2]byte
|
|
||||||
randomBits(b[:]) // clock sequence
|
|
||||||
seq = int(b[0])<<8 | int(b[1])
|
|
||||||
}
|
|
||||||
oldSeq := clockSeq
|
|
||||||
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
|
|
||||||
if oldSeq != clockSeq {
|
|
||||||
lasttime = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
|
|
||||||
// uuid. The time is only defined for version 1 and 2 UUIDs.
|
|
||||||
func (uuid UUID) Time() Time {
|
|
||||||
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
|
|
||||||
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
|
|
||||||
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
|
|
||||||
return Time(time)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClockSequence returns the clock sequence encoded in uuid.
|
|
||||||
// The clock sequence is only well defined for version 1 and 2 UUIDs.
|
|
||||||
func (uuid UUID) ClockSequence() int {
|
|
||||||
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff
|
|
||||||
}
|
|
43
vendor/github.com/google/uuid/util.go
generated
vendored
43
vendor/github.com/google/uuid/util.go
generated
vendored
@ -1,43 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// randomBits completely fills slice b with random data.
|
|
||||||
func randomBits(b []byte) {
|
|
||||||
if _, err := io.ReadFull(rander, b); err != nil {
|
|
||||||
panic(err.Error()) // rand should never fail
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// xvalues returns the value of a byte as a hexadecimal digit or 255.
|
|
||||||
var xvalues = [256]byte{
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
|
||||||
}
|
|
||||||
|
|
||||||
// xtob converts hex characters x1 and x2 into a byte.
|
|
||||||
func xtob(x1, x2 byte) (byte, bool) {
|
|
||||||
b1 := xvalues[x1]
|
|
||||||
b2 := xvalues[x2]
|
|
||||||
return (b1 << 4) | b2, b1 != 255 && b2 != 255
|
|
||||||
}
|
|
245
vendor/github.com/google/uuid/uuid.go
generated
vendored
245
vendor/github.com/google/uuid/uuid.go
generated
vendored
@ -1,245 +0,0 @@
|
|||||||
// Copyright 2018 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/hex"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
|
|
||||||
// 4122.
|
|
||||||
type UUID [16]byte
|
|
||||||
|
|
||||||
// A Version represents a UUID's version.
|
|
||||||
type Version byte
|
|
||||||
|
|
||||||
// A Variant represents a UUID's variant.
|
|
||||||
type Variant byte
|
|
||||||
|
|
||||||
// Constants returned by Variant.
|
|
||||||
const (
|
|
||||||
Invalid = Variant(iota) // Invalid UUID
|
|
||||||
RFC4122 // The variant specified in RFC4122
|
|
||||||
Reserved // Reserved, NCS backward compatibility.
|
|
||||||
Microsoft // Reserved, Microsoft Corporation backward compatibility.
|
|
||||||
Future // Reserved for future definition.
|
|
||||||
)
|
|
||||||
|
|
||||||
var rander = rand.Reader // random function
|
|
||||||
|
|
||||||
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
|
||||||
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
|
||||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
|
|
||||||
// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex
|
|
||||||
// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
|
|
||||||
func Parse(s string) (UUID, error) {
|
|
||||||
var uuid UUID
|
|
||||||
switch len(s) {
|
|
||||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
||||||
case 36:
|
|
||||||
|
|
||||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
||||||
case 36 + 9:
|
|
||||||
if strings.ToLower(s[:9]) != "urn:uuid:" {
|
|
||||||
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
|
|
||||||
}
|
|
||||||
s = s[9:]
|
|
||||||
|
|
||||||
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
|
||||||
case 36 + 2:
|
|
||||||
s = s[1:]
|
|
||||||
|
|
||||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
||||||
case 32:
|
|
||||||
var ok bool
|
|
||||||
for i := range uuid {
|
|
||||||
uuid[i], ok = xtob(s[i*2], s[i*2+1])
|
|
||||||
if !ok {
|
|
||||||
return uuid, errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return uuid, nil
|
|
||||||
default:
|
|
||||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
|
||||||
}
|
|
||||||
// s is now at least 36 bytes long
|
|
||||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
||||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
|
||||||
return uuid, errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
for i, x := range [16]int{
|
|
||||||
0, 2, 4, 6,
|
|
||||||
9, 11,
|
|
||||||
14, 16,
|
|
||||||
19, 21,
|
|
||||||
24, 26, 28, 30, 32, 34} {
|
|
||||||
v, ok := xtob(s[x], s[x+1])
|
|
||||||
if !ok {
|
|
||||||
return uuid, errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
uuid[i] = v
|
|
||||||
}
|
|
||||||
return uuid, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseBytes is like Parse, except it parses a byte slice instead of a string.
|
|
||||||
func ParseBytes(b []byte) (UUID, error) {
|
|
||||||
var uuid UUID
|
|
||||||
switch len(b) {
|
|
||||||
case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
||||||
case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
||||||
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
|
|
||||||
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
|
|
||||||
}
|
|
||||||
b = b[9:]
|
|
||||||
case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
|
||||||
b = b[1:]
|
|
||||||
case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
||||||
var ok bool
|
|
||||||
for i := 0; i < 32; i += 2 {
|
|
||||||
uuid[i/2], ok = xtob(b[i], b[i+1])
|
|
||||||
if !ok {
|
|
||||||
return uuid, errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return uuid, nil
|
|
||||||
default:
|
|
||||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
|
||||||
}
|
|
||||||
// s is now at least 36 bytes long
|
|
||||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
||||||
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
|
|
||||||
return uuid, errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
for i, x := range [16]int{
|
|
||||||
0, 2, 4, 6,
|
|
||||||
9, 11,
|
|
||||||
14, 16,
|
|
||||||
19, 21,
|
|
||||||
24, 26, 28, 30, 32, 34} {
|
|
||||||
v, ok := xtob(b[x], b[x+1])
|
|
||||||
if !ok {
|
|
||||||
return uuid, errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
uuid[i] = v
|
|
||||||
}
|
|
||||||
return uuid, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustParse is like Parse but panics if the string cannot be parsed.
|
|
||||||
// It simplifies safe initialization of global variables holding compiled UUIDs.
|
|
||||||
func MustParse(s string) UUID {
|
|
||||||
uuid, err := Parse(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(`uuid: Parse(` + s + `): ` + err.Error())
|
|
||||||
}
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
|
|
||||||
// does not have a length of 16. The bytes are copied from the slice.
|
|
||||||
func FromBytes(b []byte) (uuid UUID, err error) {
|
|
||||||
err = uuid.UnmarshalBinary(b)
|
|
||||||
return uuid, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must returns uuid if err is nil and panics otherwise.
|
|
||||||
func Must(uuid UUID, err error) UUID {
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
||||||
// , or "" if uuid is invalid.
|
|
||||||
func (uuid UUID) String() string {
|
|
||||||
var buf [36]byte
|
|
||||||
encodeHex(buf[:], uuid)
|
|
||||||
return string(buf[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// URN returns the RFC 2141 URN form of uuid,
|
|
||||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
|
|
||||||
func (uuid UUID) URN() string {
|
|
||||||
var buf [36 + 9]byte
|
|
||||||
copy(buf[:], "urn:uuid:")
|
|
||||||
encodeHex(buf[9:], uuid)
|
|
||||||
return string(buf[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeHex(dst []byte, uuid UUID) {
|
|
||||||
hex.Encode(dst, uuid[:4])
|
|
||||||
dst[8] = '-'
|
|
||||||
hex.Encode(dst[9:13], uuid[4:6])
|
|
||||||
dst[13] = '-'
|
|
||||||
hex.Encode(dst[14:18], uuid[6:8])
|
|
||||||
dst[18] = '-'
|
|
||||||
hex.Encode(dst[19:23], uuid[8:10])
|
|
||||||
dst[23] = '-'
|
|
||||||
hex.Encode(dst[24:], uuid[10:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variant returns the variant encoded in uuid.
|
|
||||||
func (uuid UUID) Variant() Variant {
|
|
||||||
switch {
|
|
||||||
case (uuid[8] & 0xc0) == 0x80:
|
|
||||||
return RFC4122
|
|
||||||
case (uuid[8] & 0xe0) == 0xc0:
|
|
||||||
return Microsoft
|
|
||||||
case (uuid[8] & 0xe0) == 0xe0:
|
|
||||||
return Future
|
|
||||||
default:
|
|
||||||
return Reserved
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version returns the version of uuid.
|
|
||||||
func (uuid UUID) Version() Version {
|
|
||||||
return Version(uuid[6] >> 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Version) String() string {
|
|
||||||
if v > 15 {
|
|
||||||
return fmt.Sprintf("BAD_VERSION_%d", v)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("VERSION_%d", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Variant) String() string {
|
|
||||||
switch v {
|
|
||||||
case RFC4122:
|
|
||||||
return "RFC4122"
|
|
||||||
case Reserved:
|
|
||||||
return "Reserved"
|
|
||||||
case Microsoft:
|
|
||||||
return "Microsoft"
|
|
||||||
case Future:
|
|
||||||
return "Future"
|
|
||||||
case Invalid:
|
|
||||||
return "Invalid"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("BadVariant%d", int(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRand sets the random number generator to r, which implements io.Reader.
|
|
||||||
// If r.Read returns an error when the package requests random data then
|
|
||||||
// a panic will be issued.
|
|
||||||
//
|
|
||||||
// Calling SetRand with nil sets the random number generator to the default
|
|
||||||
// generator.
|
|
||||||
func SetRand(r io.Reader) {
|
|
||||||
if r == nil {
|
|
||||||
rander = rand.Reader
|
|
||||||
return
|
|
||||||
}
|
|
||||||
rander = r
|
|
||||||
}
|
|
44
vendor/github.com/google/uuid/version1.go
generated
vendored
44
vendor/github.com/google/uuid/version1.go
generated
vendored
@ -1,44 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
|
|
||||||
// sequence, and the current time. If the NodeID has not been set by SetNodeID
|
|
||||||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
|
|
||||||
// be set NewUUID returns nil. If clock sequence has not been set by
|
|
||||||
// SetClockSequence then it will be set automatically. If GetTime fails to
|
|
||||||
// return the current NewUUID returns nil and an error.
|
|
||||||
//
|
|
||||||
// In most cases, New should be used.
|
|
||||||
func NewUUID() (UUID, error) {
|
|
||||||
var uuid UUID
|
|
||||||
now, seq, err := GetTime()
|
|
||||||
if err != nil {
|
|
||||||
return uuid, err
|
|
||||||
}
|
|
||||||
|
|
||||||
timeLow := uint32(now & 0xffffffff)
|
|
||||||
timeMid := uint16((now >> 32) & 0xffff)
|
|
||||||
timeHi := uint16((now >> 48) & 0x0fff)
|
|
||||||
timeHi |= 0x1000 // Version 1
|
|
||||||
|
|
||||||
binary.BigEndian.PutUint32(uuid[0:], timeLow)
|
|
||||||
binary.BigEndian.PutUint16(uuid[4:], timeMid)
|
|
||||||
binary.BigEndian.PutUint16(uuid[6:], timeHi)
|
|
||||||
binary.BigEndian.PutUint16(uuid[8:], seq)
|
|
||||||
|
|
||||||
nodeMu.Lock()
|
|
||||||
if nodeID == zeroID {
|
|
||||||
setNodeInterface("")
|
|
||||||
}
|
|
||||||
copy(uuid[10:], nodeID[:])
|
|
||||||
nodeMu.Unlock()
|
|
||||||
|
|
||||||
return uuid, nil
|
|
||||||
}
|
|
43
vendor/github.com/google/uuid/version4.go
generated
vendored
43
vendor/github.com/google/uuid/version4.go
generated
vendored
@ -1,43 +0,0 @@
|
|||||||
// Copyright 2016 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// New creates a new random UUID or panics. New is equivalent to
|
|
||||||
// the expression
|
|
||||||
//
|
|
||||||
// uuid.Must(uuid.NewRandom())
|
|
||||||
func New() UUID {
|
|
||||||
return Must(NewRandom())
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRandom returns a Random (Version 4) UUID.
|
|
||||||
//
|
|
||||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
|
||||||
// package.
|
|
||||||
//
|
|
||||||
// A note about uniqueness derived from the UUID Wikipedia entry:
|
|
||||||
//
|
|
||||||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
|
||||||
// hit by a meteorite is estimated to be one chance in 17 billion, that
|
|
||||||
// means the probability is about 0.00000000006 (6 × 10−11),
|
|
||||||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
|
|
||||||
// year and having one duplicate.
|
|
||||||
func NewRandom() (UUID, error) {
|
|
||||||
return NewRandomFromReader(rander)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader.
|
|
||||||
func NewRandomFromReader(r io.Reader) (UUID, error) {
|
|
||||||
var uuid UUID
|
|
||||||
_, err := io.ReadFull(r, uuid[:])
|
|
||||||
if err != nil {
|
|
||||||
return Nil, err
|
|
||||||
}
|
|
||||||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
|
||||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
|
||||||
return uuid, nil
|
|
||||||
}
|
|
19
vendor/github.com/justinas/alice/.travis.yml
generated
vendored
Normal file
19
vendor/github.com/justinas/alice/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
language: go
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- go: 1.2.x
|
||||||
|
- go: 1.3.x
|
||||||
|
- go: 1.4.x
|
||||||
|
- go: 1.5.x
|
||||||
|
- go: 1.6.x
|
||||||
|
- go: 1.7.x
|
||||||
|
- go: 1.8.x
|
||||||
|
- go: 1.9.x
|
||||||
|
- go: 1.10.x
|
||||||
|
- go: 1.11.x
|
||||||
|
- go: 1.12.x
|
||||||
|
- go: 1.13.x
|
||||||
|
- go: tip
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
20
vendor/github.com/justinas/alice/LICENSE
generated
vendored
Normal file
20
vendor/github.com/justinas/alice/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Justinas Stankevicius
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
98
vendor/github.com/justinas/alice/README.md
generated
vendored
Normal file
98
vendor/github.com/justinas/alice/README.md
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# Alice
|
||||||
|
|
||||||
|
[![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](http://godoc.org/github.com/justinas/alice)
|
||||||
|
[![Build Status](https://travis-ci.org/justinas/alice.svg?branch=master)](https://travis-ci.org/justinas/alice)
|
||||||
|
[![Coverage](http://gocover.io/_badge/github.com/justinas/alice)](http://gocover.io/github.com/justinas/alice)
|
||||||
|
|
||||||
|
Alice provides a convenient way to chain
|
||||||
|
your HTTP middleware functions and the app handler.
|
||||||
|
|
||||||
|
In short, it transforms
|
||||||
|
|
||||||
|
```go
|
||||||
|
Middleware1(Middleware2(Middleware3(App)))
|
||||||
|
```
|
||||||
|
|
||||||
|
to
|
||||||
|
|
||||||
|
```go
|
||||||
|
alice.New(Middleware1, Middleware2, Middleware3).Then(App)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Why?
|
||||||
|
|
||||||
|
None of the other middleware chaining solutions
|
||||||
|
behaves exactly like Alice.
|
||||||
|
Alice is as minimal as it gets:
|
||||||
|
in essence, it's just a for loop that does the wrapping for you.
|
||||||
|
|
||||||
|
Check out [this blog post](http://justinas.org/alice-painless-middleware-chaining-for-go/)
|
||||||
|
for explanation how Alice is different from other chaining solutions.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
Your middleware constructors should have the form of
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (http.Handler) http.Handler
|
||||||
|
```
|
||||||
|
|
||||||
|
Some middleware provide this out of the box.
|
||||||
|
For ones that don't, it's trivial to write one yourself.
|
||||||
|
|
||||||
|
```go
|
||||||
|
func myStripPrefix(h http.Handler) http.Handler {
|
||||||
|
return http.StripPrefix("/old", h)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This complete example shows the full power of Alice.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/throttled/throttled"
|
||||||
|
"github.com/justinas/alice"
|
||||||
|
"github.com/justinas/nosurf"
|
||||||
|
)
|
||||||
|
|
||||||
|
func timeoutHandler(h http.Handler) http.Handler {
|
||||||
|
return http.TimeoutHandler(h, 1*time.Second, "timed out")
|
||||||
|
}
|
||||||
|
|
||||||
|
func myApp(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("Hello world!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
th := throttled.Interval(throttled.PerSec(10), 1, &throttled.VaryBy{Path: true}, 50)
|
||||||
|
myHandler := http.HandlerFunc(myApp)
|
||||||
|
|
||||||
|
chain := alice.New(th.Throttle, timeoutHandler, nosurf.NewPure).Then(myHandler)
|
||||||
|
http.ListenAndServe(":8000", chain)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, the request will pass [throttled](https://github.com/PuerkitoBio/throttled) first,
|
||||||
|
then an http.TimeoutHandler we've set up,
|
||||||
|
then [nosurf](https://github.com/justinas/nosurf)
|
||||||
|
and will finally reach our handler.
|
||||||
|
|
||||||
|
Note that Alice makes **no guarantees** for
|
||||||
|
how one or another piece of middleware will behave.
|
||||||
|
Once it passes the execution to the outer layer of middleware,
|
||||||
|
it has no saying in whether middleware will execute the inner handlers.
|
||||||
|
This is intentional behavior.
|
||||||
|
|
||||||
|
Alice works with Go 1.0 and higher.
|
||||||
|
|
||||||
|
### Contributing
|
||||||
|
|
||||||
|
0. Find an issue that bugs you / open a new one.
|
||||||
|
1. Discuss.
|
||||||
|
2. Branch off, commit, test.
|
||||||
|
3. Make a pull request / attach the commits to the issue.
|
112
vendor/github.com/justinas/alice/chain.go
generated
vendored
Normal file
112
vendor/github.com/justinas/alice/chain.go
generated
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// Package alice provides a convenient way to chain http handlers.
|
||||||
|
package alice
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
// A constructor for a piece of middleware.
|
||||||
|
// Some middleware use this constructor out of the box,
|
||||||
|
// so in most cases you can just pass somepackage.New
|
||||||
|
type Constructor func(http.Handler) http.Handler
|
||||||
|
|
||||||
|
// Chain acts as a list of http.Handler constructors.
|
||||||
|
// Chain is effectively immutable:
|
||||||
|
// once created, it will always hold
|
||||||
|
// the same set of constructors in the same order.
|
||||||
|
type Chain struct {
|
||||||
|
constructors []Constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new chain,
|
||||||
|
// memorizing the given list of middleware constructors.
|
||||||
|
// New serves no other function,
|
||||||
|
// constructors are only called upon a call to Then().
|
||||||
|
func New(constructors ...Constructor) Chain {
|
||||||
|
return Chain{append(([]Constructor)(nil), constructors...)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then chains the middleware and returns the final http.Handler.
|
||||||
|
// New(m1, m2, m3).Then(h)
|
||||||
|
// is equivalent to:
|
||||||
|
// m1(m2(m3(h)))
|
||||||
|
// When the request comes in, it will be passed to m1, then m2, then m3
|
||||||
|
// and finally, the given handler
|
||||||
|
// (assuming every middleware calls the following one).
|
||||||
|
//
|
||||||
|
// A chain can be safely reused by calling Then() several times.
|
||||||
|
// stdStack := alice.New(ratelimitHandler, csrfHandler)
|
||||||
|
// indexPipe = stdStack.Then(indexHandler)
|
||||||
|
// authPipe = stdStack.Then(authHandler)
|
||||||
|
// Note that constructors are called on every call to Then()
|
||||||
|
// and thus several instances of the same middleware will be created
|
||||||
|
// when a chain is reused in this way.
|
||||||
|
// For proper middleware, this should cause no problems.
|
||||||
|
//
|
||||||
|
// Then() treats nil as http.DefaultServeMux.
|
||||||
|
func (c Chain) Then(h http.Handler) http.Handler {
|
||||||
|
if h == nil {
|
||||||
|
h = http.DefaultServeMux
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range c.constructors {
|
||||||
|
h = c.constructors[len(c.constructors)-1-i](h)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
// ThenFunc works identically to Then, but takes
|
||||||
|
// a HandlerFunc instead of a Handler.
|
||||||
|
//
|
||||||
|
// The following two statements are equivalent:
|
||||||
|
// c.Then(http.HandlerFunc(fn))
|
||||||
|
// c.ThenFunc(fn)
|
||||||
|
//
|
||||||
|
// ThenFunc provides all the guarantees of Then.
|
||||||
|
func (c Chain) ThenFunc(fn http.HandlerFunc) http.Handler {
|
||||||
|
if fn == nil {
|
||||||
|
return c.Then(nil)
|
||||||
|
}
|
||||||
|
return c.Then(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append extends a chain, adding the specified constructors
|
||||||
|
// as the last ones in the request flow.
|
||||||
|
//
|
||||||
|
// Append returns a new chain, leaving the original one untouched.
|
||||||
|
//
|
||||||
|
// stdChain := alice.New(m1, m2)
|
||||||
|
// extChain := stdChain.Append(m3, m4)
|
||||||
|
// // requests in stdChain go m1 -> m2
|
||||||
|
// // requests in extChain go m1 -> m2 -> m3 -> m4
|
||||||
|
func (c Chain) Append(constructors ...Constructor) Chain {
|
||||||
|
newCons := make([]Constructor, 0, len(c.constructors)+len(constructors))
|
||||||
|
newCons = append(newCons, c.constructors...)
|
||||||
|
newCons = append(newCons, constructors...)
|
||||||
|
|
||||||
|
return Chain{newCons}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend extends a chain by adding the specified chain
|
||||||
|
// as the last one in the request flow.
|
||||||
|
//
|
||||||
|
// Extend returns a new chain, leaving the original one untouched.
|
||||||
|
//
|
||||||
|
// stdChain := alice.New(m1, m2)
|
||||||
|
// ext1Chain := alice.New(m3, m4)
|
||||||
|
// ext2Chain := stdChain.Extend(ext1Chain)
|
||||||
|
// // requests in stdChain go m1 -> m2
|
||||||
|
// // requests in ext1Chain go m3 -> m4
|
||||||
|
// // requests in ext2Chain go m1 -> m2 -> m3 -> m4
|
||||||
|
//
|
||||||
|
// Another example:
|
||||||
|
// aHtmlAfterNosurf := alice.New(m2)
|
||||||
|
// aHtml := alice.New(m1, func(h http.Handler) http.Handler {
|
||||||
|
// csrf := nosurf.New(h)
|
||||||
|
// csrf.SetFailureHandler(aHtmlAfterNosurf.ThenFunc(csrfFail))
|
||||||
|
// return csrf
|
||||||
|
// }).Extend(aHtmlAfterNosurf)
|
||||||
|
// // requests to aHtml hitting nosurfs success handler go m1 -> nosurf -> m2 -> target-handler
|
||||||
|
// // requests to aHtml hitting nosurfs failure handler go m1 -> nosurf -> m2 -> csrfFail
|
||||||
|
func (c Chain) Extend(chain Chain) Chain {
|
||||||
|
return c.Append(chain.constructors...)
|
||||||
|
}
|
3
vendor/github.com/justinas/alice/go.mod
generated
vendored
Normal file
3
vendor/github.com/justinas/alice/go.mod
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module github.com/justinas/alice
|
||||||
|
|
||||||
|
go 1.12
|
27
vendor/github.com/rs/xid/.appveyor.yml
generated
vendored
Normal file
27
vendor/github.com/rs/xid/.appveyor.yml
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
version: 1.0.0.{build}
|
||||||
|
|
||||||
|
platform: x64
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
clone_folder: c:\gopath\src\github.com\rs\xid
|
||||||
|
|
||||||
|
environment:
|
||||||
|
GOPATH: c:\gopath
|
||||||
|
|
||||||
|
install:
|
||||||
|
- echo %PATH%
|
||||||
|
- echo %GOPATH%
|
||||||
|
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
|
||||||
|
- go version
|
||||||
|
- go env
|
||||||
|
- go get -t .
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- go build
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- go test
|
||||||
|
|
8
vendor/github.com/rs/xid/.travis.yml
generated
vendored
Normal file
8
vendor/github.com/rs/xid/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
language: go
|
||||||
|
go:
|
||||||
|
- "1.9"
|
||||||
|
- "1.10"
|
||||||
|
- "master"
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: "master"
|
19
vendor/github.com/rs/xid/LICENSE
generated
vendored
Normal file
19
vendor/github.com/rs/xid/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2015 Olivier Poitrey <rs@dailymotion.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
115
vendor/github.com/rs/xid/README.md
generated
vendored
Normal file
115
vendor/github.com/rs/xid/README.md
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# Globally Unique ID Generator
|
||||||
|
|
||||||
|
[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/xid) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/xid/master/LICENSE) [![Build Status](https://travis-ci.org/rs/xid.svg?branch=master)](https://travis-ci.org/rs/xid) [![Coverage](http://gocover.io/_badge/github.com/rs/xid)](http://gocover.io/github.com/rs/xid)
|
||||||
|
|
||||||
|
Package xid is a globally unique id generator library, ready to safely be used directly in your server code.
|
||||||
|
|
||||||
|
Xid uses the Mongo Object ID algorithm to generate globally unique ids with a different serialization (base64) to make it shorter when transported as a string:
|
||||||
|
https://docs.mongodb.org/manual/reference/object-id/
|
||||||
|
|
||||||
|
- 4-byte value representing the seconds since the Unix epoch,
|
||||||
|
- 3-byte machine identifier,
|
||||||
|
- 2-byte process id, and
|
||||||
|
- 3-byte counter, starting with a random value.
|
||||||
|
|
||||||
|
The binary representation of the id is compatible with Mongo 12 bytes Object IDs.
|
||||||
|
The string representation is using base32 hex (w/o padding) for better space efficiency
|
||||||
|
when stored in that form (20 bytes). The hex variant of base32 is used to retain the
|
||||||
|
sortable property of the id.
|
||||||
|
|
||||||
|
Xid doesn't use base64 because case sensitivity and the 2 non alphanum chars may be an
|
||||||
|
issue when transported as a string between various systems. Base36 wasn't retained either
|
||||||
|
because 1/ it's not standard 2/ the resulting size is not predictable (not bit aligned)
|
||||||
|
and 3/ it would not remain sortable. To validate a base32 `xid`, expect a 20 chars long,
|
||||||
|
all lowercase sequence of `a` to `v` letters and `0` to `9` numbers (`[0-9a-v]{20}`).
|
||||||
|
|
||||||
|
UUIDs are 16 bytes (128 bits) and 36 chars as string representation. Twitter Snowflake
|
||||||
|
ids are 8 bytes (64 bits) but require machine/data-center configuration and/or central
|
||||||
|
generator servers. xid stands in between with 12 bytes (96 bits) and a more compact
|
||||||
|
URL-safe string representation (20 chars). No configuration or central generator server
|
||||||
|
is required so it can be used directly in server's code.
|
||||||
|
|
||||||
|
| Name | Binary Size | String Size | Features
|
||||||
|
|-------------|-------------|----------------|----------------
|
||||||
|
| [UUID] | 16 bytes | 36 chars | configuration free, not sortable
|
||||||
|
| [shortuuid] | 16 bytes | 22 chars | configuration free, not sortable
|
||||||
|
| [Snowflake] | 8 bytes | up to 20 chars | needs machine/DC configuration, needs central server, sortable
|
||||||
|
| [MongoID] | 12 bytes | 24 chars | configuration free, sortable
|
||||||
|
| xid | 12 bytes | 20 chars | configuration free, sortable
|
||||||
|
|
||||||
|
[UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier
|
||||||
|
[shortuuid]: https://github.com/stochastic-technologies/shortuuid
|
||||||
|
[Snowflake]: https://blog.twitter.com/2010/announcing-snowflake
|
||||||
|
[MongoID]: https://docs.mongodb.org/manual/reference/object-id/
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
- Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake
|
||||||
|
- Base32 hex encoded by default (20 chars when transported as printable string, still sortable)
|
||||||
|
- Non configured, you don't need set a unique machine and/or data center id
|
||||||
|
- K-ordered
|
||||||
|
- Embedded time with 1 second precision
|
||||||
|
- Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process
|
||||||
|
- Lock-free (i.e.: unlike UUIDv1 and v2)
|
||||||
|
|
||||||
|
Best used with [zerolog](https://github.com/rs/zerolog)'s
|
||||||
|
[RequestIDHandler](https://godoc.org/github.com/rs/zerolog/hlog#RequestIDHandler).
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- Xid is dependent on the system time, a monotonic counter and so is not cryptographically secure. If unpredictability of IDs is important, you should not use Xids. It is worth noting that most other UUID-like implementations are also not cryptographically secure. You should use libraries that rely on cryptographically secure sources (like /dev/urandom on unix, crypto/rand in golang), if you want a truly random ID generator.
|
||||||
|
|
||||||
|
References:
|
||||||
|
|
||||||
|
- http://www.slideshare.net/davegardnerisme/unique-id-generation-in-distributed-systems
|
||||||
|
- https://en.wikipedia.org/wiki/Universally_unique_identifier
|
||||||
|
- https://blog.twitter.com/2010/announcing-snowflake
|
||||||
|
- Python port by [Graham Abbott](https://github.com/graham): https://github.com/graham/python_xid
|
||||||
|
- Scala port by [Egor Kolotaev](https://github.com/kolotaev): https://github.com/kolotaev/ride
|
||||||
|
- Rust port by [Jérôme Renard](https://github.com/jeromer/): https://github.com/jeromer/libxid
|
||||||
|
- Ruby port by [Valar](https://github.com/valarpirai/): https://github.com/valarpirai/ruby_xid
|
||||||
|
- Java port by [0xShamil](https://github.com/0xShamil/): https://github.com/0xShamil/java-xid
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
go get github.com/rs/xid
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
guid := xid.New()
|
||||||
|
|
||||||
|
println(guid.String())
|
||||||
|
// Output: 9m4e2mr0ui3e8a215n4g
|
||||||
|
```
|
||||||
|
|
||||||
|
Get `xid` embedded info:
|
||||||
|
|
||||||
|
```go
|
||||||
|
guid.Machine()
|
||||||
|
guid.Pid()
|
||||||
|
guid.Time()
|
||||||
|
guid.Counter()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benchmark
|
||||||
|
|
||||||
|
Benchmark against Go [Maxim Bublis](https://github.com/satori)'s [UUID](https://github.com/satori/go.uuid).
|
||||||
|
|
||||||
|
```
|
||||||
|
BenchmarkXID 20000000 91.1 ns/op 32 B/op 1 allocs/op
|
||||||
|
BenchmarkXID-2 20000000 55.9 ns/op 32 B/op 1 allocs/op
|
||||||
|
BenchmarkXID-4 50000000 32.3 ns/op 32 B/op 1 allocs/op
|
||||||
|
BenchmarkUUIDv1 10000000 204 ns/op 48 B/op 1 allocs/op
|
||||||
|
BenchmarkUUIDv1-2 10000000 160 ns/op 48 B/op 1 allocs/op
|
||||||
|
BenchmarkUUIDv1-4 10000000 195 ns/op 48 B/op 1 allocs/op
|
||||||
|
BenchmarkUUIDv4 1000000 1503 ns/op 64 B/op 2 allocs/op
|
||||||
|
BenchmarkUUIDv4-2 1000000 1427 ns/op 64 B/op 2 allocs/op
|
||||||
|
BenchmarkUUIDv4-4 1000000 1452 ns/op 64 B/op 2 allocs/op
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: UUIDv1 requires a global lock, hence the performance degradation as we add more CPUs.
|
||||||
|
|
||||||
|
## Licenses
|
||||||
|
|
||||||
|
All source code is licensed under the [MIT License](https://raw.github.com/rs/xid/master/LICENSE).
|
3
vendor/github.com/rs/xid/go.mod
generated
vendored
Normal file
3
vendor/github.com/rs/xid/go.mod
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module github.com/rs/xid
|
||||||
|
|
||||||
|
go 1.12
|
9
vendor/github.com/rs/xid/hostid_darwin.go
generated
vendored
Normal file
9
vendor/github.com/rs/xid/hostid_darwin.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package xid
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func readPlatformMachineID() (string, error) {
|
||||||
|
return syscall.Sysctl("kern.uuid")
|
||||||
|
}
|
9
vendor/github.com/rs/xid/hostid_fallback.go
generated
vendored
Normal file
9
vendor/github.com/rs/xid/hostid_fallback.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build !darwin,!linux,!freebsd,!windows
|
||||||
|
|
||||||
|
package xid
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
func readPlatformMachineID() (string, error) {
|
||||||
|
return "", errors.New("not implemented")
|
||||||
|
}
|
9
vendor/github.com/rs/xid/hostid_freebsd.go
generated
vendored
Normal file
9
vendor/github.com/rs/xid/hostid_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build freebsd
|
||||||
|
|
||||||
|
package xid
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func readPlatformMachineID() (string, error) {
|
||||||
|
return syscall.Sysctl("kern.hostuuid")
|
||||||
|
}
|
13
vendor/github.com/rs/xid/hostid_linux.go
generated
vendored
Normal file
13
vendor/github.com/rs/xid/hostid_linux.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// +build linux
|
||||||
|
|
||||||
|
package xid
|
||||||
|
|
||||||
|
import "io/ioutil"
|
||||||
|
|
||||||
|
func readPlatformMachineID() (string, error) {
|
||||||
|
b, err := ioutil.ReadFile("/etc/machine-id")
|
||||||
|
if err != nil || len(b) == 0 {
|
||||||
|
b, err = ioutil.ReadFile("/sys/class/dmi/id/product_uuid")
|
||||||
|
}
|
||||||
|
return string(b), err
|
||||||
|
}
|
38
vendor/github.com/rs/xid/hostid_windows.go
generated
vendored
Normal file
38
vendor/github.com/rs/xid/hostid_windows.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package xid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func readPlatformMachineID() (string, error) {
|
||||||
|
// source: https://github.com/shirou/gopsutil/blob/master/host/host_syscall.go
|
||||||
|
var h syscall.Handle
|
||||||
|
err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(`SOFTWARE\Microsoft\Cryptography`), 0, syscall.KEY_READ|syscall.KEY_WOW64_64KEY, &h)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer syscall.RegCloseKey(h)
|
||||||
|
|
||||||
|
const syscallRegBufLen = 74 // len(`{`) + len(`abcdefgh-1234-456789012-123345456671` * 2) + len(`}`) // 2 == bytes/UTF16
|
||||||
|
const uuidLen = 36
|
||||||
|
|
||||||
|
var regBuf [syscallRegBufLen]uint16
|
||||||
|
bufLen := uint32(syscallRegBufLen)
|
||||||
|
var valType uint32
|
||||||
|
err = syscall.RegQueryValueEx(h, syscall.StringToUTF16Ptr(`MachineGuid`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
hostID := syscall.UTF16ToString(regBuf[:])
|
||||||
|
hostIDLen := len(hostID)
|
||||||
|
if hostIDLen != uuidLen {
|
||||||
|
return "", fmt.Errorf("HostID incorrect: %q\n", hostID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return hostID, nil
|
||||||
|
}
|
380
vendor/github.com/rs/xid/id.go
generated
vendored
Normal file
380
vendor/github.com/rs/xid/id.go
generated
vendored
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
// Package xid is a globally unique id generator suited for web scale
|
||||||
|
//
|
||||||
|
// Xid is using Mongo Object ID algorithm to generate globally unique ids:
|
||||||
|
// https://docs.mongodb.org/manual/reference/object-id/
|
||||||
|
//
|
||||||
|
// - 4-byte value representing the seconds since the Unix epoch,
|
||||||
|
// - 3-byte machine identifier,
|
||||||
|
// - 2-byte process id, and
|
||||||
|
// - 3-byte counter, starting with a random value.
|
||||||
|
//
|
||||||
|
// The binary representation of the id is compatible with Mongo 12 bytes Object IDs.
|
||||||
|
// The string representation is using base32 hex (w/o padding) for better space efficiency
|
||||||
|
// when stored in that form (20 bytes). The hex variant of base32 is used to retain the
|
||||||
|
// sortable property of the id.
|
||||||
|
//
|
||||||
|
// Xid doesn't use base64 because case sensitivity and the 2 non alphanum chars may be an
|
||||||
|
// issue when transported as a string between various systems. Base36 wasn't retained either
|
||||||
|
// because 1/ it's not standard 2/ the resulting size is not predictable (not bit aligned)
|
||||||
|
// and 3/ it would not remain sortable. To validate a base32 `xid`, expect a 20 chars long,
|
||||||
|
// all lowercase sequence of `a` to `v` letters and `0` to `9` numbers (`[0-9a-v]{20}`).
|
||||||
|
//
|
||||||
|
// UUID is 16 bytes (128 bits), snowflake is 8 bytes (64 bits), xid stands in between
|
||||||
|
// with 12 bytes with a more compact string representation ready for the web and no
|
||||||
|
// required configuration or central generation server.
|
||||||
|
//
|
||||||
|
// Features:
|
||||||
|
//
|
||||||
|
// - Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake
|
||||||
|
// - Base32 hex encoded by default (16 bytes storage when transported as printable string)
|
||||||
|
// - Non configured, you don't need set a unique machine and/or data center id
|
||||||
|
// - K-ordered
|
||||||
|
// - Embedded time with 1 second precision
|
||||||
|
// - Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process
|
||||||
|
//
|
||||||
|
// Best used with xlog's RequestIDHandler (https://godoc.org/github.com/rs/xlog#RequestIDHandler).
|
||||||
|
//
|
||||||
|
// References:
|
||||||
|
//
|
||||||
|
// - http://www.slideshare.net/davegardnerisme/unique-id-generation-in-distributed-systems
|
||||||
|
// - https://en.wikipedia.org/wiki/Universally_unique_identifier
|
||||||
|
// - https://blog.twitter.com/2010/announcing-snowflake
|
||||||
|
package xid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/rand"
|
||||||
|
"database/sql/driver"
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"hash/crc32"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Code inspired from mgo/bson ObjectId
|
||||||
|
|
||||||
|
// ID represents a unique request id
|
||||||
|
type ID [rawLen]byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
encodedLen = 20 // string encoded len
|
||||||
|
rawLen = 12 // binary raw len
|
||||||
|
|
||||||
|
// encoding stores a custom version of the base32 encoding with lower case
|
||||||
|
// letters.
|
||||||
|
encoding = "0123456789abcdefghijklmnopqrstuv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrInvalidID is returned when trying to unmarshal an invalid ID
|
||||||
|
ErrInvalidID = errors.New("xid: invalid ID")
|
||||||
|
|
||||||
|
// objectIDCounter is atomically incremented when generating a new ObjectId
|
||||||
|
// using NewObjectId() function. It's used as a counter part of an id.
|
||||||
|
// This id is initialized with a random value.
|
||||||
|
objectIDCounter = randInt()
|
||||||
|
|
||||||
|
// machineId stores machine id generated once and used in subsequent calls
|
||||||
|
// to NewObjectId function.
|
||||||
|
machineID = readMachineID()
|
||||||
|
|
||||||
|
// pid stores the current process id
|
||||||
|
pid = os.Getpid()
|
||||||
|
|
||||||
|
nilID ID
|
||||||
|
|
||||||
|
// dec is the decoding map for base32 encoding
|
||||||
|
dec [256]byte
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
for i := 0; i < len(dec); i++ {
|
||||||
|
dec[i] = 0xFF
|
||||||
|
}
|
||||||
|
for i := 0; i < len(encoding); i++ {
|
||||||
|
dec[encoding[i]] = byte(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If /proc/self/cpuset exists and is not /, we can assume that we are in a
|
||||||
|
// form of container and use the content of cpuset xor-ed with the PID in
|
||||||
|
// order get a reasonable machine global unique PID.
|
||||||
|
b, err := ioutil.ReadFile("/proc/self/cpuset")
|
||||||
|
if err == nil && len(b) > 1 {
|
||||||
|
pid ^= int(crc32.ChecksumIEEE(b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// readMachineId generates machine id and puts it into the machineId global
|
||||||
|
// variable. If this function fails to get the hostname, it will cause
|
||||||
|
// a runtime error.
|
||||||
|
func readMachineID() []byte {
|
||||||
|
id := make([]byte, 3)
|
||||||
|
hid, err := readPlatformMachineID()
|
||||||
|
if err != nil || len(hid) == 0 {
|
||||||
|
hid, err = os.Hostname()
|
||||||
|
}
|
||||||
|
if err == nil && len(hid) != 0 {
|
||||||
|
hw := md5.New()
|
||||||
|
hw.Write([]byte(hid))
|
||||||
|
copy(id, hw.Sum(nil))
|
||||||
|
} else {
|
||||||
|
// Fallback to rand number if machine id can't be gathered
|
||||||
|
if _, randErr := rand.Reader.Read(id); randErr != nil {
|
||||||
|
panic(fmt.Errorf("xid: cannot get hostname nor generate a random number: %v; %v", err, randErr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
// randInt generates a random uint32
|
||||||
|
func randInt() uint32 {
|
||||||
|
b := make([]byte, 3)
|
||||||
|
if _, err := rand.Reader.Read(b); err != nil {
|
||||||
|
panic(fmt.Errorf("xid: cannot generate random number: %v;", err))
|
||||||
|
}
|
||||||
|
return uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
// New generates a globally unique ID
|
||||||
|
func New() ID {
|
||||||
|
return NewWithTime(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWithTime generates a globally unique ID with the passed in time
|
||||||
|
func NewWithTime(t time.Time) ID {
|
||||||
|
var id ID
|
||||||
|
// Timestamp, 4 bytes, big endian
|
||||||
|
binary.BigEndian.PutUint32(id[:], uint32(t.Unix()))
|
||||||
|
// Machine, first 3 bytes of md5(hostname)
|
||||||
|
id[4] = machineID[0]
|
||||||
|
id[5] = machineID[1]
|
||||||
|
id[6] = machineID[2]
|
||||||
|
// Pid, 2 bytes, specs don't specify endianness, but we use big endian.
|
||||||
|
id[7] = byte(pid >> 8)
|
||||||
|
id[8] = byte(pid)
|
||||||
|
// Increment, 3 bytes, big endian
|
||||||
|
i := atomic.AddUint32(&objectIDCounter, 1)
|
||||||
|
id[9] = byte(i >> 16)
|
||||||
|
id[10] = byte(i >> 8)
|
||||||
|
id[11] = byte(i)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString reads an ID from its string representation
|
||||||
|
func FromString(id string) (ID, error) {
|
||||||
|
i := &ID{}
|
||||||
|
err := i.UnmarshalText([]byte(id))
|
||||||
|
return *i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a base32 hex lowercased with no padding representation of the id (char set is 0-9, a-v).
|
||||||
|
func (id ID) String() string {
|
||||||
|
text := make([]byte, encodedLen)
|
||||||
|
encode(text, id[:])
|
||||||
|
return *(*string)(unsafe.Pointer(&text))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encodes the id using base32 encoding, writing 20 bytes to dst and return it.
|
||||||
|
func (id ID) Encode(dst []byte) []byte {
|
||||||
|
encode(dst, id[:])
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText implements encoding/text TextMarshaler interface
|
||||||
|
func (id ID) MarshalText() ([]byte, error) {
|
||||||
|
text := make([]byte, encodedLen)
|
||||||
|
encode(text, id[:])
|
||||||
|
return text, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements encoding/json Marshaler interface
|
||||||
|
func (id ID) MarshalJSON() ([]byte, error) {
|
||||||
|
if id.IsNil() {
|
||||||
|
return []byte("null"), nil
|
||||||
|
}
|
||||||
|
text := make([]byte, encodedLen+2)
|
||||||
|
encode(text[1:encodedLen+1], id[:])
|
||||||
|
text[0], text[encodedLen+1] = '"', '"'
|
||||||
|
return text, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encode by unrolling the stdlib base32 algorithm + removing all safe checks
|
||||||
|
func encode(dst, id []byte) {
|
||||||
|
_ = dst[19]
|
||||||
|
_ = id[11]
|
||||||
|
|
||||||
|
dst[19] = encoding[(id[11]<<4)&0x1F]
|
||||||
|
dst[18] = encoding[(id[11]>>1)&0x1F]
|
||||||
|
dst[17] = encoding[(id[11]>>6)&0x1F|(id[10]<<2)&0x1F]
|
||||||
|
dst[16] = encoding[id[10]>>3]
|
||||||
|
dst[15] = encoding[id[9]&0x1F]
|
||||||
|
dst[14] = encoding[(id[9]>>5)|(id[8]<<3)&0x1F]
|
||||||
|
dst[13] = encoding[(id[8]>>2)&0x1F]
|
||||||
|
dst[12] = encoding[id[8]>>7|(id[7]<<1)&0x1F]
|
||||||
|
dst[11] = encoding[(id[7]>>4)&0x1F|(id[6]<<4)&0x1F]
|
||||||
|
dst[10] = encoding[(id[6]>>1)&0x1F]
|
||||||
|
dst[9] = encoding[(id[6]>>6)&0x1F|(id[5]<<2)&0x1F]
|
||||||
|
dst[8] = encoding[id[5]>>3]
|
||||||
|
dst[7] = encoding[id[4]&0x1F]
|
||||||
|
dst[6] = encoding[id[4]>>5|(id[3]<<3)&0x1F]
|
||||||
|
dst[5] = encoding[(id[3]>>2)&0x1F]
|
||||||
|
dst[4] = encoding[id[3]>>7|(id[2]<<1)&0x1F]
|
||||||
|
dst[3] = encoding[(id[2]>>4)&0x1F|(id[1]<<4)&0x1F]
|
||||||
|
dst[2] = encoding[(id[1]>>1)&0x1F]
|
||||||
|
dst[1] = encoding[(id[1]>>6)&0x1F|(id[0]<<2)&0x1F]
|
||||||
|
dst[0] = encoding[id[0]>>3]
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText implements encoding/text TextUnmarshaler interface
|
||||||
|
func (id *ID) UnmarshalText(text []byte) error {
|
||||||
|
if len(text) != encodedLen {
|
||||||
|
return ErrInvalidID
|
||||||
|
}
|
||||||
|
for _, c := range text {
|
||||||
|
if dec[c] == 0xFF {
|
||||||
|
return ErrInvalidID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decode(id, text)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements encoding/json Unmarshaler interface
|
||||||
|
func (id *ID) UnmarshalJSON(b []byte) error {
|
||||||
|
s := string(b)
|
||||||
|
if s == "null" {
|
||||||
|
*id = nilID
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return id.UnmarshalText(b[1 : len(b)-1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode by unrolling the stdlib base32 algorithm + removing all safe checks
|
||||||
|
func decode(id *ID, src []byte) {
|
||||||
|
_ = src[19]
|
||||||
|
_ = id[11]
|
||||||
|
|
||||||
|
id[11] = dec[src[17]]<<6 | dec[src[18]]<<1 | dec[src[19]]>>4
|
||||||
|
id[10] = dec[src[16]]<<3 | dec[src[17]]>>2
|
||||||
|
id[9] = dec[src[14]]<<5 | dec[src[15]]
|
||||||
|
id[8] = dec[src[12]]<<7 | dec[src[13]]<<2 | dec[src[14]]>>3
|
||||||
|
id[7] = dec[src[11]]<<4 | dec[src[12]]>>1
|
||||||
|
id[6] = dec[src[9]]<<6 | dec[src[10]]<<1 | dec[src[11]]>>4
|
||||||
|
id[5] = dec[src[8]]<<3 | dec[src[9]]>>2
|
||||||
|
id[4] = dec[src[6]]<<5 | dec[src[7]]
|
||||||
|
id[3] = dec[src[4]]<<7 | dec[src[5]]<<2 | dec[src[6]]>>3
|
||||||
|
id[2] = dec[src[3]]<<4 | dec[src[4]]>>1
|
||||||
|
id[1] = dec[src[1]]<<6 | dec[src[2]]<<1 | dec[src[3]]>>4
|
||||||
|
id[0] = dec[src[0]]<<3 | dec[src[1]]>>2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time returns the timestamp part of the id.
|
||||||
|
// It's a runtime error to call this method with an invalid id.
|
||||||
|
func (id ID) Time() time.Time {
|
||||||
|
// First 4 bytes of ObjectId is 32-bit big-endian seconds from epoch.
|
||||||
|
secs := int64(binary.BigEndian.Uint32(id[0:4]))
|
||||||
|
return time.Unix(secs, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Machine returns the 3-byte machine id part of the id.
|
||||||
|
// It's a runtime error to call this method with an invalid id.
|
||||||
|
func (id ID) Machine() []byte {
|
||||||
|
return id[4:7]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pid returns the process id part of the id.
|
||||||
|
// It's a runtime error to call this method with an invalid id.
|
||||||
|
func (id ID) Pid() uint16 {
|
||||||
|
return binary.BigEndian.Uint16(id[7:9])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Counter returns the incrementing value part of the id.
|
||||||
|
// It's a runtime error to call this method with an invalid id.
|
||||||
|
func (id ID) Counter() int32 {
|
||||||
|
b := id[9:12]
|
||||||
|
// Counter is stored as big-endian 3-byte value
|
||||||
|
return int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements the driver.Valuer interface.
|
||||||
|
func (id ID) Value() (driver.Value, error) {
|
||||||
|
if id.IsNil() {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
b, err := id.MarshalText()
|
||||||
|
return string(b), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan implements the sql.Scanner interface.
|
||||||
|
func (id *ID) Scan(value interface{}) (err error) {
|
||||||
|
switch val := value.(type) {
|
||||||
|
case string:
|
||||||
|
return id.UnmarshalText([]byte(val))
|
||||||
|
case []byte:
|
||||||
|
return id.UnmarshalText(val)
|
||||||
|
case nil:
|
||||||
|
*id = nilID
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("xid: scanning unsupported type: %T", value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNil Returns true if this is a "nil" ID
|
||||||
|
func (id ID) IsNil() bool {
|
||||||
|
return id == nilID
|
||||||
|
}
|
||||||
|
|
||||||
|
// NilID returns a zero value for `xid.ID`.
|
||||||
|
func NilID() ID {
|
||||||
|
return nilID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns the byte array representation of `ID`
|
||||||
|
func (id ID) Bytes() []byte {
|
||||||
|
return id[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromBytes convert the byte array representation of `ID` back to `ID`
|
||||||
|
func FromBytes(b []byte) (ID, error) {
|
||||||
|
var id ID
|
||||||
|
if len(b) != rawLen {
|
||||||
|
return id, ErrInvalidID
|
||||||
|
}
|
||||||
|
copy(id[:], b)
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare returns an integer comparing two IDs. It behaves just like `bytes.Compare`.
|
||||||
|
// The result will be 0 if two IDs are identical, -1 if current id is less than the other one,
|
||||||
|
// and 1 if current id is greater than the other.
|
||||||
|
func (id ID) Compare(other ID) int {
|
||||||
|
return bytes.Compare(id[:], other[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
type sorter []ID
|
||||||
|
|
||||||
|
func (s sorter) Len() int {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s sorter) Less(i, j int) bool {
|
||||||
|
return s[i].Compare(s[j]) < 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s sorter) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort sorts an array of IDs inplace.
|
||||||
|
// It works by wrapping `[]ID` and use `sort.Sort`.
|
||||||
|
func Sort(ids []ID) {
|
||||||
|
sort.Sort(sorter(ids))
|
||||||
|
}
|
15
vendor/github.com/rs/zerolog/.travis.yml
generated
vendored
15
vendor/github.com/rs/zerolog/.travis.yml
generated
vendored
@ -1,15 +0,0 @@
|
|||||||
language: go
|
|
||||||
go:
|
|
||||||
- "1.7"
|
|
||||||
- "1.8"
|
|
||||||
- "1.9"
|
|
||||||
- "1.10"
|
|
||||||
- "1.11"
|
|
||||||
- "1.12"
|
|
||||||
- "master"
|
|
||||||
matrix:
|
|
||||||
allow_failures:
|
|
||||||
- go: "master"
|
|
||||||
script:
|
|
||||||
- go test -v -race -cpu=1,2,4 -bench . -benchmem ./...
|
|
||||||
- go test -v -tags binary_log -race -cpu=1,2,4 -bench . -benchmem ./...
|
|
99
vendor/github.com/rs/zerolog/README.md
generated
vendored
99
vendor/github.com/rs/zerolog/README.md
generated
vendored
@ -18,16 +18,17 @@ Find out [who uses zerolog](https://github.com/rs/zerolog/wiki/Who-uses-zerolog)
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Blazing fast
|
* [Blazing fast](#benchmarks)
|
||||||
* Low to zero allocation
|
* [Low to zero allocation](#benchmarks)
|
||||||
* Level logging
|
* [Leveled logging](#leveled-logging)
|
||||||
* Sampling
|
* [Sampling](#log-sampling)
|
||||||
* Hooks
|
* [Hooks](#hooks)
|
||||||
* Contextual fields
|
* [Contextual fields](#contextual-logging)
|
||||||
* `context.Context` integration
|
* `context.Context` integration
|
||||||
* `net/http` helpers
|
* [Integration with `net/http`](#integration-with-nethttp)
|
||||||
* JSON and CBOR encoding formats
|
* [JSON and CBOR encoding formats](#binary-encoding)
|
||||||
* Pretty logging for development
|
* [Pretty logging for development](#pretty-logging)
|
||||||
|
* [Error Logging (with optional Stacktrace)](#error-logging)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@ -51,8 +52,6 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// UNIX Time is faster and smaller than most timestamps
|
// UNIX Time is faster and smaller than most timestamps
|
||||||
// If you set zerolog.TimeFieldFormat to an empty string,
|
|
||||||
// logs will write with UNIX time
|
|
||||||
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
|
||||||
log.Print("hello world")
|
log.Print("hello world")
|
||||||
@ -205,6 +204,80 @@ func main() {
|
|||||||
// Output: {"time":1494567715,"foo":"bar"}
|
// Output: {"time":1494567715,"foo":"bar"}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Error Logging
|
||||||
|
|
||||||
|
You can log errors using the `Err` method
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
|
||||||
|
err := errors.New("seems we have an error here")
|
||||||
|
log.Error().Err(err).Msg("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"level":"error","error":"seems we have an error here","time":1609085256}
|
||||||
|
```
|
||||||
|
|
||||||
|
> The default field name for errors is `error`, you can change this by setting `zerolog.ErrorFieldName` to meet your needs.
|
||||||
|
|
||||||
|
#### Error Logging with Stacktrace
|
||||||
|
|
||||||
|
Using `github.com/pkg/errors`, you can add a formatted stacktrace to your errors.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/rs/zerolog/pkgerrors"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||||
|
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
|
||||||
|
|
||||||
|
err := outer()
|
||||||
|
log.Error().Stack().Err(err).Msg("")
|
||||||
|
}
|
||||||
|
|
||||||
|
func inner() error {
|
||||||
|
return errors.New("seems we have an error here")
|
||||||
|
}
|
||||||
|
|
||||||
|
func middle() error {
|
||||||
|
err := inner()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func outer() error {
|
||||||
|
err := middle()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: {"level":"error","stack":[{"func":"inner","line":"20","source":"errors.go"},{"func":"middle","line":"24","source":"errors.go"},{"func":"outer","line":"32","source":"errors.go"},{"func":"main","line":"15","source":"errors.go"},{"func":"main","line":"204","source":"proc.go"},{"func":"goexit","line":"1374","source":"asm_amd64.s"}],"error":"seems we have an error here","time":1609086683}
|
||||||
|
```
|
||||||
|
|
||||||
|
> zerolog.ErrorStackMarshaler must be set in order for the stack to output anything.
|
||||||
|
|
||||||
#### Logging Fatal Messages
|
#### Logging Fatal Messages
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -235,6 +308,7 @@ func main() {
|
|||||||
|
|
||||||
> NOTE: Using `Msgf` generates one allocation even when the logger is disabled.
|
> NOTE: Using `Msgf` generates one allocation even when the logger is disabled.
|
||||||
|
|
||||||
|
|
||||||
### Create logger instance to manage different outputs
|
### Create logger instance to manage different outputs
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -517,6 +591,7 @@ Some settings can be changed and will by applied to all loggers:
|
|||||||
### Advanced Fields
|
### Advanced Fields
|
||||||
|
|
||||||
* `Err`: Takes an `error` and renders it as a string using the `zerolog.ErrorFieldName` field name.
|
* `Err`: Takes an `error` and renders it as a string using the `zerolog.ErrorFieldName` field name.
|
||||||
|
* `Func`: Run a `func` only if the level is enabled.
|
||||||
* `Timestamp`: Inserts a timestamp field with `zerolog.TimestampFieldName` field name, formatted using `zerolog.TimeFieldFormat`.
|
* `Timestamp`: Inserts a timestamp field with `zerolog.TimestampFieldName` field name, formatted using `zerolog.TimeFieldFormat`.
|
||||||
* `Time`: Adds a field with time formatted with `zerolog.TimeFieldFormat`.
|
* `Time`: Adds a field with time formatted with `zerolog.TimeFieldFormat`.
|
||||||
* `Dur`: Adds a field with `time.Duration`.
|
* `Dur`: Adds a field with `time.Duration`.
|
||||||
@ -541,6 +616,8 @@ with zerolog library is [CSD](https://github.com/toravir/csd/).
|
|||||||
## Related Projects
|
## Related Projects
|
||||||
|
|
||||||
* [grpc-zerolog](https://github.com/cheapRoc/grpc-zerolog): Implementation of `grpclog.LoggerV2` interface using `zerolog`
|
* [grpc-zerolog](https://github.com/cheapRoc/grpc-zerolog): Implementation of `grpclog.LoggerV2` interface using `zerolog`
|
||||||
|
* [overlog](https://github.com/Trendyol/overlog): Implementation of `Mapped Diagnostic Context` interface using `zerolog`
|
||||||
|
* [zerologr](https://github.com/go-logr/zerologr): Implementation of `logr.LogSink` interface using `zerolog`
|
||||||
|
|
||||||
## Benchmarks
|
## Benchmarks
|
||||||
|
|
||||||
|
7
vendor/github.com/rs/zerolog/array.go
generated
vendored
7
vendor/github.com/rs/zerolog/array.go
generated
vendored
@ -231,3 +231,10 @@ func (a *Array) MACAddr(ha net.HardwareAddr) *Array {
|
|||||||
a.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha)
|
a.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha)
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dict adds the dict Event to the array
|
||||||
|
func (a *Array) Dict(dict *Event) *Array {
|
||||||
|
dict.buf = enc.AppendEndMarker(dict.buf)
|
||||||
|
a.buf = append(enc.AppendArrayDelim(a.buf), dict.buf...)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
36
vendor/github.com/rs/zerolog/console.go
generated
vendored
36
vendor/github.com/rs/zerolog/console.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -57,6 +58,9 @@ type ConsoleWriter struct {
|
|||||||
// PartsOrder defines the order of parts in output.
|
// PartsOrder defines the order of parts in output.
|
||||||
PartsOrder []string
|
PartsOrder []string
|
||||||
|
|
||||||
|
// PartsExclude defines parts to not display in output.
|
||||||
|
PartsExclude []string
|
||||||
|
|
||||||
FormatTimestamp Formatter
|
FormatTimestamp Formatter
|
||||||
FormatLevel Formatter
|
FormatLevel Formatter
|
||||||
FormatCaller Formatter
|
FormatCaller Formatter
|
||||||
@ -208,6 +212,14 @@ func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer
|
|||||||
func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{}, p string) {
|
func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{}, p string) {
|
||||||
var f Formatter
|
var f Formatter
|
||||||
|
|
||||||
|
if w.PartsExclude != nil && len(w.PartsExclude) > 0 {
|
||||||
|
for _, exclude := range w.PartsExclude {
|
||||||
|
if exclude == p {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch p {
|
switch p {
|
||||||
case LevelFieldName:
|
case LevelFieldName:
|
||||||
if w.FormatLevel == nil {
|
if w.FormatLevel == nil {
|
||||||
@ -321,19 +333,19 @@ func consoleDefaultFormatLevel(noColor bool) Formatter {
|
|||||||
var l string
|
var l string
|
||||||
if ll, ok := i.(string); ok {
|
if ll, ok := i.(string); ok {
|
||||||
switch ll {
|
switch ll {
|
||||||
case "trace":
|
case LevelTraceValue:
|
||||||
l = colorize("TRC", colorMagenta, noColor)
|
l = colorize("TRC", colorMagenta, noColor)
|
||||||
case "debug":
|
case LevelDebugValue:
|
||||||
l = colorize("DBG", colorYellow, noColor)
|
l = colorize("DBG", colorYellow, noColor)
|
||||||
case "info":
|
case LevelInfoValue:
|
||||||
l = colorize("INF", colorGreen, noColor)
|
l = colorize("INF", colorGreen, noColor)
|
||||||
case "warn":
|
case LevelWarnValue:
|
||||||
l = colorize("WRN", colorRed, noColor)
|
l = colorize("WRN", colorRed, noColor)
|
||||||
case "error":
|
case LevelErrorValue:
|
||||||
l = colorize(colorize("ERR", colorRed, noColor), colorBold, noColor)
|
l = colorize(colorize("ERR", colorRed, noColor), colorBold, noColor)
|
||||||
case "fatal":
|
case LevelFatalValue:
|
||||||
l = colorize(colorize("FTL", colorRed, noColor), colorBold, noColor)
|
l = colorize(colorize("FTL", colorRed, noColor), colorBold, noColor)
|
||||||
case "panic":
|
case LevelPanicValue:
|
||||||
l = colorize(colorize("PNC", colorRed, noColor), colorBold, noColor)
|
l = colorize(colorize("PNC", colorRed, noColor), colorBold, noColor)
|
||||||
default:
|
default:
|
||||||
l = colorize("???", colorBold, noColor)
|
l = colorize("???", colorBold, noColor)
|
||||||
@ -356,10 +368,10 @@ func consoleDefaultFormatCaller(noColor bool) Formatter {
|
|||||||
c = cc
|
c = cc
|
||||||
}
|
}
|
||||||
if len(c) > 0 {
|
if len(c) > 0 {
|
||||||
cwd, err := os.Getwd()
|
if cwd, err := os.Getwd(); err == nil {
|
||||||
if err == nil {
|
if rel, err := filepath.Rel(cwd, c); err == nil {
|
||||||
c = strings.TrimPrefix(c, cwd)
|
c = rel
|
||||||
c = strings.TrimPrefix(c, "/")
|
}
|
||||||
}
|
}
|
||||||
c = colorize(c, colorBold, noColor) + colorize(" >", colorCyan, noColor)
|
c = colorize(c, colorBold, noColor) + colorize(" >", colorCyan, noColor)
|
||||||
}
|
}
|
||||||
@ -386,7 +398,7 @@ func consoleDefaultFormatFieldValue(i interface{}) string {
|
|||||||
|
|
||||||
func consoleDefaultFormatErrFieldName(noColor bool) Formatter {
|
func consoleDefaultFormatErrFieldName(noColor bool) Formatter {
|
||||||
return func(i interface{}) string {
|
return func(i interface{}) string {
|
||||||
return colorize(fmt.Sprintf("%s=", i), colorRed, noColor)
|
return colorize(fmt.Sprintf("%s=", i), colorCyan, noColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
vendor/github.com/rs/zerolog/context.go
generated
vendored
16
vendor/github.com/rs/zerolog/context.go
generated
vendored
@ -18,8 +18,10 @@ func (c Context) Logger() Logger {
|
|||||||
return c.l
|
return c.l
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fields is a helper function to use a map to set fields using type assertion.
|
// Fields is a helper function to use a map or slice to set fields using type assertion.
|
||||||
func (c Context) Fields(fields map[string]interface{}) Context {
|
// Only map[string]interface{} and []interface{} are accepted. []interface{} must
|
||||||
|
// alternate string keys and arbitrary values, and extraneous ones are ignored.
|
||||||
|
func (c Context) Fields(fields interface{}) Context {
|
||||||
c.l.context = appendFields(c.l.context, fields)
|
c.l.context = appendFields(c.l.context, fields)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@ -406,17 +408,9 @@ func (c Context) CallerWithSkipFrameCount(skipFrameCount int) Context {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
type stackTraceHook struct{}
|
|
||||||
|
|
||||||
func (sh stackTraceHook) Run(e *Event, level Level, msg string) {
|
|
||||||
e.Stack()
|
|
||||||
}
|
|
||||||
|
|
||||||
var sh = stackTraceHook{}
|
|
||||||
|
|
||||||
// Stack enables stack trace printing for the error passed to Err().
|
// Stack enables stack trace printing for the error passed to Err().
|
||||||
func (c Context) Stack() Context {
|
func (c Context) Stack() Context {
|
||||||
c.l = c.l.Hook(sh)
|
c.l.stack = true
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
vendor/github.com/rs/zerolog/ctx.go
generated
vendored
5
vendor/github.com/rs/zerolog/ctx.go
generated
vendored
@ -39,10 +39,13 @@ func (l *Logger) WithContext(ctx context.Context) context.Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ctx returns the Logger associated with the ctx. If no logger
|
// Ctx returns the Logger associated with the ctx. If no logger
|
||||||
// is associated, a disabled logger is returned.
|
// is associated, DefaultContextLogger is returned, unless DefaultContextLogger
|
||||||
|
// is nil, in which case a disabled logger is returned.
|
||||||
func Ctx(ctx context.Context) *Logger {
|
func Ctx(ctx context.Context) *Logger {
|
||||||
if l, ok := ctx.Value(ctxKey{}).(*Logger); ok {
|
if l, ok := ctx.Value(ctxKey{}).(*Logger); ok {
|
||||||
return l
|
return l
|
||||||
|
} else if l = DefaultContextLogger; l != nil {
|
||||||
|
return l
|
||||||
}
|
}
|
||||||
return disabledLogger
|
return disabledLogger
|
||||||
}
|
}
|
||||||
|
7
vendor/github.com/rs/zerolog/encoder_cbor.go
generated
vendored
7
vendor/github.com/rs/zerolog/encoder_cbor.go
generated
vendored
@ -14,6 +14,13 @@ var (
|
|||||||
enc = cbor.Encoder{}
|
enc = cbor.Encoder{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// using closure to reflect the changes at runtime.
|
||||||
|
cbor.JSONMarshalFunc = func(v interface{}) ([]byte, error) {
|
||||||
|
return InterfaceMarshalFunc(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func appendJSON(dst []byte, j []byte) []byte {
|
func appendJSON(dst []byte, j []byte) []byte {
|
||||||
return cbor.AppendEmbeddedJSON(dst, j)
|
return cbor.AppendEmbeddedJSON(dst, j)
|
||||||
}
|
}
|
||||||
|
7
vendor/github.com/rs/zerolog/encoder_json.go
generated
vendored
7
vendor/github.com/rs/zerolog/encoder_json.go
generated
vendored
@ -15,6 +15,13 @@ var (
|
|||||||
enc = json.Encoder{}
|
enc = json.Encoder{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// using closure to reflect the changes at runtime.
|
||||||
|
json.JSONMarshalFunc = func(v interface{}) ([]byte, error) {
|
||||||
|
return InterfaceMarshalFunc(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func appendJSON(dst []byte, j []byte) []byte {
|
func appendJSON(dst []byte, j []byte) []byte {
|
||||||
return append(dst, j...)
|
return append(dst, j...)
|
||||||
}
|
}
|
||||||
|
65
vendor/github.com/rs/zerolog/event.go
generated
vendored
65
vendor/github.com/rs/zerolog/event.go
generated
vendored
@ -20,12 +20,13 @@ var eventPool = &sync.Pool{
|
|||||||
// Event represents a log event. It is instanced by one of the level method of
|
// Event represents a log event. It is instanced by one of the level method of
|
||||||
// Logger and finalized by the Msg or Msgf method.
|
// Logger and finalized by the Msg or Msgf method.
|
||||||
type Event struct {
|
type Event struct {
|
||||||
buf []byte
|
buf []byte
|
||||||
w LevelWriter
|
w LevelWriter
|
||||||
level Level
|
level Level
|
||||||
done func(msg string)
|
done func(msg string)
|
||||||
stack bool // enable error stack trace
|
stack bool // enable error stack trace
|
||||||
ch []Hook // hooks from context
|
ch []Hook // hooks from context
|
||||||
|
skipFrame int // The number of additional frames to skip when printing the caller.
|
||||||
}
|
}
|
||||||
|
|
||||||
func putEvent(e *Event) {
|
func putEvent(e *Event) {
|
||||||
@ -62,6 +63,7 @@ func newEvent(w LevelWriter, level Level) *Event {
|
|||||||
e.w = w
|
e.w = w
|
||||||
e.level = level
|
e.level = level
|
||||||
e.stack = false
|
e.stack = false
|
||||||
|
e.skipFrame = 0
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,8 +148,10 @@ func (e *Event) msg(msg string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fields is a helper function to use a map to set fields using type assertion.
|
// Fields is a helper function to use a map or slice to set fields using type assertion.
|
||||||
func (e *Event) Fields(fields map[string]interface{}) *Event {
|
// Only map[string]interface{} and []interface{} are accepted. []interface{} must
|
||||||
|
// alternate string keys and arbitrary values, and extraneous ones are ignored.
|
||||||
|
func (e *Event) Fields(fields interface{}) *Event {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@ -205,15 +209,32 @@ func (e *Event) Object(key string, obj LogObjectMarshaler) *Event {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
e.buf = enc.AppendKey(e.buf, key)
|
e.buf = enc.AppendKey(e.buf, key)
|
||||||
|
if obj == nil {
|
||||||
|
e.buf = enc.AppendNil(e.buf)
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
e.appendObject(obj)
|
e.appendObject(obj)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Func allows an anonymous func to run only if the event is enabled.
|
||||||
|
func (e *Event) Func(f func(e *Event)) *Event {
|
||||||
|
if e != nil && e.Enabled() {
|
||||||
|
f(e)
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// EmbedObject marshals an object that implement the LogObjectMarshaler interface.
|
// EmbedObject marshals an object that implement the LogObjectMarshaler interface.
|
||||||
func (e *Event) EmbedObject(obj LogObjectMarshaler) *Event {
|
func (e *Event) EmbedObject(obj LogObjectMarshaler) *Event {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
if obj == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
obj.MarshalZerologObject(e)
|
obj.MarshalZerologObject(e)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@ -236,18 +257,24 @@ func (e *Event) Strs(key string, vals []string) *Event {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stringer adds the field key with val.String() (or null if val is nil) to the *Event context.
|
// Stringer adds the field key with val.String() (or null if val is nil)
|
||||||
|
// to the *Event context.
|
||||||
func (e *Event) Stringer(key string, val fmt.Stringer) *Event {
|
func (e *Event) Stringer(key string, val fmt.Stringer) *Event {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
e.buf = enc.AppendStringer(enc.AppendKey(e.buf, key), val)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
if val != nil {
|
// Stringers adds the field key with vals where each individual val
|
||||||
e.buf = enc.AppendString(enc.AppendKey(e.buf, key), val.String())
|
// is used as val.String() (or null if val is empty) to the *Event
|
||||||
|
// context.
|
||||||
|
func (e *Event) Stringers(key string, vals []fmt.Stringer) *Event {
|
||||||
|
if e == nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
e.buf = enc.AppendStringers(enc.AppendKey(e.buf, key), vals)
|
||||||
e.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), nil)
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,6 +712,16 @@ func (e *Event) Interface(key string, i interface{}) *Event {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CallerSkipFrame instructs any future Caller calls to skip the specified number of frames.
|
||||||
|
// This includes those added via hooks from the context.
|
||||||
|
func (e *Event) CallerSkipFrame(skip int) *Event {
|
||||||
|
if e == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
e.skipFrame += skip
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
|
// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
|
||||||
// The argument skip is the number of stack frames to ascend
|
// The argument skip is the number of stack frames to ascend
|
||||||
// Skip If not passed, use the global variable CallerSkipFrameCount
|
// Skip If not passed, use the global variable CallerSkipFrameCount
|
||||||
@ -700,7 +737,7 @@ func (e *Event) caller(skip int) *Event {
|
|||||||
if e == nil {
|
if e == nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
_, file, line, ok := runtime.Caller(skip)
|
_, file, line, ok := runtime.Caller(skip + e.skipFrame)
|
||||||
if !ok {
|
if !ok {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
40
vendor/github.com/rs/zerolog/fields.go
generated
vendored
40
vendor/github.com/rs/zerolog/fields.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package zerolog
|
package zerolog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"net"
|
"net"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
@ -11,15 +12,36 @@ func isNilValue(i interface{}) bool {
|
|||||||
return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0
|
return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendFields(dst []byte, fields map[string]interface{}) []byte {
|
func appendFields(dst []byte, fields interface{}) []byte {
|
||||||
keys := make([]string, 0, len(fields))
|
switch fields := fields.(type) {
|
||||||
for key := range fields {
|
case []interface{}:
|
||||||
keys = append(keys, key)
|
if n := len(fields); n&0x1 == 1 { // odd number
|
||||||
|
fields = fields[:n-1]
|
||||||
|
}
|
||||||
|
dst = appendFieldList(dst, fields)
|
||||||
|
case map[string]interface{}:
|
||||||
|
keys := make([]string, 0, len(fields))
|
||||||
|
for key := range fields {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
kv := make([]interface{}, 2)
|
||||||
|
for _, key := range keys {
|
||||||
|
kv[0], kv[1] = key, fields[key]
|
||||||
|
dst = appendFieldList(dst, kv)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sort.Strings(keys)
|
return dst
|
||||||
for _, key := range keys {
|
}
|
||||||
dst = enc.AppendKey(dst, key)
|
|
||||||
val := fields[key]
|
func appendFieldList(dst []byte, kvList []interface{}) []byte {
|
||||||
|
for i, n := 0, len(kvList); i < n; i += 2 {
|
||||||
|
key, val := kvList[i], kvList[i+1]
|
||||||
|
if key, ok := key.(string); ok {
|
||||||
|
dst = enc.AppendKey(dst, key)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if val, ok := val.(LogObjectMarshaler); ok {
|
if val, ok := val.(LogObjectMarshaler); ok {
|
||||||
e := newEvent(nil, 0)
|
e := newEvent(nil, 0)
|
||||||
e.buf = e.buf[:0]
|
e.buf = e.buf[:0]
|
||||||
@ -245,6 +267,8 @@ func appendFields(dst []byte, fields map[string]interface{}) []byte {
|
|||||||
dst = enc.AppendIPPrefix(dst, val)
|
dst = enc.AppendIPPrefix(dst, val)
|
||||||
case net.HardwareAddr:
|
case net.HardwareAddr:
|
||||||
dst = enc.AppendMACAddr(dst, val)
|
dst = enc.AppendMACAddr(dst, val)
|
||||||
|
case json.RawMessage:
|
||||||
|
dst = appendJSON(dst, val)
|
||||||
default:
|
default:
|
||||||
dst = enc.AppendInterface(dst, val)
|
dst = enc.AppendInterface(dst, val)
|
||||||
}
|
}
|
||||||
|
26
vendor/github.com/rs/zerolog/globals.go
generated
vendored
26
vendor/github.com/rs/zerolog/globals.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package zerolog
|
package zerolog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -27,7 +28,22 @@ var (
|
|||||||
// LevelFieldName is the field name used for the level field.
|
// LevelFieldName is the field name used for the level field.
|
||||||
LevelFieldName = "level"
|
LevelFieldName = "level"
|
||||||
|
|
||||||
// LevelFieldMarshalFunc allows customization of global level field marshaling
|
// LevelTraceValue is the value used for the trace level field.
|
||||||
|
LevelTraceValue = "trace"
|
||||||
|
// LevelDebugValue is the value used for the debug level field.
|
||||||
|
LevelDebugValue = "debug"
|
||||||
|
// LevelInfoValue is the value used for the info level field.
|
||||||
|
LevelInfoValue = "info"
|
||||||
|
// LevelWarnValue is the value used for the warn level field.
|
||||||
|
LevelWarnValue = "warn"
|
||||||
|
// LevelErrorValue is the value used for the error level field.
|
||||||
|
LevelErrorValue = "error"
|
||||||
|
// LevelFatalValue is the value used for the fatal level field.
|
||||||
|
LevelFatalValue = "fatal"
|
||||||
|
// LevelPanicValue is the value used for the panic level field.
|
||||||
|
LevelPanicValue = "panic"
|
||||||
|
|
||||||
|
// LevelFieldMarshalFunc allows customization of global level field marshaling.
|
||||||
LevelFieldMarshalFunc = func(l Level) string {
|
LevelFieldMarshalFunc = func(l Level) string {
|
||||||
return l.String()
|
return l.String()
|
||||||
}
|
}
|
||||||
@ -60,6 +76,10 @@ var (
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InterfaceMarshalFunc allows customization of interface marshaling.
|
||||||
|
// Default: "encoding/json.Marshal"
|
||||||
|
InterfaceMarshalFunc = json.Marshal
|
||||||
|
|
||||||
// TimeFieldFormat defines the time format of the Time field type. If set to
|
// TimeFieldFormat defines the time format of the Time field type. If set to
|
||||||
// TimeFormatUnix, TimeFormatUnixMs or TimeFormatUnixMicro, the time is formatted as an UNIX
|
// TimeFormatUnix, TimeFormatUnixMs or TimeFormatUnixMicro, the time is formatted as an UNIX
|
||||||
// timestamp as integer.
|
// timestamp as integer.
|
||||||
@ -80,6 +100,10 @@ var (
|
|||||||
// output. If not set, an error is printed on the stderr. This handler must
|
// output. If not set, an error is printed on the stderr. This handler must
|
||||||
// be thread safe and non-blocking.
|
// be thread safe and non-blocking.
|
||||||
ErrorHandler func(err error)
|
ErrorHandler func(err error)
|
||||||
|
|
||||||
|
// DefaultContextLogger is returned from Ctx() if there is no logger associated
|
||||||
|
// with the context.
|
||||||
|
DefaultContextLogger *Logger
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
11
vendor/github.com/rs/zerolog/go.mod
generated
vendored
11
vendor/github.com/rs/zerolog/go.mod
generated
vendored
@ -1,8 +1,11 @@
|
|||||||
module github.com/rs/zerolog
|
module github.com/rs/zerolog
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
|
github.com/coreos/go-systemd/v22 v22.3.2
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/rs/xid v1.2.1
|
github.com/rs/xid v1.3.0
|
||||||
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74
|
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e // indirect
|
||||||
|
golang.org/x/tools v0.1.7
|
||||||
)
|
)
|
||||||
|
39
vendor/github.com/rs/zerolog/go.sum
generated
vendored
39
vendor/github.com/rs/zerolog/go.sum
generated
vendored
@ -1,14 +1,37 @@
|
|||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
|
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4=
|
||||||
|
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
|
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||||
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
|
||||||
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74 h1:4cFkmztxtMslUX2SctSl+blCyXfpzhGOy9LhKAqSMA4=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
||||||
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
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=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
204
vendor/github.com/rs/zerolog/hlog/hlog.go
generated
vendored
Normal file
204
vendor/github.com/rs/zerolog/hlog/hlog.go
generated
vendored
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
// Package hlog provides a set of http.Handler helpers for zerolog.
|
||||||
|
package hlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/xid"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/hlog/internal/mutil"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FromRequest gets the logger in the request's context.
|
||||||
|
// This is a shortcut for log.Ctx(r.Context())
|
||||||
|
func FromRequest(r *http.Request) *zerolog.Logger {
|
||||||
|
return log.Ctx(r.Context())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHandler injects log into requests context.
|
||||||
|
func NewHandler(log zerolog.Logger) func(http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Create a copy of the logger (including internal context slice)
|
||||||
|
// to prevent data race when using UpdateContext.
|
||||||
|
l := log.With().Logger()
|
||||||
|
r = r.WithContext(l.WithContext(r.Context()))
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLHandler adds the requested URL as a field to the context's logger
|
||||||
|
// using fieldKey as field key.
|
||||||
|
func URLHandler(fieldKey string) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log := zerolog.Ctx(r.Context())
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(fieldKey, r.URL.String())
|
||||||
|
})
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MethodHandler adds the request method as a field to the context's logger
|
||||||
|
// using fieldKey as field key.
|
||||||
|
func MethodHandler(fieldKey string) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log := zerolog.Ctx(r.Context())
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(fieldKey, r.Method)
|
||||||
|
})
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequestHandler adds the request method and URL as a field to the context's logger
|
||||||
|
// using fieldKey as field key.
|
||||||
|
func RequestHandler(fieldKey string) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log := zerolog.Ctx(r.Context())
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(fieldKey, r.Method+" "+r.URL.String())
|
||||||
|
})
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoteAddrHandler adds the request's remote address as a field to the context's logger
|
||||||
|
// using fieldKey as field key.
|
||||||
|
func RemoteAddrHandler(fieldKey string) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.RemoteAddr != "" {
|
||||||
|
log := zerolog.Ctx(r.Context())
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(fieldKey, r.RemoteAddr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserAgentHandler adds the request's user-agent as a field to the context's logger
|
||||||
|
// using fieldKey as field key.
|
||||||
|
func UserAgentHandler(fieldKey string) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if ua := r.Header.Get("User-Agent"); ua != "" {
|
||||||
|
log := zerolog.Ctx(r.Context())
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(fieldKey, ua)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RefererHandler adds the request's referer as a field to the context's logger
|
||||||
|
// using fieldKey as field key.
|
||||||
|
func RefererHandler(fieldKey string) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if ref := r.Header.Get("Referer"); ref != "" {
|
||||||
|
log := zerolog.Ctx(r.Context())
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(fieldKey, ref)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type idKey struct{}
|
||||||
|
|
||||||
|
// IDFromRequest returns the unique id associated to the request if any.
|
||||||
|
func IDFromRequest(r *http.Request) (id xid.ID, ok bool) {
|
||||||
|
if r == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return IDFromCtx(r.Context())
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDFromCtx returns the unique id associated to the context if any.
|
||||||
|
func IDFromCtx(ctx context.Context) (id xid.ID, ok bool) {
|
||||||
|
id, ok = ctx.Value(idKey{}).(xid.ID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CtxWithID adds the given xid.ID to the context
|
||||||
|
func CtxWithID(ctx context.Context, id xid.ID) context.Context {
|
||||||
|
return context.WithValue(ctx, idKey{}, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequestIDHandler returns a handler setting a unique id to the request which can
|
||||||
|
// be gathered using IDFromRequest(req). This generated id is added as a field to the
|
||||||
|
// logger using the passed fieldKey as field name. The id is also added as a response
|
||||||
|
// header if the headerName is not empty.
|
||||||
|
//
|
||||||
|
// The generated id is a URL safe base64 encoded mongo object-id-like unique id.
|
||||||
|
// Mongo unique id generation algorithm has been selected as a trade-off between
|
||||||
|
// size and ease of use: UUID is less space efficient and snowflake requires machine
|
||||||
|
// configuration.
|
||||||
|
func RequestIDHandler(fieldKey, headerName string) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
id, ok := IDFromRequest(r)
|
||||||
|
if !ok {
|
||||||
|
id = xid.New()
|
||||||
|
ctx = CtxWithID(ctx, id)
|
||||||
|
r = r.WithContext(ctx)
|
||||||
|
}
|
||||||
|
if fieldKey != "" {
|
||||||
|
log := zerolog.Ctx(ctx)
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(fieldKey, id.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if headerName != "" {
|
||||||
|
w.Header().Set(headerName, id.String())
|
||||||
|
}
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CustomHeaderHandler adds given header from request's header as a field to
|
||||||
|
// the context's logger using fieldKey as field key.
|
||||||
|
func CustomHeaderHandler(fieldKey, header string) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if val := r.Header.Get(header); val != "" {
|
||||||
|
log := zerolog.Ctx(r.Context())
|
||||||
|
log.UpdateContext(func(c zerolog.Context) zerolog.Context {
|
||||||
|
return c.Str(fieldKey, val)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccessHandler returns a handler that call f after each request.
|
||||||
|
func AccessHandler(f func(r *http.Request, status, size int, duration time.Duration)) func(next http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
start := time.Now()
|
||||||
|
lw := mutil.WrapWriter(w)
|
||||||
|
next.ServeHTTP(lw, r)
|
||||||
|
f(r, lw.Status(), lw.BytesWritten(), time.Since(start))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
20
vendor/github.com/rs/zerolog/hlog/internal/mutil/LICENSE
generated
vendored
Normal file
20
vendor/github.com/rs/zerolog/hlog/internal/mutil/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Copyright (c) 2014, 2015, 2016 Carl Jackson (carl@avtok.com)
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
6
vendor/github.com/rs/zerolog/hlog/internal/mutil/mutil.go
generated
vendored
Normal file
6
vendor/github.com/rs/zerolog/hlog/internal/mutil/mutil.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Package mutil contains various functions that are helpful when writing http
|
||||||
|
// middleware.
|
||||||
|
//
|
||||||
|
// It has been vendored from Goji v1.0, with the exception of the code for Go 1.8:
|
||||||
|
// https://github.com/zenazn/goji/
|
||||||
|
package mutil
|
154
vendor/github.com/rs/zerolog/hlog/internal/mutil/writer_proxy.go
generated
vendored
Normal file
154
vendor/github.com/rs/zerolog/hlog/internal/mutil/writer_proxy.go
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
package mutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WriterProxy is a proxy around an http.ResponseWriter that allows you to hook
|
||||||
|
// into various parts of the response process.
|
||||||
|
type WriterProxy interface {
|
||||||
|
http.ResponseWriter
|
||||||
|
// Status returns the HTTP status of the request, or 0 if one has not
|
||||||
|
// yet been sent.
|
||||||
|
Status() int
|
||||||
|
// BytesWritten returns the total number of bytes sent to the client.
|
||||||
|
BytesWritten() int
|
||||||
|
// Tee causes the response body to be written to the given io.Writer in
|
||||||
|
// addition to proxying the writes through. Only one io.Writer can be
|
||||||
|
// tee'd to at once: setting a second one will overwrite the first.
|
||||||
|
// Writes will be sent to the proxy before being written to this
|
||||||
|
// io.Writer. It is illegal for the tee'd writer to be modified
|
||||||
|
// concurrently with writes.
|
||||||
|
Tee(io.Writer)
|
||||||
|
// Unwrap returns the original proxied target.
|
||||||
|
Unwrap() http.ResponseWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapWriter wraps an http.ResponseWriter, returning a proxy that allows you to
|
||||||
|
// hook into various parts of the response process.
|
||||||
|
func WrapWriter(w http.ResponseWriter) WriterProxy {
|
||||||
|
_, cn := w.(http.CloseNotifier)
|
||||||
|
_, fl := w.(http.Flusher)
|
||||||
|
_, hj := w.(http.Hijacker)
|
||||||
|
_, rf := w.(io.ReaderFrom)
|
||||||
|
|
||||||
|
bw := basicWriter{ResponseWriter: w}
|
||||||
|
if cn && fl && hj && rf {
|
||||||
|
return &fancyWriter{bw}
|
||||||
|
}
|
||||||
|
if fl {
|
||||||
|
return &flushWriter{bw}
|
||||||
|
}
|
||||||
|
return &bw
|
||||||
|
}
|
||||||
|
|
||||||
|
// basicWriter wraps a http.ResponseWriter that implements the minimal
|
||||||
|
// http.ResponseWriter interface.
|
||||||
|
type basicWriter struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
wroteHeader bool
|
||||||
|
code int
|
||||||
|
bytes int
|
||||||
|
tee io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *basicWriter) WriteHeader(code int) {
|
||||||
|
if !b.wroteHeader {
|
||||||
|
b.code = code
|
||||||
|
b.wroteHeader = true
|
||||||
|
b.ResponseWriter.WriteHeader(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *basicWriter) Write(buf []byte) (int, error) {
|
||||||
|
b.WriteHeader(http.StatusOK)
|
||||||
|
n, err := b.ResponseWriter.Write(buf)
|
||||||
|
if b.tee != nil {
|
||||||
|
_, err2 := b.tee.Write(buf[:n])
|
||||||
|
// Prefer errors generated by the proxied writer.
|
||||||
|
if err == nil {
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.bytes += n
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *basicWriter) maybeWriteHeader() {
|
||||||
|
if !b.wroteHeader {
|
||||||
|
b.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *basicWriter) Status() int {
|
||||||
|
return b.code
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *basicWriter) BytesWritten() int {
|
||||||
|
return b.bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *basicWriter) Tee(w io.Writer) {
|
||||||
|
b.tee = w
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *basicWriter) Unwrap() http.ResponseWriter {
|
||||||
|
return b.ResponseWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
// fancyWriter is a writer that additionally satisfies http.CloseNotifier,
|
||||||
|
// http.Flusher, http.Hijacker, and io.ReaderFrom. It exists for the common case
|
||||||
|
// of wrapping the http.ResponseWriter that package http gives you, in order to
|
||||||
|
// make the proxied object support the full method set of the proxied object.
|
||||||
|
type fancyWriter struct {
|
||||||
|
basicWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fancyWriter) CloseNotify() <-chan bool {
|
||||||
|
cn := f.basicWriter.ResponseWriter.(http.CloseNotifier)
|
||||||
|
return cn.CloseNotify()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fancyWriter) Flush() {
|
||||||
|
fl := f.basicWriter.ResponseWriter.(http.Flusher)
|
||||||
|
fl.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fancyWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
|
hj := f.basicWriter.ResponseWriter.(http.Hijacker)
|
||||||
|
return hj.Hijack()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fancyWriter) ReadFrom(r io.Reader) (int64, error) {
|
||||||
|
if f.basicWriter.tee != nil {
|
||||||
|
n, err := io.Copy(&f.basicWriter, r)
|
||||||
|
f.bytes += int(n)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
rf := f.basicWriter.ResponseWriter.(io.ReaderFrom)
|
||||||
|
f.basicWriter.maybeWriteHeader()
|
||||||
|
|
||||||
|
n, err := rf.ReadFrom(r)
|
||||||
|
f.bytes += int(n)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type flushWriter struct {
|
||||||
|
basicWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *flushWriter) Flush() {
|
||||||
|
fl := f.basicWriter.ResponseWriter.(http.Flusher)
|
||||||
|
fl.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ http.CloseNotifier = &fancyWriter{}
|
||||||
|
_ http.Flusher = &fancyWriter{}
|
||||||
|
_ http.Hijacker = &fancyWriter{}
|
||||||
|
_ io.ReaderFrom = &fancyWriter{}
|
||||||
|
_ http.Flusher = &flushWriter{}
|
||||||
|
)
|
10
vendor/github.com/rs/zerolog/internal/cbor/base.go
generated
vendored
10
vendor/github.com/rs/zerolog/internal/cbor/base.go
generated
vendored
@ -1,5 +1,13 @@
|
|||||||
package cbor
|
package cbor
|
||||||
|
|
||||||
|
// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice.
|
||||||
|
// Making it package level instead of embedded in Encoder brings
|
||||||
|
// some extra efforts at importing, but avoids value copy when the functions
|
||||||
|
// of Encoder being invoked.
|
||||||
|
// DO REMEMBER to set this variable at importing, or
|
||||||
|
// you might get a nil pointer dereference panic at runtime.
|
||||||
|
var JSONMarshalFunc func(v interface{}) ([]byte, error)
|
||||||
|
|
||||||
type Encoder struct{}
|
type Encoder struct{}
|
||||||
|
|
||||||
// AppendKey adds a key (string) to the binary encoded log message
|
// AppendKey adds a key (string) to the binary encoded log message
|
||||||
@ -8,4 +16,4 @@ func (e Encoder) AppendKey(dst []byte, key string) []byte {
|
|||||||
dst = e.AppendBeginMarker(dst)
|
dst = e.AppendBeginMarker(dst)
|
||||||
}
|
}
|
||||||
return e.AppendString(dst, key)
|
return e.AppendString(dst, key)
|
||||||
}
|
}
|
||||||
|
27
vendor/github.com/rs/zerolog/internal/cbor/string.go
generated
vendored
27
vendor/github.com/rs/zerolog/internal/cbor/string.go
generated
vendored
@ -1,5 +1,7 @@
|
|||||||
package cbor
|
package cbor
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
// AppendStrings encodes and adds an array of strings to the dst byte array.
|
// AppendStrings encodes and adds an array of strings to the dst byte array.
|
||||||
func (e Encoder) AppendStrings(dst []byte, vals []string) []byte {
|
func (e Encoder) AppendStrings(dst []byte, vals []string) []byte {
|
||||||
major := majorTypeArray
|
major := majorTypeArray
|
||||||
@ -30,6 +32,31 @@ func (Encoder) AppendString(dst []byte, s string) []byte {
|
|||||||
return append(dst, s...)
|
return append(dst, s...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendStringers encodes and adds an array of Stringer values
|
||||||
|
// to the dst byte array.
|
||||||
|
func (e Encoder) AppendStringers(dst []byte, vals []fmt.Stringer) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return e.AppendArrayEnd(e.AppendArrayStart(dst))
|
||||||
|
}
|
||||||
|
dst = e.AppendArrayStart(dst)
|
||||||
|
dst = e.AppendStringer(dst, vals[0])
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = e.AppendStringer(dst, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e.AppendArrayEnd(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendStringer encodes and adds the Stringer value to the dst
|
||||||
|
// byte array.
|
||||||
|
func (e Encoder) AppendStringer(dst []byte, val fmt.Stringer) []byte {
|
||||||
|
if val == nil {
|
||||||
|
return e.AppendNil(dst)
|
||||||
|
}
|
||||||
|
return e.AppendString(dst, val.String())
|
||||||
|
}
|
||||||
|
|
||||||
// AppendBytes encodes and adds an array of bytes to the dst byte array.
|
// AppendBytes encodes and adds an array of bytes to the dst byte array.
|
||||||
func (Encoder) AppendBytes(dst, s []byte) []byte {
|
func (Encoder) AppendBytes(dst, s []byte) []byte {
|
||||||
major := majorTypeByteString
|
major := majorTypeByteString
|
||||||
|
3
vendor/github.com/rs/zerolog/internal/cbor/types.go
generated
vendored
3
vendor/github.com/rs/zerolog/internal/cbor/types.go
generated
vendored
@ -1,7 +1,6 @@
|
|||||||
package cbor
|
package cbor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
@ -432,7 +431,7 @@ func (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
|
|||||||
|
|
||||||
// AppendInterface takes an arbitrary object and converts it to JSON and embeds it dst.
|
// AppendInterface takes an arbitrary object and converts it to JSON and embeds it dst.
|
||||||
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
|
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
|
||||||
marshaled, err := json.Marshal(i)
|
marshaled, err := JSONMarshalFunc(i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
|
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/rs/zerolog/internal/json/base.go
generated
vendored
8
vendor/github.com/rs/zerolog/internal/json/base.go
generated
vendored
@ -1,5 +1,13 @@
|
|||||||
package json
|
package json
|
||||||
|
|
||||||
|
// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice.
|
||||||
|
// Making it package level instead of embedded in Encoder brings
|
||||||
|
// some extra efforts at importing, but avoids value copy when the functions
|
||||||
|
// of Encoder being invoked.
|
||||||
|
// DO REMEMBER to set this variable at importing, or
|
||||||
|
// you might get a nil pointer dereference panic at runtime.
|
||||||
|
var JSONMarshalFunc func(v interface{}) ([]byte, error)
|
||||||
|
|
||||||
type Encoder struct{}
|
type Encoder struct{}
|
||||||
|
|
||||||
// AppendKey appends a new key to the output JSON.
|
// AppendKey appends a new key to the output JSON.
|
||||||
|
32
vendor/github.com/rs/zerolog/internal/json/string.go
generated
vendored
32
vendor/github.com/rs/zerolog/internal/json/string.go
generated
vendored
@ -1,6 +1,9 @@
|
|||||||
package json
|
package json
|
||||||
|
|
||||||
import "unicode/utf8"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
const hex = "0123456789abcdef"
|
const hex = "0123456789abcdef"
|
||||||
|
|
||||||
@ -60,7 +63,32 @@ func (Encoder) AppendString(dst []byte, s string) []byte {
|
|||||||
return append(dst, '"')
|
return append(dst, '"')
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendStringComplex is used by appendString to take over an in
|
// AppendStringers encodes the provided Stringer list to json and
|
||||||
|
// appends the encoded Stringer list to the input byte slice.
|
||||||
|
func (e Encoder) AppendStringers(dst []byte, vals []fmt.Stringer) []byte {
|
||||||
|
if len(vals) == 0 {
|
||||||
|
return append(dst, '[', ']')
|
||||||
|
}
|
||||||
|
dst = append(dst, '[')
|
||||||
|
dst = e.AppendStringer(dst, vals[0])
|
||||||
|
if len(vals) > 1 {
|
||||||
|
for _, val := range vals[1:] {
|
||||||
|
dst = e.AppendStringer(append(dst, ','), val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return append(dst, ']')
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendStringer encodes the input Stringer to json and appends the
|
||||||
|
// encoded Stringer value to the input byte slice.
|
||||||
|
func (e Encoder) AppendStringer(dst []byte, val fmt.Stringer) []byte {
|
||||||
|
if val == nil {
|
||||||
|
return e.AppendInterface(dst, nil)
|
||||||
|
}
|
||||||
|
return e.AppendString(dst, val.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
//// appendStringComplex is used by appendString to take over an in
|
||||||
// progress JSON string encoding that encountered a character that needs
|
// progress JSON string encoding that encountered a character that needs
|
||||||
// to be encoded.
|
// to be encoded.
|
||||||
func appendStringComplex(dst []byte, s string, i int) []byte {
|
func appendStringComplex(dst []byte, s string, i int) []byte {
|
||||||
|
5
vendor/github.com/rs/zerolog/internal/json/types.go
generated
vendored
5
vendor/github.com/rs/zerolog/internal/json/types.go
generated
vendored
@ -1,7 +1,6 @@
|
|||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
@ -350,7 +349,7 @@ func (Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
|
|||||||
return append(dst, '[', ']')
|
return append(dst, '[', ']')
|
||||||
}
|
}
|
||||||
dst = append(dst, '[')
|
dst = append(dst, '[')
|
||||||
dst = appendFloat(dst, vals[0], 32)
|
dst = appendFloat(dst, vals[0], 64)
|
||||||
if len(vals) > 1 {
|
if len(vals) > 1 {
|
||||||
for _, val := range vals[1:] {
|
for _, val := range vals[1:] {
|
||||||
dst = appendFloat(append(dst, ','), val, 64)
|
dst = appendFloat(append(dst, ','), val, 64)
|
||||||
@ -363,7 +362,7 @@ func (Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
|
|||||||
// AppendInterface marshals the input interface to a string and
|
// AppendInterface marshals the input interface to a string and
|
||||||
// appends the encoded string to the input byte slice.
|
// appends the encoded string to the input byte slice.
|
||||||
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
|
func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {
|
||||||
marshaled, err := json.Marshal(i)
|
marshaled, err := JSONMarshalFunc(i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
|
return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err))
|
||||||
}
|
}
|
||||||
|
45
vendor/github.com/rs/zerolog/log.go
generated
vendored
45
vendor/github.com/rs/zerolog/log.go
generated
vendored
@ -129,28 +129,31 @@ const (
|
|||||||
|
|
||||||
// TraceLevel defines trace log level.
|
// TraceLevel defines trace log level.
|
||||||
TraceLevel Level = -1
|
TraceLevel Level = -1
|
||||||
|
// Values less than TraceLevel are handled as numbers.
|
||||||
)
|
)
|
||||||
|
|
||||||
func (l Level) String() string {
|
func (l Level) String() string {
|
||||||
switch l {
|
switch l {
|
||||||
case TraceLevel:
|
case TraceLevel:
|
||||||
return "trace"
|
return LevelTraceValue
|
||||||
case DebugLevel:
|
case DebugLevel:
|
||||||
return "debug"
|
return LevelDebugValue
|
||||||
case InfoLevel:
|
case InfoLevel:
|
||||||
return "info"
|
return LevelInfoValue
|
||||||
case WarnLevel:
|
case WarnLevel:
|
||||||
return "warn"
|
return LevelWarnValue
|
||||||
case ErrorLevel:
|
case ErrorLevel:
|
||||||
return "error"
|
return LevelErrorValue
|
||||||
case FatalLevel:
|
case FatalLevel:
|
||||||
return "fatal"
|
return LevelFatalValue
|
||||||
case PanicLevel:
|
case PanicLevel:
|
||||||
return "panic"
|
return LevelPanicValue
|
||||||
|
case Disabled:
|
||||||
|
return "disabled"
|
||||||
case NoLevel:
|
case NoLevel:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return ""
|
return strconv.Itoa(int(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseLevel converts a level string into a zerolog Level value.
|
// ParseLevel converts a level string into a zerolog Level value.
|
||||||
@ -171,10 +174,19 @@ func ParseLevel(levelStr string) (Level, error) {
|
|||||||
return FatalLevel, nil
|
return FatalLevel, nil
|
||||||
case LevelFieldMarshalFunc(PanicLevel):
|
case LevelFieldMarshalFunc(PanicLevel):
|
||||||
return PanicLevel, nil
|
return PanicLevel, nil
|
||||||
|
case LevelFieldMarshalFunc(Disabled):
|
||||||
|
return Disabled, nil
|
||||||
case LevelFieldMarshalFunc(NoLevel):
|
case LevelFieldMarshalFunc(NoLevel):
|
||||||
return NoLevel, nil
|
return NoLevel, nil
|
||||||
}
|
}
|
||||||
return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr)
|
i, err := strconv.Atoi(levelStr)
|
||||||
|
if err != nil {
|
||||||
|
return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr)
|
||||||
|
}
|
||||||
|
if i > 127 || i < -128 {
|
||||||
|
return NoLevel, fmt.Errorf("Out-Of-Bounds Level: '%d', defaulting to NoLevel", i)
|
||||||
|
}
|
||||||
|
return Level(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Logger represents an active logging object that generates lines
|
// A Logger represents an active logging object that generates lines
|
||||||
@ -188,6 +200,7 @@ type Logger struct {
|
|||||||
sampler Sampler
|
sampler Sampler
|
||||||
context []byte
|
context []byte
|
||||||
hooks []Hook
|
hooks []Hook
|
||||||
|
stack bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a root logger with given output writer. If the output writer implements
|
// New creates a root logger with given output writer. If the output writer implements
|
||||||
@ -218,6 +231,7 @@ func (l Logger) Output(w io.Writer) Logger {
|
|||||||
l2 := New(w)
|
l2 := New(w)
|
||||||
l2.level = l.level
|
l2.level = l.level
|
||||||
l2.sampler = l.sampler
|
l2.sampler = l.sampler
|
||||||
|
l2.stack = l.stack
|
||||||
if len(l.hooks) > 0 {
|
if len(l.hooks) > 0 {
|
||||||
l2.hooks = append(l2.hooks, l.hooks...)
|
l2.hooks = append(l2.hooks, l.hooks...)
|
||||||
}
|
}
|
||||||
@ -371,7 +385,7 @@ func (l *Logger) WithLevel(level Level) *Event {
|
|||||||
case Disabled:
|
case Disabled:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
panic("zerolog: WithLevel(): invalid level: " + strconv.Itoa(int(level)))
|
return l.newEvent(level, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +401,7 @@ func (l *Logger) Log() *Event {
|
|||||||
// Arguments are handled in the manner of fmt.Print.
|
// Arguments are handled in the manner of fmt.Print.
|
||||||
func (l *Logger) Print(v ...interface{}) {
|
func (l *Logger) Print(v ...interface{}) {
|
||||||
if e := l.Debug(); e.Enabled() {
|
if e := l.Debug(); e.Enabled() {
|
||||||
e.Msg(fmt.Sprint(v...))
|
e.CallerSkipFrame(1).Msg(fmt.Sprint(v...))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,7 +409,7 @@ func (l *Logger) Print(v ...interface{}) {
|
|||||||
// Arguments are handled in the manner of fmt.Printf.
|
// Arguments are handled in the manner of fmt.Printf.
|
||||||
func (l *Logger) Printf(format string, v ...interface{}) {
|
func (l *Logger) Printf(format string, v ...interface{}) {
|
||||||
if e := l.Debug(); e.Enabled() {
|
if e := l.Debug(); e.Enabled() {
|
||||||
e.Msg(fmt.Sprintf(format, v...))
|
e.CallerSkipFrame(1).Msg(fmt.Sprintf(format, v...))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +421,7 @@ func (l Logger) Write(p []byte) (n int, err error) {
|
|||||||
// Trim CR added by stdlog.
|
// Trim CR added by stdlog.
|
||||||
p = p[0 : n-1]
|
p = p[0 : n-1]
|
||||||
}
|
}
|
||||||
l.Log().Msg(string(p))
|
l.Log().CallerSkipFrame(1).Msg(string(p))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,12 +433,15 @@ func (l *Logger) newEvent(level Level, done func(string)) *Event {
|
|||||||
e := newEvent(l.w, level)
|
e := newEvent(l.w, level)
|
||||||
e.done = done
|
e.done = done
|
||||||
e.ch = l.hooks
|
e.ch = l.hooks
|
||||||
if level != NoLevel {
|
if level != NoLevel && LevelFieldName != "" {
|
||||||
e.Str(LevelFieldName, LevelFieldMarshalFunc(level))
|
e.Str(LevelFieldName, LevelFieldMarshalFunc(level))
|
||||||
}
|
}
|
||||||
if l.context != nil && len(l.context) > 1 {
|
if l.context != nil && len(l.context) > 1 {
|
||||||
e.buf = enc.AppendObjectData(e.buf, l.context)
|
e.buf = enc.AppendObjectData(e.buf, l.context)
|
||||||
}
|
}
|
||||||
|
if l.stack {
|
||||||
|
e.Stack()
|
||||||
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
vendor/github.com/rs/zerolog/log/log.go
generated
vendored
5
vendor/github.com/rs/zerolog/log/log.go
generated
vendored
@ -3,6 +3,7 @@ package log
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -114,13 +115,13 @@ func Log() *zerolog.Event {
|
|||||||
// Print sends a log event using debug level and no extra field.
|
// Print sends a log event using debug level and no extra field.
|
||||||
// Arguments are handled in the manner of fmt.Print.
|
// Arguments are handled in the manner of fmt.Print.
|
||||||
func Print(v ...interface{}) {
|
func Print(v ...interface{}) {
|
||||||
Logger.Print(v...)
|
Logger.Debug().CallerSkipFrame(1).Msg(fmt.Sprint(v...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printf sends a log event using debug level and no extra field.
|
// Printf sends a log event using debug level and no extra field.
|
||||||
// Arguments are handled in the manner of fmt.Printf.
|
// Arguments are handled in the manner of fmt.Printf.
|
||||||
func Printf(format string, v ...interface{}) {
|
func Printf(format string, v ...interface{}) {
|
||||||
Logger.Printf(format, v...)
|
Logger.Debug().CallerSkipFrame(1).Msgf(format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ctx returns the Logger associated with the ctx. If no logger
|
// Ctx returns the Logger associated with the ctx. If no logger
|
||||||
|
BIN
vendor/github.com/rs/zerolog/pretty.png
generated
vendored
BIN
vendor/github.com/rs/zerolog/pretty.png
generated
vendored
Binary file not shown.
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 82 KiB |
2
vendor/github.com/rs/zerolog/sampler.go
generated
vendored
2
vendor/github.com/rs/zerolog/sampler.go
generated
vendored
@ -38,7 +38,7 @@ func (s RandomSampler) Sample(lvl Level) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BasicSampler is a sampler that will send every Nth events, regardless of
|
// BasicSampler is a sampler that will send every Nth events, regardless of
|
||||||
// there level.
|
// their level.
|
||||||
type BasicSampler struct {
|
type BasicSampler struct {
|
||||||
N uint32
|
N uint32
|
||||||
counter uint32
|
counter uint32
|
||||||
|
42
vendor/github.com/rs/zerolog/syslog.go
generated
vendored
42
vendor/github.com/rs/zerolog/syslog.go
generated
vendored
@ -7,6 +7,10 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// See http://cee.mitre.org/language/1.0-beta1/clt.html#syslog
|
||||||
|
// or https://www.rsyslog.com/json-elasticsearch/
|
||||||
|
const ceePrefix = "@cee:"
|
||||||
|
|
||||||
// SyslogWriter is an interface matching a syslog.Writer struct.
|
// SyslogWriter is an interface matching a syslog.Writer struct.
|
||||||
type SyslogWriter interface {
|
type SyslogWriter interface {
|
||||||
io.Writer
|
io.Writer
|
||||||
@ -19,17 +23,34 @@ type SyslogWriter interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type syslogWriter struct {
|
type syslogWriter struct {
|
||||||
w SyslogWriter
|
w SyslogWriter
|
||||||
|
prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
// SyslogLevelWriter wraps a SyslogWriter and call the right syslog level
|
// SyslogLevelWriter wraps a SyslogWriter and call the right syslog level
|
||||||
// method matching the zerolog level.
|
// method matching the zerolog level.
|
||||||
func SyslogLevelWriter(w SyslogWriter) LevelWriter {
|
func SyslogLevelWriter(w SyslogWriter) LevelWriter {
|
||||||
return syslogWriter{w}
|
return syslogWriter{w, ""}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyslogCEEWriter wraps a SyslogWriter with a SyslogLevelWriter that adds a
|
||||||
|
// MITRE CEE prefix for JSON syslog entries, compatible with rsyslog
|
||||||
|
// and syslog-ng JSON logging support.
|
||||||
|
// See https://www.rsyslog.com/json-elasticsearch/
|
||||||
|
func SyslogCEEWriter(w SyslogWriter) LevelWriter {
|
||||||
|
return syslogWriter{w, ceePrefix}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sw syslogWriter) Write(p []byte) (n int, err error) {
|
func (sw syslogWriter) Write(p []byte) (n int, err error) {
|
||||||
return sw.w.Write(p)
|
var pn int
|
||||||
|
if sw.prefix != "" {
|
||||||
|
pn, err = sw.w.Write([]byte(sw.prefix))
|
||||||
|
if err != nil {
|
||||||
|
return pn, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n, err = sw.w.Write(p)
|
||||||
|
return pn + n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteLevel implements LevelWriter interface.
|
// WriteLevel implements LevelWriter interface.
|
||||||
@ -37,22 +58,23 @@ func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) {
|
|||||||
switch level {
|
switch level {
|
||||||
case TraceLevel:
|
case TraceLevel:
|
||||||
case DebugLevel:
|
case DebugLevel:
|
||||||
err = sw.w.Debug(string(p))
|
err = sw.w.Debug(sw.prefix + string(p))
|
||||||
case InfoLevel:
|
case InfoLevel:
|
||||||
err = sw.w.Info(string(p))
|
err = sw.w.Info(sw.prefix + string(p))
|
||||||
case WarnLevel:
|
case WarnLevel:
|
||||||
err = sw.w.Warning(string(p))
|
err = sw.w.Warning(sw.prefix + string(p))
|
||||||
case ErrorLevel:
|
case ErrorLevel:
|
||||||
err = sw.w.Err(string(p))
|
err = sw.w.Err(sw.prefix + string(p))
|
||||||
case FatalLevel:
|
case FatalLevel:
|
||||||
err = sw.w.Emerg(string(p))
|
err = sw.w.Emerg(sw.prefix + string(p))
|
||||||
case PanicLevel:
|
case PanicLevel:
|
||||||
err = sw.w.Crit(string(p))
|
err = sw.w.Crit(sw.prefix + string(p))
|
||||||
case NoLevel:
|
case NoLevel:
|
||||||
err = sw.w.Info(string(p))
|
err = sw.w.Info(sw.prefix + string(p))
|
||||||
default:
|
default:
|
||||||
panic("invalid level")
|
panic("invalid level")
|
||||||
}
|
}
|
||||||
|
// Any CEE prefix is not part of the message, so we don't include its length
|
||||||
n = len(p)
|
n = len(p)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
88
vendor/github.com/rs/zerolog/writer.go
generated
vendored
88
vendor/github.com/rs/zerolog/writer.go
generated
vendored
@ -1,7 +1,12 @@
|
|||||||
package zerolog
|
package zerolog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
|
"path"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -56,30 +61,30 @@ type multiLevelWriter struct {
|
|||||||
|
|
||||||
func (t multiLevelWriter) Write(p []byte) (n int, err error) {
|
func (t multiLevelWriter) Write(p []byte) (n int, err error) {
|
||||||
for _, w := range t.writers {
|
for _, w := range t.writers {
|
||||||
n, err = w.Write(p)
|
if _n, _err := w.Write(p); err == nil {
|
||||||
if err != nil {
|
n = _n
|
||||||
return
|
if _err != nil {
|
||||||
}
|
err = _err
|
||||||
if n != len(p) {
|
} else if _n != len(p) {
|
||||||
err = io.ErrShortWrite
|
err = io.ErrShortWrite
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len(p), nil
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t multiLevelWriter) WriteLevel(l Level, p []byte) (n int, err error) {
|
func (t multiLevelWriter) WriteLevel(l Level, p []byte) (n int, err error) {
|
||||||
for _, w := range t.writers {
|
for _, w := range t.writers {
|
||||||
n, err = w.WriteLevel(l, p)
|
if _n, _err := w.WriteLevel(l, p); err == nil {
|
||||||
if err != nil {
|
n = _n
|
||||||
return
|
if _err != nil {
|
||||||
}
|
err = _err
|
||||||
if n != len(p) {
|
} else if _n != len(p) {
|
||||||
err = io.ErrShortWrite
|
err = io.ErrShortWrite
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len(p), nil
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultiLevelWriter creates a writer that duplicates its writes to all the
|
// MultiLevelWriter creates a writer that duplicates its writes to all the
|
||||||
@ -96,3 +101,54 @@ func MultiLevelWriter(writers ...io.Writer) LevelWriter {
|
|||||||
}
|
}
|
||||||
return multiLevelWriter{lwriters}
|
return multiLevelWriter{lwriters}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestingLog is the logging interface of testing.TB.
|
||||||
|
type TestingLog interface {
|
||||||
|
Log(args ...interface{})
|
||||||
|
Logf(format string, args ...interface{})
|
||||||
|
Helper()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWriter is a writer that writes to testing.TB.
|
||||||
|
type TestWriter struct {
|
||||||
|
T TestingLog
|
||||||
|
|
||||||
|
// Frame skips caller frames to capture the original file and line numbers.
|
||||||
|
Frame int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTestWriter creates a writer that logs to the testing.TB.
|
||||||
|
func NewTestWriter(t TestingLog) TestWriter {
|
||||||
|
return TestWriter{T: t}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to testing.TB.
|
||||||
|
func (t TestWriter) Write(p []byte) (n int, err error) {
|
||||||
|
t.T.Helper()
|
||||||
|
|
||||||
|
n = len(p)
|
||||||
|
|
||||||
|
// Strip trailing newline because t.Log always adds one.
|
||||||
|
p = bytes.TrimRight(p, "\n")
|
||||||
|
|
||||||
|
// Try to correct the log file and line number to the caller.
|
||||||
|
if t.Frame > 0 {
|
||||||
|
_, origFile, origLine, _ := runtime.Caller(1)
|
||||||
|
_, frameFile, frameLine, ok := runtime.Caller(1 + t.Frame)
|
||||||
|
if ok {
|
||||||
|
erase := strings.Repeat("\b", len(path.Base(origFile))+len(strconv.Itoa(origLine))+3)
|
||||||
|
t.T.Logf("%s%s:%d: %s", erase, path.Base(frameFile), frameLine, p)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.T.Log(string(p))
|
||||||
|
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConsoleTestWriter creates an option that correctly sets the file frame depth for testing.TB log.
|
||||||
|
func ConsoleTestWriter(t TestingLog) func(w *ConsoleWriter) {
|
||||||
|
return func(w *ConsoleWriter) {
|
||||||
|
w.Out = TestWriter{T: t, Frame: 6}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
172
vendor/github.com/stretchr/testify/assert/assertion_compare.go
generated
vendored
172
vendor/github.com/stretchr/testify/assert/assertion_compare.go
generated
vendored
@ -13,12 +13,42 @@ const (
|
|||||||
compareGreater
|
compareGreater
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
intType = reflect.TypeOf(int(1))
|
||||||
|
int8Type = reflect.TypeOf(int8(1))
|
||||||
|
int16Type = reflect.TypeOf(int16(1))
|
||||||
|
int32Type = reflect.TypeOf(int32(1))
|
||||||
|
int64Type = reflect.TypeOf(int64(1))
|
||||||
|
|
||||||
|
uintType = reflect.TypeOf(uint(1))
|
||||||
|
uint8Type = reflect.TypeOf(uint8(1))
|
||||||
|
uint16Type = reflect.TypeOf(uint16(1))
|
||||||
|
uint32Type = reflect.TypeOf(uint32(1))
|
||||||
|
uint64Type = reflect.TypeOf(uint64(1))
|
||||||
|
|
||||||
|
float32Type = reflect.TypeOf(float32(1))
|
||||||
|
float64Type = reflect.TypeOf(float64(1))
|
||||||
|
|
||||||
|
stringType = reflect.TypeOf("")
|
||||||
|
)
|
||||||
|
|
||||||
func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
||||||
|
obj1Value := reflect.ValueOf(obj1)
|
||||||
|
obj2Value := reflect.ValueOf(obj2)
|
||||||
|
|
||||||
|
// throughout this switch we try and avoid calling .Convert() if possible,
|
||||||
|
// as this has a pretty big performance impact
|
||||||
switch kind {
|
switch kind {
|
||||||
case reflect.Int:
|
case reflect.Int:
|
||||||
{
|
{
|
||||||
intobj1 := obj1.(int)
|
intobj1, ok := obj1.(int)
|
||||||
intobj2 := obj2.(int)
|
if !ok {
|
||||||
|
intobj1 = obj1Value.Convert(intType).Interface().(int)
|
||||||
|
}
|
||||||
|
intobj2, ok := obj2.(int)
|
||||||
|
if !ok {
|
||||||
|
intobj2 = obj2Value.Convert(intType).Interface().(int)
|
||||||
|
}
|
||||||
if intobj1 > intobj2 {
|
if intobj1 > intobj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -31,8 +61,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Int8:
|
case reflect.Int8:
|
||||||
{
|
{
|
||||||
int8obj1 := obj1.(int8)
|
int8obj1, ok := obj1.(int8)
|
||||||
int8obj2 := obj2.(int8)
|
if !ok {
|
||||||
|
int8obj1 = obj1Value.Convert(int8Type).Interface().(int8)
|
||||||
|
}
|
||||||
|
int8obj2, ok := obj2.(int8)
|
||||||
|
if !ok {
|
||||||
|
int8obj2 = obj2Value.Convert(int8Type).Interface().(int8)
|
||||||
|
}
|
||||||
if int8obj1 > int8obj2 {
|
if int8obj1 > int8obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -45,8 +81,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Int16:
|
case reflect.Int16:
|
||||||
{
|
{
|
||||||
int16obj1 := obj1.(int16)
|
int16obj1, ok := obj1.(int16)
|
||||||
int16obj2 := obj2.(int16)
|
if !ok {
|
||||||
|
int16obj1 = obj1Value.Convert(int16Type).Interface().(int16)
|
||||||
|
}
|
||||||
|
int16obj2, ok := obj2.(int16)
|
||||||
|
if !ok {
|
||||||
|
int16obj2 = obj2Value.Convert(int16Type).Interface().(int16)
|
||||||
|
}
|
||||||
if int16obj1 > int16obj2 {
|
if int16obj1 > int16obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -59,8 +101,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Int32:
|
case reflect.Int32:
|
||||||
{
|
{
|
||||||
int32obj1 := obj1.(int32)
|
int32obj1, ok := obj1.(int32)
|
||||||
int32obj2 := obj2.(int32)
|
if !ok {
|
||||||
|
int32obj1 = obj1Value.Convert(int32Type).Interface().(int32)
|
||||||
|
}
|
||||||
|
int32obj2, ok := obj2.(int32)
|
||||||
|
if !ok {
|
||||||
|
int32obj2 = obj2Value.Convert(int32Type).Interface().(int32)
|
||||||
|
}
|
||||||
if int32obj1 > int32obj2 {
|
if int32obj1 > int32obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -73,8 +121,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Int64:
|
case reflect.Int64:
|
||||||
{
|
{
|
||||||
int64obj1 := obj1.(int64)
|
int64obj1, ok := obj1.(int64)
|
||||||
int64obj2 := obj2.(int64)
|
if !ok {
|
||||||
|
int64obj1 = obj1Value.Convert(int64Type).Interface().(int64)
|
||||||
|
}
|
||||||
|
int64obj2, ok := obj2.(int64)
|
||||||
|
if !ok {
|
||||||
|
int64obj2 = obj2Value.Convert(int64Type).Interface().(int64)
|
||||||
|
}
|
||||||
if int64obj1 > int64obj2 {
|
if int64obj1 > int64obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -87,8 +141,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Uint:
|
case reflect.Uint:
|
||||||
{
|
{
|
||||||
uintobj1 := obj1.(uint)
|
uintobj1, ok := obj1.(uint)
|
||||||
uintobj2 := obj2.(uint)
|
if !ok {
|
||||||
|
uintobj1 = obj1Value.Convert(uintType).Interface().(uint)
|
||||||
|
}
|
||||||
|
uintobj2, ok := obj2.(uint)
|
||||||
|
if !ok {
|
||||||
|
uintobj2 = obj2Value.Convert(uintType).Interface().(uint)
|
||||||
|
}
|
||||||
if uintobj1 > uintobj2 {
|
if uintobj1 > uintobj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -101,8 +161,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Uint8:
|
case reflect.Uint8:
|
||||||
{
|
{
|
||||||
uint8obj1 := obj1.(uint8)
|
uint8obj1, ok := obj1.(uint8)
|
||||||
uint8obj2 := obj2.(uint8)
|
if !ok {
|
||||||
|
uint8obj1 = obj1Value.Convert(uint8Type).Interface().(uint8)
|
||||||
|
}
|
||||||
|
uint8obj2, ok := obj2.(uint8)
|
||||||
|
if !ok {
|
||||||
|
uint8obj2 = obj2Value.Convert(uint8Type).Interface().(uint8)
|
||||||
|
}
|
||||||
if uint8obj1 > uint8obj2 {
|
if uint8obj1 > uint8obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -115,8 +181,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Uint16:
|
case reflect.Uint16:
|
||||||
{
|
{
|
||||||
uint16obj1 := obj1.(uint16)
|
uint16obj1, ok := obj1.(uint16)
|
||||||
uint16obj2 := obj2.(uint16)
|
if !ok {
|
||||||
|
uint16obj1 = obj1Value.Convert(uint16Type).Interface().(uint16)
|
||||||
|
}
|
||||||
|
uint16obj2, ok := obj2.(uint16)
|
||||||
|
if !ok {
|
||||||
|
uint16obj2 = obj2Value.Convert(uint16Type).Interface().(uint16)
|
||||||
|
}
|
||||||
if uint16obj1 > uint16obj2 {
|
if uint16obj1 > uint16obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -129,8 +201,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Uint32:
|
case reflect.Uint32:
|
||||||
{
|
{
|
||||||
uint32obj1 := obj1.(uint32)
|
uint32obj1, ok := obj1.(uint32)
|
||||||
uint32obj2 := obj2.(uint32)
|
if !ok {
|
||||||
|
uint32obj1 = obj1Value.Convert(uint32Type).Interface().(uint32)
|
||||||
|
}
|
||||||
|
uint32obj2, ok := obj2.(uint32)
|
||||||
|
if !ok {
|
||||||
|
uint32obj2 = obj2Value.Convert(uint32Type).Interface().(uint32)
|
||||||
|
}
|
||||||
if uint32obj1 > uint32obj2 {
|
if uint32obj1 > uint32obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -143,8 +221,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Uint64:
|
case reflect.Uint64:
|
||||||
{
|
{
|
||||||
uint64obj1 := obj1.(uint64)
|
uint64obj1, ok := obj1.(uint64)
|
||||||
uint64obj2 := obj2.(uint64)
|
if !ok {
|
||||||
|
uint64obj1 = obj1Value.Convert(uint64Type).Interface().(uint64)
|
||||||
|
}
|
||||||
|
uint64obj2, ok := obj2.(uint64)
|
||||||
|
if !ok {
|
||||||
|
uint64obj2 = obj2Value.Convert(uint64Type).Interface().(uint64)
|
||||||
|
}
|
||||||
if uint64obj1 > uint64obj2 {
|
if uint64obj1 > uint64obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -157,8 +241,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Float32:
|
case reflect.Float32:
|
||||||
{
|
{
|
||||||
float32obj1 := obj1.(float32)
|
float32obj1, ok := obj1.(float32)
|
||||||
float32obj2 := obj2.(float32)
|
if !ok {
|
||||||
|
float32obj1 = obj1Value.Convert(float32Type).Interface().(float32)
|
||||||
|
}
|
||||||
|
float32obj2, ok := obj2.(float32)
|
||||||
|
if !ok {
|
||||||
|
float32obj2 = obj2Value.Convert(float32Type).Interface().(float32)
|
||||||
|
}
|
||||||
if float32obj1 > float32obj2 {
|
if float32obj1 > float32obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -171,8 +261,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.Float64:
|
case reflect.Float64:
|
||||||
{
|
{
|
||||||
float64obj1 := obj1.(float64)
|
float64obj1, ok := obj1.(float64)
|
||||||
float64obj2 := obj2.(float64)
|
if !ok {
|
||||||
|
float64obj1 = obj1Value.Convert(float64Type).Interface().(float64)
|
||||||
|
}
|
||||||
|
float64obj2, ok := obj2.(float64)
|
||||||
|
if !ok {
|
||||||
|
float64obj2 = obj2Value.Convert(float64Type).Interface().(float64)
|
||||||
|
}
|
||||||
if float64obj1 > float64obj2 {
|
if float64obj1 > float64obj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -185,8 +281,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||||||
}
|
}
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
{
|
{
|
||||||
stringobj1 := obj1.(string)
|
stringobj1, ok := obj1.(string)
|
||||||
stringobj2 := obj2.(string)
|
if !ok {
|
||||||
|
stringobj1 = obj1Value.Convert(stringType).Interface().(string)
|
||||||
|
}
|
||||||
|
stringobj2, ok := obj2.(string)
|
||||||
|
if !ok {
|
||||||
|
stringobj2 = obj2Value.Convert(stringType).Interface().(string)
|
||||||
|
}
|
||||||
if stringobj1 > stringobj2 {
|
if stringobj1 > stringobj2 {
|
||||||
return compareGreater, true
|
return compareGreater, true
|
||||||
}
|
}
|
||||||
@ -240,6 +342,24 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter
|
|||||||
return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs)
|
return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Positive asserts that the specified element is positive
|
||||||
|
//
|
||||||
|
// assert.Positive(t, 1)
|
||||||
|
// assert.Positive(t, 1.23)
|
||||||
|
func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
zero := reflect.Zero(reflect.TypeOf(e))
|
||||||
|
return compareTwoValues(t, e, zero.Interface(), []CompareType{compareGreater}, "\"%v\" is not positive", msgAndArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negative asserts that the specified element is negative
|
||||||
|
//
|
||||||
|
// assert.Negative(t, -1)
|
||||||
|
// assert.Negative(t, -1.23)
|
||||||
|
func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
zero := reflect.Zero(reflect.TypeOf(e))
|
||||||
|
return compareTwoValues(t, e, zero.Interface(), []CompareType{compareLess}, "\"%v\" is not negative", msgAndArgs)
|
||||||
|
}
|
||||||
|
|
||||||
func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {
|
func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {
|
||||||
if h, ok := t.(tHelper); ok {
|
if h, ok := t.(tHelper); ok {
|
||||||
h.Helper()
|
h.Helper()
|
||||||
|
97
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
97
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
@ -114,6 +114,24 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
|||||||
return Error(t, err, append([]interface{}{msg}, args...)...)
|
return Error(t, err, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||||
|
// This is a wrapper for errors.As.
|
||||||
|
func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return ErrorAs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorIsf asserts that at least one of the errors in err's chain matches target.
|
||||||
|
// This is a wrapper for errors.Is.
|
||||||
|
func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return ErrorIs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
// Eventuallyf asserts that given condition will be met in waitFor time,
|
// Eventuallyf asserts that given condition will be met in waitFor time,
|
||||||
// periodically checking target function each tick.
|
// periodically checking target function each tick.
|
||||||
//
|
//
|
||||||
@ -321,6 +339,54 @@ func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsil
|
|||||||
return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsDecreasingf asserts that the collection is decreasing
|
||||||
|
//
|
||||||
|
// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted")
|
||||||
|
// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||||
|
// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||||
|
func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsDecreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsIncreasingf asserts that the collection is increasing
|
||||||
|
//
|
||||||
|
// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted")
|
||||||
|
// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||||
|
// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||||
|
func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsIncreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNonDecreasingf asserts that the collection is not decreasing
|
||||||
|
//
|
||||||
|
// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted")
|
||||||
|
// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||||
|
// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||||
|
func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsNonDecreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNonIncreasingf asserts that the collection is not increasing
|
||||||
|
//
|
||||||
|
// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted")
|
||||||
|
// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||||
|
// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||||
|
func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
// IsTypef asserts that the specified objects are of the same type.
|
// IsTypef asserts that the specified objects are of the same type.
|
||||||
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||||
if h, ok := t.(tHelper); ok {
|
if h, ok := t.(tHelper); ok {
|
||||||
@ -375,6 +441,17 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args .
|
|||||||
return LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)
|
return LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Negativef asserts that the specified element is negative
|
||||||
|
//
|
||||||
|
// assert.Negativef(t, -1, "error message %s", "formatted")
|
||||||
|
// assert.Negativef(t, -1.23, "error message %s", "formatted")
|
||||||
|
func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return Negative(t, e, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
// Neverf asserts that the given condition doesn't satisfy in waitFor time,
|
// Neverf asserts that the given condition doesn't satisfy in waitFor time,
|
||||||
// periodically checking the target function each tick.
|
// periodically checking the target function each tick.
|
||||||
//
|
//
|
||||||
@ -476,6 +553,15 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s
|
|||||||
return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotErrorIsf asserts that at none of the errors in err's chain matches target.
|
||||||
|
// This is a wrapper for errors.Is.
|
||||||
|
func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return NotErrorIs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
// NotNilf asserts that the specified object is not nil.
|
// NotNilf asserts that the specified object is not nil.
|
||||||
//
|
//
|
||||||
// assert.NotNilf(t, err, "error message %s", "formatted")
|
// assert.NotNilf(t, err, "error message %s", "formatted")
|
||||||
@ -572,6 +658,17 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str
|
|||||||
return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
|
return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Positivef asserts that the specified element is positive
|
||||||
|
//
|
||||||
|
// assert.Positivef(t, 1, "error message %s", "formatted")
|
||||||
|
// assert.Positivef(t, 1.23, "error message %s", "formatted")
|
||||||
|
func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return Positive(t, e, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
// Regexpf asserts that a specified regexp matches a string.
|
// Regexpf asserts that a specified regexp matches a string.
|
||||||
//
|
//
|
||||||
// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted")
|
// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted")
|
||||||
|
194
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
194
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
@ -204,6 +204,42 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
|
|||||||
return Error(a.t, err, msgAndArgs...)
|
return Error(a.t, err, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||||
|
// This is a wrapper for errors.As.
|
||||||
|
func (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return ErrorAs(a.t, err, target, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||||
|
// This is a wrapper for errors.As.
|
||||||
|
func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return ErrorAsf(a.t, err, target, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorIs asserts that at least one of the errors in err's chain matches target.
|
||||||
|
// This is a wrapper for errors.Is.
|
||||||
|
func (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return ErrorIs(a.t, err, target, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorIsf asserts that at least one of the errors in err's chain matches target.
|
||||||
|
// This is a wrapper for errors.Is.
|
||||||
|
func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return ErrorIsf(a.t, err, target, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||||
//
|
//
|
||||||
// actualObj, err := SomeFunction()
|
// actualObj, err := SomeFunction()
|
||||||
@ -631,6 +667,102 @@ func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilo
|
|||||||
return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
|
return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsDecreasing asserts that the collection is decreasing
|
||||||
|
//
|
||||||
|
// a.IsDecreasing([]int{2, 1, 0})
|
||||||
|
// a.IsDecreasing([]float{2, 1})
|
||||||
|
// a.IsDecreasing([]string{"b", "a"})
|
||||||
|
func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsDecreasing(a.t, object, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDecreasingf asserts that the collection is decreasing
|
||||||
|
//
|
||||||
|
// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted")
|
||||||
|
// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted")
|
||||||
|
// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted")
|
||||||
|
func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsDecreasingf(a.t, object, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsIncreasing asserts that the collection is increasing
|
||||||
|
//
|
||||||
|
// a.IsIncreasing([]int{1, 2, 3})
|
||||||
|
// a.IsIncreasing([]float{1, 2})
|
||||||
|
// a.IsIncreasing([]string{"a", "b"})
|
||||||
|
func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsIncreasing(a.t, object, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsIncreasingf asserts that the collection is increasing
|
||||||
|
//
|
||||||
|
// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted")
|
||||||
|
// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted")
|
||||||
|
// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted")
|
||||||
|
func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsIncreasingf(a.t, object, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNonDecreasing asserts that the collection is not decreasing
|
||||||
|
//
|
||||||
|
// a.IsNonDecreasing([]int{1, 1, 2})
|
||||||
|
// a.IsNonDecreasing([]float{1, 2})
|
||||||
|
// a.IsNonDecreasing([]string{"a", "b"})
|
||||||
|
func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsNonDecreasing(a.t, object, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNonDecreasingf asserts that the collection is not decreasing
|
||||||
|
//
|
||||||
|
// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted")
|
||||||
|
// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted")
|
||||||
|
// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted")
|
||||||
|
func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsNonDecreasingf(a.t, object, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNonIncreasing asserts that the collection is not increasing
|
||||||
|
//
|
||||||
|
// a.IsNonIncreasing([]int{2, 1, 1})
|
||||||
|
// a.IsNonIncreasing([]float{2, 1})
|
||||||
|
// a.IsNonIncreasing([]string{"b", "a"})
|
||||||
|
func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsNonIncreasing(a.t, object, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNonIncreasingf asserts that the collection is not increasing
|
||||||
|
//
|
||||||
|
// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted")
|
||||||
|
// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted")
|
||||||
|
// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted")
|
||||||
|
func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return IsNonIncreasingf(a.t, object, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
// IsType asserts that the specified objects are of the same type.
|
// IsType asserts that the specified objects are of the same type.
|
||||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
if h, ok := a.t.(tHelper); ok {
|
if h, ok := a.t.(tHelper); ok {
|
||||||
@ -739,6 +871,28 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i
|
|||||||
return Lessf(a.t, e1, e2, msg, args...)
|
return Lessf(a.t, e1, e2, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Negative asserts that the specified element is negative
|
||||||
|
//
|
||||||
|
// a.Negative(-1)
|
||||||
|
// a.Negative(-1.23)
|
||||||
|
func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return Negative(a.t, e, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negativef asserts that the specified element is negative
|
||||||
|
//
|
||||||
|
// a.Negativef(-1, "error message %s", "formatted")
|
||||||
|
// a.Negativef(-1.23, "error message %s", "formatted")
|
||||||
|
func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return Negativef(a.t, e, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
// Never asserts that the given condition doesn't satisfy in waitFor time,
|
// Never asserts that the given condition doesn't satisfy in waitFor time,
|
||||||
// periodically checking the target function each tick.
|
// periodically checking the target function each tick.
|
||||||
//
|
//
|
||||||
@ -941,6 +1095,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
|
|||||||
return NotEqualf(a.t, expected, actual, msg, args...)
|
return NotEqualf(a.t, expected, actual, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotErrorIs asserts that at none of the errors in err's chain matches target.
|
||||||
|
// This is a wrapper for errors.Is.
|
||||||
|
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return NotErrorIs(a.t, err, target, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotErrorIsf asserts that at none of the errors in err's chain matches target.
|
||||||
|
// This is a wrapper for errors.Is.
|
||||||
|
func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return NotErrorIsf(a.t, err, target, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
// NotNil asserts that the specified object is not nil.
|
// NotNil asserts that the specified object is not nil.
|
||||||
//
|
//
|
||||||
// a.NotNil(err)
|
// a.NotNil(err)
|
||||||
@ -1133,6 +1305,28 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b
|
|||||||
return Panicsf(a.t, f, msg, args...)
|
return Panicsf(a.t, f, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Positive asserts that the specified element is positive
|
||||||
|
//
|
||||||
|
// a.Positive(1)
|
||||||
|
// a.Positive(1.23)
|
||||||
|
func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return Positive(a.t, e, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Positivef asserts that the specified element is positive
|
||||||
|
//
|
||||||
|
// a.Positivef(1, "error message %s", "formatted")
|
||||||
|
// a.Positivef(1.23, "error message %s", "formatted")
|
||||||
|
func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return Positivef(a.t, e, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
// Regexp asserts that a specified regexp matches a string.
|
// Regexp asserts that a specified regexp matches a string.
|
||||||
//
|
//
|
||||||
// a.Regexp(regexp.MustCompile("start"), "it's starting")
|
// a.Regexp(regexp.MustCompile("start"), "it's starting")
|
||||||
|
81
vendor/github.com/stretchr/testify/assert/assertion_order.go
generated
vendored
Normal file
81
vendor/github.com/stretchr/testify/assert/assertion_order.go
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package assert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// isOrdered checks that collection contains orderable elements.
|
||||||
|
func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {
|
||||||
|
objKind := reflect.TypeOf(object).Kind()
|
||||||
|
if objKind != reflect.Slice && objKind != reflect.Array {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
objValue := reflect.ValueOf(object)
|
||||||
|
objLen := objValue.Len()
|
||||||
|
|
||||||
|
if objLen <= 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
value := objValue.Index(0)
|
||||||
|
valueInterface := value.Interface()
|
||||||
|
firstValueKind := value.Kind()
|
||||||
|
|
||||||
|
for i := 1; i < objLen; i++ {
|
||||||
|
prevValue := value
|
||||||
|
prevValueInterface := valueInterface
|
||||||
|
|
||||||
|
value = objValue.Index(i)
|
||||||
|
valueInterface = value.Interface()
|
||||||
|
|
||||||
|
compareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind)
|
||||||
|
|
||||||
|
if !isComparable {
|
||||||
|
return Fail(t, fmt.Sprintf("Can not compare type \"%s\" and \"%s\"", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !containsValue(allowedComparesResults, compareResult) {
|
||||||
|
return Fail(t, fmt.Sprintf(failMessage, prevValue, value), msgAndArgs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsIncreasing asserts that the collection is increasing
|
||||||
|
//
|
||||||
|
// assert.IsIncreasing(t, []int{1, 2, 3})
|
||||||
|
// assert.IsIncreasing(t, []float{1, 2})
|
||||||
|
// assert.IsIncreasing(t, []string{"a", "b"})
|
||||||
|
func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNonIncreasing asserts that the collection is not increasing
|
||||||
|
//
|
||||||
|
// assert.IsNonIncreasing(t, []int{2, 1, 1})
|
||||||
|
// assert.IsNonIncreasing(t, []float{2, 1})
|
||||||
|
// assert.IsNonIncreasing(t, []string{"b", "a"})
|
||||||
|
func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDecreasing asserts that the collection is decreasing
|
||||||
|
//
|
||||||
|
// assert.IsDecreasing(t, []int{2, 1, 0})
|
||||||
|
// assert.IsDecreasing(t, []float{2, 1})
|
||||||
|
// assert.IsDecreasing(t, []string{"b", "a"})
|
||||||
|
func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNonDecreasing asserts that the collection is not decreasing
|
||||||
|
//
|
||||||
|
// assert.IsNonDecreasing(t, []int{1, 1, 2})
|
||||||
|
// assert.IsNonDecreasing(t, []float{1, 2})
|
||||||
|
// assert.IsNonDecreasing(t, []string{"a", "b"})
|
||||||
|
func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs)
|
||||||
|
}
|
83
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
83
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
@ -172,8 +172,8 @@ func isTest(name, prefix string) bool {
|
|||||||
if len(name) == len(prefix) { // "Test" is ok
|
if len(name) == len(prefix) { // "Test" is ok
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
|
r, _ := utf8.DecodeRuneInString(name[len(prefix):])
|
||||||
return !unicode.IsLower(rune)
|
return !unicode.IsLower(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
|
func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
|
||||||
@ -1622,6 +1622,7 @@ var spewConfig = spew.ConfigState{
|
|||||||
DisableCapacities: true,
|
DisableCapacities: true,
|
||||||
SortKeys: true,
|
SortKeys: true,
|
||||||
DisableMethods: true,
|
DisableMethods: true,
|
||||||
|
MaxDepth: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
type tHelper interface {
|
type tHelper interface {
|
||||||
@ -1693,3 +1694,81 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrorIs asserts that at least one of the errors in err's chain matches target.
|
||||||
|
// This is a wrapper for errors.Is.
|
||||||
|
func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
if errors.Is(err, target) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var expectedText string
|
||||||
|
if target != nil {
|
||||||
|
expectedText = target.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
chain := buildErrorChainString(err)
|
||||||
|
|
||||||
|
return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+
|
||||||
|
"expected: %q\n"+
|
||||||
|
"in chain: %s", expectedText, chain,
|
||||||
|
), msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotErrorIs asserts that at none of the errors in err's chain matches target.
|
||||||
|
// This is a wrapper for errors.Is.
|
||||||
|
func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
if !errors.Is(err, target) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var expectedText string
|
||||||
|
if target != nil {
|
||||||
|
expectedText = target.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
chain := buildErrorChainString(err)
|
||||||
|
|
||||||
|
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
|
||||||
|
"found: %q\n"+
|
||||||
|
"in chain: %s", expectedText, chain,
|
||||||
|
), msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||||
|
// This is a wrapper for errors.As.
|
||||||
|
func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
if errors.As(err, target) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
chain := buildErrorChainString(err)
|
||||||
|
|
||||||
|
return Fail(t, fmt.Sprintf("Should be in error chain:\n"+
|
||||||
|
"expected: %q\n"+
|
||||||
|
"in chain: %s", target, chain,
|
||||||
|
), msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildErrorChainString(err error) string {
|
||||||
|
if err == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
e := errors.Unwrap(err)
|
||||||
|
chain := fmt.Sprintf("%q", err.Error())
|
||||||
|
for e != nil {
|
||||||
|
chain += fmt.Sprintf("\n\t%q", e.Error())
|
||||||
|
e = errors.Unwrap(e)
|
||||||
|
}
|
||||||
|
return chain
|
||||||
|
}
|
||||||
|
28
vendor/github.com/stretchr/testify/require/doc.go
generated
vendored
Normal file
28
vendor/github.com/stretchr/testify/require/doc.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Package require implements the same assertions as the `assert` package but
|
||||||
|
// stops test execution when a test fails.
|
||||||
|
//
|
||||||
|
// Example Usage
|
||||||
|
//
|
||||||
|
// The following is a complete example using require in a standard test function:
|
||||||
|
// import (
|
||||||
|
// "testing"
|
||||||
|
// "github.com/stretchr/testify/require"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func TestSomething(t *testing.T) {
|
||||||
|
//
|
||||||
|
// var a string = "Hello"
|
||||||
|
// var b string = "Hello"
|
||||||
|
//
|
||||||
|
// require.Equal(t, a, b, "The two words should be the same.")
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Assertions
|
||||||
|
//
|
||||||
|
// The `require` package have same global functions as in the `assert` package,
|
||||||
|
// but instead of returning a boolean result they call `t.FailNow()`.
|
||||||
|
//
|
||||||
|
// Every assertion function also takes an optional string message as the final argument,
|
||||||
|
// allowing custom error messages to be appended to the message the assertion method outputs.
|
||||||
|
package require
|
16
vendor/github.com/stretchr/testify/require/forward_requirements.go
generated
vendored
Normal file
16
vendor/github.com/stretchr/testify/require/forward_requirements.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package require
|
||||||
|
|
||||||
|
// Assertions provides assertion methods around the
|
||||||
|
// TestingT interface.
|
||||||
|
type Assertions struct {
|
||||||
|
t TestingT
|
||||||
|
}
|
||||||
|
|
||||||
|
// New makes a new Assertions object for the specified TestingT.
|
||||||
|
func New(t TestingT) *Assertions {
|
||||||
|
return &Assertions{
|
||||||
|
t: t,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require_forward.go.tmpl -include-format-funcs"
|
1879
vendor/github.com/stretchr/testify/require/require.go
generated
vendored
Normal file
1879
vendor/github.com/stretchr/testify/require/require.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
vendor/github.com/stretchr/testify/require/require.go.tmpl
generated
vendored
Normal file
6
vendor/github.com/stretchr/testify/require/require.go.tmpl
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{{.Comment}}
|
||||||
|
func {{.DocInfo.Name}}(t TestingT, {{.Params}}) {
|
||||||
|
if h, ok := t.(tHelper); ok { h.Helper() }
|
||||||
|
if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return }
|
||||||
|
t.FailNow()
|
||||||
|
}
|
1471
vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
Normal file
1471
vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
vendor/github.com/stretchr/testify/require/require_forward.go.tmpl
generated
vendored
Normal file
5
vendor/github.com/stretchr/testify/require/require_forward.go.tmpl
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{{.CommentWithoutT "a"}}
|
||||||
|
func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) {
|
||||||
|
if h, ok := a.t.(tHelper); ok { h.Helper() }
|
||||||
|
{{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
|
||||||
|
}
|
29
vendor/github.com/stretchr/testify/require/requirements.go
generated
vendored
Normal file
29
vendor/github.com/stretchr/testify/require/requirements.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package require
|
||||||
|
|
||||||
|
// TestingT is an interface wrapper around *testing.T
|
||||||
|
type TestingT interface {
|
||||||
|
Errorf(format string, args ...interface{})
|
||||||
|
FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
type tHelper interface {
|
||||||
|
Helper()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful
|
||||||
|
// for table driven tests.
|
||||||
|
type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{})
|
||||||
|
|
||||||
|
// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful
|
||||||
|
// for table driven tests.
|
||||||
|
type ValueAssertionFunc func(TestingT, interface{}, ...interface{})
|
||||||
|
|
||||||
|
// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful
|
||||||
|
// for table driven tests.
|
||||||
|
type BoolAssertionFunc func(TestingT, bool, ...interface{})
|
||||||
|
|
||||||
|
// ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful
|
||||||
|
// for table driven tests.
|
||||||
|
type ErrorAssertionFunc func(TestingT, error, ...interface{})
|
||||||
|
|
||||||
|
//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs"
|
16
vendor/gopkg.in/yaml.v3/.travis.yml
generated
vendored
16
vendor/gopkg.in/yaml.v3/.travis.yml
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- "1.4.x"
|
|
||||||
- "1.5.x"
|
|
||||||
- "1.6.x"
|
|
||||||
- "1.7.x"
|
|
||||||
- "1.8.x"
|
|
||||||
- "1.9.x"
|
|
||||||
- "1.10.x"
|
|
||||||
- "1.11.x"
|
|
||||||
- "1.12.x"
|
|
||||||
- "1.13.x"
|
|
||||||
- "tip"
|
|
||||||
|
|
||||||
go_import_path: gopkg.in/yaml.v3
|
|
1
vendor/gopkg.in/yaml.v3/apic.go
generated
vendored
1
vendor/gopkg.in/yaml.v3/apic.go
generated
vendored
@ -108,6 +108,7 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) {
|
|||||||
raw_buffer: make([]byte, 0, output_raw_buffer_size),
|
raw_buffer: make([]byte, 0, output_raw_buffer_size),
|
||||||
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
|
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
|
||||||
events: make([]yaml_event_t, 0, initial_queue_size),
|
events: make([]yaml_event_t, 0, initial_queue_size),
|
||||||
|
best_width: -1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
65
vendor/gopkg.in/yaml.v3/decode.go
generated
vendored
65
vendor/gopkg.in/yaml.v3/decode.go
generated
vendored
@ -35,6 +35,7 @@ type parser struct {
|
|||||||
doc *Node
|
doc *Node
|
||||||
anchors map[string]*Node
|
anchors map[string]*Node
|
||||||
doneInit bool
|
doneInit bool
|
||||||
|
textless bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newParser(b []byte) *parser {
|
func newParser(b []byte) *parser {
|
||||||
@ -108,14 +109,18 @@ func (p *parser) peek() yaml_event_type_t {
|
|||||||
func (p *parser) fail() {
|
func (p *parser) fail() {
|
||||||
var where string
|
var where string
|
||||||
var line int
|
var line int
|
||||||
if p.parser.problem_mark.line != 0 {
|
if p.parser.context_mark.line != 0 {
|
||||||
|
line = p.parser.context_mark.line
|
||||||
|
// Scanner errors don't iterate line before returning error
|
||||||
|
if p.parser.error == yaml_SCANNER_ERROR {
|
||||||
|
line++
|
||||||
|
}
|
||||||
|
} else if p.parser.problem_mark.line != 0 {
|
||||||
line = p.parser.problem_mark.line
|
line = p.parser.problem_mark.line
|
||||||
// Scanner errors don't iterate line before returning error
|
// Scanner errors don't iterate line before returning error
|
||||||
if p.parser.error == yaml_SCANNER_ERROR {
|
if p.parser.error == yaml_SCANNER_ERROR {
|
||||||
line++
|
line++
|
||||||
}
|
}
|
||||||
} else if p.parser.context_mark.line != 0 {
|
|
||||||
line = p.parser.context_mark.line
|
|
||||||
}
|
}
|
||||||
if line != 0 {
|
if line != 0 {
|
||||||
where = "line " + strconv.Itoa(line) + ": "
|
where = "line " + strconv.Itoa(line) + ": "
|
||||||
@ -169,17 +174,20 @@ func (p *parser) node(kind Kind, defaultTag, tag, value string) *Node {
|
|||||||
} else if kind == ScalarNode {
|
} else if kind == ScalarNode {
|
||||||
tag, _ = resolve("", value)
|
tag, _ = resolve("", value)
|
||||||
}
|
}
|
||||||
return &Node{
|
n := &Node{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Tag: tag,
|
Tag: tag,
|
||||||
Value: value,
|
Value: value,
|
||||||
Style: style,
|
Style: style,
|
||||||
Line: p.event.start_mark.line + 1,
|
|
||||||
Column: p.event.start_mark.column + 1,
|
|
||||||
HeadComment: string(p.event.head_comment),
|
|
||||||
LineComment: string(p.event.line_comment),
|
|
||||||
FootComment: string(p.event.foot_comment),
|
|
||||||
}
|
}
|
||||||
|
if !p.textless {
|
||||||
|
n.Line = p.event.start_mark.line + 1
|
||||||
|
n.Column = p.event.start_mark.column + 1
|
||||||
|
n.HeadComment = string(p.event.head_comment)
|
||||||
|
n.LineComment = string(p.event.line_comment)
|
||||||
|
n.FootComment = string(p.event.foot_comment)
|
||||||
|
}
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) parseChild(parent *Node) *Node {
|
func (p *parser) parseChild(parent *Node) *Node {
|
||||||
@ -497,8 +505,13 @@ func (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) {
|
|||||||
good = d.mapping(n, out)
|
good = d.mapping(n, out)
|
||||||
case SequenceNode:
|
case SequenceNode:
|
||||||
good = d.sequence(n, out)
|
good = d.sequence(n, out)
|
||||||
|
case 0:
|
||||||
|
if n.IsZero() {
|
||||||
|
return d.null(out)
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
default:
|
default:
|
||||||
panic("internal error: unknown node kind: " + strconv.Itoa(int(n.Kind)))
|
failf("cannot decode node with unknown kind %d", n.Kind)
|
||||||
}
|
}
|
||||||
return good
|
return good
|
||||||
}
|
}
|
||||||
@ -533,6 +546,17 @@ func resetMap(out reflect.Value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *decoder) null(out reflect.Value) bool {
|
||||||
|
if out.CanAddr() {
|
||||||
|
switch out.Kind() {
|
||||||
|
case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
|
||||||
|
out.Set(reflect.Zero(out.Type()))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (d *decoder) scalar(n *Node, out reflect.Value) bool {
|
func (d *decoder) scalar(n *Node, out reflect.Value) bool {
|
||||||
var tag string
|
var tag string
|
||||||
var resolved interface{}
|
var resolved interface{}
|
||||||
@ -550,14 +574,7 @@ func (d *decoder) scalar(n *Node, out reflect.Value) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if resolved == nil {
|
if resolved == nil {
|
||||||
if out.CanAddr() {
|
return d.null(out)
|
||||||
switch out.Kind() {
|
|
||||||
case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
|
|
||||||
out.Set(reflect.Zero(out.Type()))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
|
if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
|
||||||
// We've resolved to exactly the type we want, so use that.
|
// We've resolved to exactly the type we want, so use that.
|
||||||
@ -791,8 +808,10 @@ func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapIsNew := false
|
||||||
if out.IsNil() {
|
if out.IsNil() {
|
||||||
out.Set(reflect.MakeMap(outt))
|
out.Set(reflect.MakeMap(outt))
|
||||||
|
mapIsNew = true
|
||||||
}
|
}
|
||||||
for i := 0; i < l; i += 2 {
|
for i := 0; i < l; i += 2 {
|
||||||
if isMerge(n.Content[i]) {
|
if isMerge(n.Content[i]) {
|
||||||
@ -809,7 +828,7 @@ func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) {
|
|||||||
failf("invalid map key: %#v", k.Interface())
|
failf("invalid map key: %#v", k.Interface())
|
||||||
}
|
}
|
||||||
e := reflect.New(et).Elem()
|
e := reflect.New(et).Elem()
|
||||||
if d.unmarshal(n.Content[i+1], e) {
|
if d.unmarshal(n.Content[i+1], e) || n.Content[i+1].ShortTag() == nullTag && (mapIsNew || !out.MapIndex(k).IsValid()) {
|
||||||
out.SetMapIndex(k, e)
|
out.SetMapIndex(k, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
58
vendor/gopkg.in/yaml.v3/emitterc.go
generated
vendored
58
vendor/gopkg.in/yaml.v3/emitterc.go
generated
vendored
@ -235,10 +235,13 @@ func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool
|
|||||||
emitter.indent = 0
|
emitter.indent = 0
|
||||||
}
|
}
|
||||||
} else if !indentless {
|
} else if !indentless {
|
||||||
emitter.indent += emitter.best_indent
|
// [Go] This was changed so that indentations are more regular.
|
||||||
// [Go] If inside a block sequence item, discount the space taken by the indicator.
|
if emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE {
|
||||||
if emitter.best_indent > 2 && emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE {
|
// The first indent inside a sequence will just skip the "- " indicator.
|
||||||
emitter.indent -= 2
|
emitter.indent += 2
|
||||||
|
} else {
|
||||||
|
// Everything else aligns to the chosen indentation.
|
||||||
|
emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -725,16 +728,9 @@ func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_e
|
|||||||
// Expect a block item node.
|
// Expect a block item node.
|
||||||
func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
|
func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
|
||||||
if first {
|
if first {
|
||||||
// [Go] The original logic here would not indent the sequence when inside a mapping.
|
if !yaml_emitter_increase_indent(emitter, false, false) {
|
||||||
// In Go we always indent it, but take the sequence indicator out of the indentation.
|
|
||||||
indentless := emitter.best_indent == 2 && emitter.mapping_context && (emitter.column == 0 || !emitter.indention)
|
|
||||||
original := emitter.indent
|
|
||||||
if !yaml_emitter_increase_indent(emitter, false, indentless) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if emitter.indent > original+2 {
|
|
||||||
emitter.indent -= 2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if event.typ == yaml_SEQUENCE_END_EVENT {
|
if event.typ == yaml_SEQUENCE_END_EVENT {
|
||||||
emitter.indent = emitter.indents[len(emitter.indents)-1]
|
emitter.indent = emitter.indents[len(emitter.indents)-1]
|
||||||
@ -785,6 +781,13 @@ func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_ev
|
|||||||
if !yaml_emitter_write_indent(emitter) {
|
if !yaml_emitter_write_indent(emitter) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if len(emitter.line_comment) > 0 {
|
||||||
|
// [Go] A line comment was provided for the key. That's unusual as the
|
||||||
|
// scanner associates line comments with the value. Either way,
|
||||||
|
// save the line comment and render it appropriately later.
|
||||||
|
emitter.key_line_comment = emitter.line_comment
|
||||||
|
emitter.line_comment = nil
|
||||||
|
}
|
||||||
if yaml_emitter_check_simple_key(emitter) {
|
if yaml_emitter_check_simple_key(emitter) {
|
||||||
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
|
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
|
||||||
return yaml_emitter_emit_node(emitter, event, false, false, true, true)
|
return yaml_emitter_emit_node(emitter, event, false, false, true, true)
|
||||||
@ -810,6 +813,27 @@ func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(emitter.key_line_comment) > 0 {
|
||||||
|
// [Go] Line comments are generally associated with the value, but when there's
|
||||||
|
// no value on the same line as a mapping key they end up attached to the
|
||||||
|
// key itself.
|
||||||
|
if event.typ == yaml_SCALAR_EVENT {
|
||||||
|
if len(emitter.line_comment) == 0 {
|
||||||
|
// A scalar is coming and it has no line comments by itself yet,
|
||||||
|
// so just let it handle the line comment as usual. If it has a
|
||||||
|
// line comment, we can't have both so the one from the key is lost.
|
||||||
|
emitter.line_comment = emitter.key_line_comment
|
||||||
|
emitter.key_line_comment = nil
|
||||||
|
}
|
||||||
|
} else if event.sequence_style() != yaml_FLOW_SEQUENCE_STYLE && (event.typ == yaml_MAPPING_START_EVENT || event.typ == yaml_SEQUENCE_START_EVENT) {
|
||||||
|
// An indented block follows, so write the comment right now.
|
||||||
|
emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment
|
||||||
|
if !yaml_emitter_process_line_comment(emitter) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment
|
||||||
|
}
|
||||||
|
}
|
||||||
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
|
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
|
||||||
if !yaml_emitter_emit_node(emitter, event, false, false, true, false) {
|
if !yaml_emitter_emit_node(emitter, event, false, false, true, false) {
|
||||||
return false
|
return false
|
||||||
@ -823,6 +847,10 @@ func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func yaml_emitter_silent_nil_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
|
||||||
|
return event.typ == yaml_SCALAR_EVENT && event.implicit && !emitter.canonical && len(emitter.scalar_data.value) == 0
|
||||||
|
}
|
||||||
|
|
||||||
// Expect a node.
|
// Expect a node.
|
||||||
func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
|
func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
|
||||||
root bool, sequence bool, mapping bool, simple_key bool) bool {
|
root bool, sequence bool, mapping bool, simple_key bool) bool {
|
||||||
@ -1866,7 +1894,7 @@ func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bo
|
|||||||
if !yaml_emitter_write_block_scalar_hints(emitter, value) {
|
if !yaml_emitter_write_block_scalar_hints(emitter, value) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !put_break(emitter) {
|
if !yaml_emitter_process_line_comment(emitter) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
//emitter.indention = true
|
//emitter.indention = true
|
||||||
@ -1903,10 +1931,10 @@ func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) boo
|
|||||||
if !yaml_emitter_write_block_scalar_hints(emitter, value) {
|
if !yaml_emitter_write_block_scalar_hints(emitter, value) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if !yaml_emitter_process_line_comment(emitter) {
|
||||||
if !put_break(emitter) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
//emitter.indention = true
|
//emitter.indention = true
|
||||||
emitter.whitespace = true
|
emitter.whitespace = true
|
||||||
|
|
||||||
|
30
vendor/gopkg.in/yaml.v3/encode.go
generated
vendored
30
vendor/gopkg.in/yaml.v3/encode.go
generated
vendored
@ -119,6 +119,14 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
|
|||||||
case *Node:
|
case *Node:
|
||||||
e.nodev(in)
|
e.nodev(in)
|
||||||
return
|
return
|
||||||
|
case Node:
|
||||||
|
if !in.CanAddr() {
|
||||||
|
var n = reflect.New(in.Type()).Elem()
|
||||||
|
n.Set(in)
|
||||||
|
in = n
|
||||||
|
}
|
||||||
|
e.nodev(in.Addr())
|
||||||
|
return
|
||||||
case time.Time:
|
case time.Time:
|
||||||
e.timev(tag, in)
|
e.timev(tag, in)
|
||||||
return
|
return
|
||||||
@ -422,18 +430,23 @@ func (e *encoder) nodev(in reflect.Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) node(node *Node, tail string) {
|
func (e *encoder) node(node *Node, tail string) {
|
||||||
|
// Zero nodes behave as nil.
|
||||||
|
if node.Kind == 0 && node.IsZero() {
|
||||||
|
e.nilv()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// If the tag was not explicitly requested, and dropping it won't change the
|
// If the tag was not explicitly requested, and dropping it won't change the
|
||||||
// implicit tag of the value, don't include it in the presentation.
|
// implicit tag of the value, don't include it in the presentation.
|
||||||
var tag = node.Tag
|
var tag = node.Tag
|
||||||
var stag = shortTag(tag)
|
var stag = shortTag(tag)
|
||||||
var rtag string
|
|
||||||
var forceQuoting bool
|
var forceQuoting bool
|
||||||
if tag != "" && node.Style&TaggedStyle == 0 {
|
if tag != "" && node.Style&TaggedStyle == 0 {
|
||||||
if node.Kind == ScalarNode {
|
if node.Kind == ScalarNode {
|
||||||
if stag == strTag && node.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0 {
|
if stag == strTag && node.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0 {
|
||||||
tag = ""
|
tag = ""
|
||||||
} else {
|
} else {
|
||||||
rtag, _ = resolve("", node.Value)
|
rtag, _ := resolve("", node.Value)
|
||||||
if rtag == stag {
|
if rtag == stag {
|
||||||
tag = ""
|
tag = ""
|
||||||
} else if stag == strTag {
|
} else if stag == strTag {
|
||||||
@ -442,6 +455,7 @@ func (e *encoder) node(node *Node, tail string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
var rtag string
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
case MappingNode:
|
case MappingNode:
|
||||||
rtag = mapTag
|
rtag = mapTag
|
||||||
@ -471,7 +485,7 @@ func (e *encoder) node(node *Node, tail string) {
|
|||||||
if node.Style&FlowStyle != 0 {
|
if node.Style&FlowStyle != 0 {
|
||||||
style = yaml_FLOW_SEQUENCE_STYLE
|
style = yaml_FLOW_SEQUENCE_STYLE
|
||||||
}
|
}
|
||||||
e.must(yaml_sequence_start_event_initialize(&e.event, []byte(node.Anchor), []byte(tag), tag == "", style))
|
e.must(yaml_sequence_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == "", style))
|
||||||
e.event.head_comment = []byte(node.HeadComment)
|
e.event.head_comment = []byte(node.HeadComment)
|
||||||
e.emit()
|
e.emit()
|
||||||
for _, node := range node.Content {
|
for _, node := range node.Content {
|
||||||
@ -487,7 +501,7 @@ func (e *encoder) node(node *Node, tail string) {
|
|||||||
if node.Style&FlowStyle != 0 {
|
if node.Style&FlowStyle != 0 {
|
||||||
style = yaml_FLOW_MAPPING_STYLE
|
style = yaml_FLOW_MAPPING_STYLE
|
||||||
}
|
}
|
||||||
yaml_mapping_start_event_initialize(&e.event, []byte(node.Anchor), []byte(tag), tag == "", style)
|
yaml_mapping_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == "", style)
|
||||||
e.event.tail_comment = []byte(tail)
|
e.event.tail_comment = []byte(tail)
|
||||||
e.event.head_comment = []byte(node.HeadComment)
|
e.event.head_comment = []byte(node.HeadComment)
|
||||||
e.emit()
|
e.emit()
|
||||||
@ -528,11 +542,11 @@ func (e *encoder) node(node *Node, tail string) {
|
|||||||
case ScalarNode:
|
case ScalarNode:
|
||||||
value := node.Value
|
value := node.Value
|
||||||
if !utf8.ValidString(value) {
|
if !utf8.ValidString(value) {
|
||||||
if tag == binaryTag {
|
if stag == binaryTag {
|
||||||
failf("explicitly tagged !!binary data must be base64-encoded")
|
failf("explicitly tagged !!binary data must be base64-encoded")
|
||||||
}
|
}
|
||||||
if tag != "" {
|
if stag != "" {
|
||||||
failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
|
failf("cannot marshal invalid UTF-8 data as %s", stag)
|
||||||
}
|
}
|
||||||
// It can't be encoded directly as YAML so use a binary tag
|
// It can't be encoded directly as YAML so use a binary tag
|
||||||
// and encode it as base64.
|
// and encode it as base64.
|
||||||
@ -557,5 +571,7 @@ func (e *encoder) node(node *Node, tail string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.emitScalar(value, node.Anchor, tag, style, []byte(node.HeadComment), []byte(node.LineComment), []byte(node.FootComment), []byte(tail))
|
e.emitScalar(value, node.Anchor, tag, style, []byte(node.HeadComment), []byte(node.LineComment), []byte(node.FootComment), []byte(tail))
|
||||||
|
default:
|
||||||
|
failf("cannot encode node with unknown kind %d", node.Kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
vendor/gopkg.in/yaml.v3/parserc.go
generated
vendored
48
vendor/gopkg.in/yaml.v3/parserc.go
generated
vendored
@ -648,6 +648,10 @@ func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, i
|
|||||||
implicit: implicit,
|
implicit: implicit,
|
||||||
style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
|
style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
|
||||||
}
|
}
|
||||||
|
if parser.stem_comment != nil {
|
||||||
|
event.head_comment = parser.stem_comment
|
||||||
|
parser.stem_comment = nil
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if len(anchor) > 0 || len(tag) > 0 {
|
if len(anchor) > 0 || len(tag) > 0 {
|
||||||
@ -694,25 +698,13 @@ func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_e
|
|||||||
|
|
||||||
if token.typ == yaml_BLOCK_ENTRY_TOKEN {
|
if token.typ == yaml_BLOCK_ENTRY_TOKEN {
|
||||||
mark := token.end_mark
|
mark := token.end_mark
|
||||||
prior_head := len(parser.head_comment)
|
prior_head_len := len(parser.head_comment)
|
||||||
skip_token(parser)
|
skip_token(parser)
|
||||||
|
yaml_parser_split_stem_comment(parser, prior_head_len)
|
||||||
token = peek_token(parser)
|
token = peek_token(parser)
|
||||||
if token == nil {
|
if token == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if prior_head > 0 && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
|
|
||||||
// [Go] It's a sequence under a sequence entry, so the former head comment
|
|
||||||
// is for the list itself, not the first list item under it.
|
|
||||||
parser.stem_comment = parser.head_comment[:prior_head]
|
|
||||||
if len(parser.head_comment) == prior_head {
|
|
||||||
parser.head_comment = nil
|
|
||||||
} else {
|
|
||||||
// Copy suffix to prevent very strange bugs if someone ever appends
|
|
||||||
// further bytes to the prefix in the stem_comment slice above.
|
|
||||||
parser.head_comment = append([]byte(nil), parser.head_comment[prior_head+1:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
|
if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
|
||||||
parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
|
parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
|
||||||
return yaml_parser_parse_node(parser, event, true, false)
|
return yaml_parser_parse_node(parser, event, true, false)
|
||||||
@ -754,7 +746,9 @@ func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *y
|
|||||||
|
|
||||||
if token.typ == yaml_BLOCK_ENTRY_TOKEN {
|
if token.typ == yaml_BLOCK_ENTRY_TOKEN {
|
||||||
mark := token.end_mark
|
mark := token.end_mark
|
||||||
|
prior_head_len := len(parser.head_comment)
|
||||||
skip_token(parser)
|
skip_token(parser)
|
||||||
|
yaml_parser_split_stem_comment(parser, prior_head_len)
|
||||||
token = peek_token(parser)
|
token = peek_token(parser)
|
||||||
if token == nil {
|
if token == nil {
|
||||||
return false
|
return false
|
||||||
@ -780,6 +774,32 @@ func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *y
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Split stem comment from head comment.
|
||||||
|
//
|
||||||
|
// When a sequence or map is found under a sequence entry, the former head comment
|
||||||
|
// is assigned to the underlying sequence or map as a whole, not the individual
|
||||||
|
// sequence or map entry as would be expected otherwise. To handle this case the
|
||||||
|
// previous head comment is moved aside as the stem comment.
|
||||||
|
func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
|
||||||
|
if stem_len == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
token := peek_token(parser)
|
||||||
|
if token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.stem_comment = parser.head_comment[:stem_len]
|
||||||
|
if len(parser.head_comment) == stem_len {
|
||||||
|
parser.head_comment = nil
|
||||||
|
} else {
|
||||||
|
// Copy suffix to prevent very strange bugs if someone ever appends
|
||||||
|
// further bytes to the prefix in the stem_comment slice above.
|
||||||
|
parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parse the productions:
|
// Parse the productions:
|
||||||
// block_mapping ::= BLOCK-MAPPING_START
|
// block_mapping ::= BLOCK-MAPPING_START
|
||||||
// *******************
|
// *******************
|
||||||
|
49
vendor/gopkg.in/yaml.v3/scannerc.go
generated
vendored
49
vendor/gopkg.in/yaml.v3/scannerc.go
generated
vendored
@ -749,6 +749,11 @@ func yaml_parser_fetch_next_token(parser *yaml_parser_t) (ok bool) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(parser.tokens) > 0 && parser.tokens[len(parser.tokens)-1].typ == yaml_BLOCK_ENTRY_TOKEN {
|
||||||
|
// Sequence indicators alone have no line comments. It becomes
|
||||||
|
// a head comment for whatever follows.
|
||||||
|
return
|
||||||
|
}
|
||||||
if !yaml_parser_scan_line_comment(parser, comment_mark) {
|
if !yaml_parser_scan_line_comment(parser, comment_mark) {
|
||||||
ok = false
|
ok = false
|
||||||
return
|
return
|
||||||
@ -2255,10 +2260,9 @@ func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if parser.buffer[parser.buffer_pos] == '#' {
|
if parser.buffer[parser.buffer_pos] == '#' {
|
||||||
// TODO Test this and then re-enable it.
|
if !yaml_parser_scan_line_comment(parser, start_mark) {
|
||||||
//if !yaml_parser_scan_line_comment(parser, start_mark) {
|
return false
|
||||||
// return false
|
}
|
||||||
//}
|
|
||||||
for !is_breakz(parser.buffer, parser.buffer_pos) {
|
for !is_breakz(parser.buffer, parser.buffer_pos) {
|
||||||
skip(parser)
|
skip(parser)
|
||||||
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
||||||
@ -2856,13 +2860,12 @@ func yaml_parser_scan_line_comment(parser *yaml_parser_t, token_mark yaml_mark_t
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
skip_line(parser)
|
skip_line(parser)
|
||||||
} else {
|
} else if parser.mark.index >= seen {
|
||||||
if parser.mark.index >= seen {
|
if len(text) == 0 {
|
||||||
if len(text) == 0 {
|
start_mark = parser.mark
|
||||||
start_mark = parser.mark
|
|
||||||
}
|
|
||||||
text = append(text, parser.buffer[parser.buffer_pos])
|
|
||||||
}
|
}
|
||||||
|
text = read(parser, text)
|
||||||
|
} else {
|
||||||
skip(parser)
|
skip(parser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2888,6 +2891,10 @@ func yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) boo
|
|||||||
|
|
||||||
var token_mark = token.start_mark
|
var token_mark = token.start_mark
|
||||||
var start_mark yaml_mark_t
|
var start_mark yaml_mark_t
|
||||||
|
var next_indent = parser.indent
|
||||||
|
if next_indent < 0 {
|
||||||
|
next_indent = 0
|
||||||
|
}
|
||||||
|
|
||||||
var recent_empty = false
|
var recent_empty = false
|
||||||
var first_empty = parser.newlines <= 1
|
var first_empty = parser.newlines <= 1
|
||||||
@ -2919,15 +2926,18 @@ func yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) boo
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c := parser.buffer[parser.buffer_pos+peek]
|
c := parser.buffer[parser.buffer_pos+peek]
|
||||||
if is_breakz(parser.buffer, parser.buffer_pos+peek) || parser.flow_level > 0 && (c == ']' || c == '}') {
|
var close_flow = parser.flow_level > 0 && (c == ']' || c == '}')
|
||||||
|
if close_flow || is_breakz(parser.buffer, parser.buffer_pos+peek) {
|
||||||
// Got line break or terminator.
|
// Got line break or terminator.
|
||||||
if !recent_empty {
|
if close_flow || !recent_empty {
|
||||||
if first_empty && (start_mark.line == foot_line || start_mark.column-1 < parser.indent) {
|
if close_flow || first_empty && (start_mark.line == foot_line && token.typ != yaml_VALUE_TOKEN || start_mark.column-1 < next_indent) {
|
||||||
// This is the first empty line and there were no empty lines before,
|
// This is the first empty line and there were no empty lines before,
|
||||||
// so this initial part of the comment is a foot of the prior token
|
// so this initial part of the comment is a foot of the prior token
|
||||||
// instead of being a head for the following one. Split it up.
|
// instead of being a head for the following one. Split it up.
|
||||||
|
// Alternatively, this might also be the last comment inside a flow
|
||||||
|
// scope, so it must be a footer.
|
||||||
if len(text) > 0 {
|
if len(text) > 0 {
|
||||||
if start_mark.column-1 < parser.indent {
|
if start_mark.column-1 < next_indent {
|
||||||
// If dedented it's unrelated to the prior token.
|
// If dedented it's unrelated to the prior token.
|
||||||
token_mark = start_mark
|
token_mark = start_mark
|
||||||
}
|
}
|
||||||
@ -2958,7 +2968,7 @@ func yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) boo
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(text) > 0 && column < parser.indent+1 && column != start_mark.column {
|
if len(text) > 0 && (close_flow || column-1 < next_indent && column != start_mark.column) {
|
||||||
// The comment at the different indentation is a foot of the
|
// The comment at the different indentation is a foot of the
|
||||||
// preceding data rather than a head of the upcoming one.
|
// preceding data rather than a head of the upcoming one.
|
||||||
parser.comments = append(parser.comments, yaml_comment_t{
|
parser.comments = append(parser.comments, yaml_comment_t{
|
||||||
@ -2999,10 +3009,9 @@ func yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) boo
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
skip_line(parser)
|
skip_line(parser)
|
||||||
|
} else if parser.mark.index >= seen {
|
||||||
|
text = read(parser, text)
|
||||||
} else {
|
} else {
|
||||||
if parser.mark.index >= seen {
|
|
||||||
text = append(text, parser.buffer[parser.buffer_pos])
|
|
||||||
}
|
|
||||||
skip(parser)
|
skip(parser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3010,6 +3019,10 @@ func yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) boo
|
|||||||
peek = 0
|
peek = 0
|
||||||
column = 0
|
column = 0
|
||||||
line = parser.mark.line
|
line = parser.mark.line
|
||||||
|
next_indent = parser.indent
|
||||||
|
if next_indent < 0 {
|
||||||
|
next_indent = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(text) > 0 {
|
if len(text) > 0 {
|
||||||
|
40
vendor/gopkg.in/yaml.v3/yaml.go
generated
vendored
40
vendor/gopkg.in/yaml.v3/yaml.go
generated
vendored
@ -89,7 +89,7 @@ func Unmarshal(in []byte, out interface{}) (err error) {
|
|||||||
return unmarshal(in, out, false)
|
return unmarshal(in, out, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Decorder reads and decodes YAML values from an input stream.
|
// A Decoder reads and decodes YAML values from an input stream.
|
||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
parser *parser
|
parser *parser
|
||||||
knownFields bool
|
knownFields bool
|
||||||
@ -194,7 +194,7 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) {
|
|||||||
// Zero valued structs will be omitted if all their public
|
// Zero valued structs will be omitted if all their public
|
||||||
// fields are zero, unless they implement an IsZero
|
// fields are zero, unless they implement an IsZero
|
||||||
// method (see the IsZeroer interface type), in which
|
// method (see the IsZeroer interface type), in which
|
||||||
// case the field will be included if that method returns true.
|
// case the field will be excluded if IsZero returns true.
|
||||||
//
|
//
|
||||||
// flow Marshal using a flow style (useful for structs,
|
// flow Marshal using a flow style (useful for structs,
|
||||||
// sequences and maps).
|
// sequences and maps).
|
||||||
@ -252,6 +252,24 @@ func (e *Encoder) Encode(v interface{}) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode encodes value v and stores its representation in n.
|
||||||
|
//
|
||||||
|
// See the documentation for Marshal for details about the
|
||||||
|
// conversion of Go values into YAML.
|
||||||
|
func (n *Node) Encode(v interface{}) (err error) {
|
||||||
|
defer handleErr(&err)
|
||||||
|
e := newEncoder()
|
||||||
|
defer e.destroy()
|
||||||
|
e.marshalDoc("", reflect.ValueOf(v))
|
||||||
|
e.finish()
|
||||||
|
p := newParser(e.out)
|
||||||
|
p.textless = true
|
||||||
|
defer p.destroy()
|
||||||
|
doc := p.parse()
|
||||||
|
*n = *doc.Content[0]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetIndent changes the used indentation used when encoding.
|
// SetIndent changes the used indentation used when encoding.
|
||||||
func (e *Encoder) SetIndent(spaces int) {
|
func (e *Encoder) SetIndent(spaces int) {
|
||||||
if spaces < 0 {
|
if spaces < 0 {
|
||||||
@ -328,6 +346,12 @@ const (
|
|||||||
// and maps, Node is an intermediate representation that allows detailed
|
// and maps, Node is an intermediate representation that allows detailed
|
||||||
// control over the content being decoded or encoded.
|
// control over the content being decoded or encoded.
|
||||||
//
|
//
|
||||||
|
// It's worth noting that although Node offers access into details such as
|
||||||
|
// line numbers, colums, and comments, the content when re-encoded will not
|
||||||
|
// have its original textual representation preserved. An effort is made to
|
||||||
|
// render the data plesantly, and to preserve comments near the data they
|
||||||
|
// describe, though.
|
||||||
|
//
|
||||||
// Values that make use of the Node type interact with the yaml package in the
|
// Values that make use of the Node type interact with the yaml package in the
|
||||||
// same way any other type would do, by encoding and decoding yaml data
|
// same way any other type would do, by encoding and decoding yaml data
|
||||||
// directly or indirectly into them.
|
// directly or indirectly into them.
|
||||||
@ -391,6 +415,13 @@ type Node struct {
|
|||||||
Column int
|
Column int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsZero returns whether the node has all of its fields unset.
|
||||||
|
func (n *Node) IsZero() bool {
|
||||||
|
return n.Kind == 0 && n.Style == 0 && n.Tag == "" && n.Value == "" && n.Anchor == "" && n.Alias == nil && n.Content == nil &&
|
||||||
|
n.HeadComment == "" && n.LineComment == "" && n.FootComment == "" && n.Line == 0 && n.Column == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// LongTag returns the long form of the tag that indicates the data type for
|
// LongTag returns the long form of the tag that indicates the data type for
|
||||||
// the node. If the Tag field isn't explicitly defined, one will be computed
|
// the node. If the Tag field isn't explicitly defined, one will be computed
|
||||||
// based on the node properties.
|
// based on the node properties.
|
||||||
@ -418,6 +449,11 @@ func (n *Node) ShortTag() string {
|
|||||||
case ScalarNode:
|
case ScalarNode:
|
||||||
tag, _ := resolve("", n.Value)
|
tag, _ := resolve("", n.Value)
|
||||||
return tag
|
return tag
|
||||||
|
case 0:
|
||||||
|
// Special case to make the zero value convenient.
|
||||||
|
if n.IsZero() {
|
||||||
|
return nullTag
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user