Compare commits
41 Commits
Author | SHA1 | Date | |
---|---|---|---|
e72aa1c853 | |||
3c02969ffd | |||
7a3fd4e400 | |||
d10f31109b | |||
eb5d136207 | |||
32ddcdc269 | |||
bb2a195007 | |||
3c797f0850 | |||
715eedf4bf | |||
fa74f7ad4c | |||
d7738f79e1 | |||
1a1a8e0f98 | |||
5b0f744a75 | |||
f79bc57d83 | |||
9b2e68ae0a | |||
9e2662d1dd | |||
2daa8927d1 | |||
6c77212eba | |||
eb7ea55016 | |||
5ef001a877 | |||
08fd6fab59 | |||
3a87c3e8ef | |||
9f8c4f4135 | |||
14decf2db8 | |||
5bfdaf5974 | |||
b2ce13bed2 | |||
f0612534a3 | |||
3f8a7d5d6e | |||
b06ab1c801 | |||
fd08fe13fe | |||
74543480f1 | |||
a196e4dc46 | |||
6e76a6dbd9 | |||
85a7d0bb3a | |||
cfcb9d9387 | |||
deb1c47ca4 | |||
c09ead8ae0 | |||
3e23f7e872 | |||
fc4b4cc2e6 | |||
c320cc8133 | |||
a493f65f18 |
141
.drone.yml
141
.drone.yml
@ -1,64 +1,70 @@
|
|||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: cleanup-before
|
name: build-linux
|
||||||
|
|
||||||
|
environment:
|
||||||
|
GOOS: linux
|
||||||
|
GOOPTIONS: -mod=vendor
|
||||||
|
SRCFILES: cmd/dip/*.go
|
||||||
|
PROJECTNAME: dip
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: clean
|
- name: build-linux-amd64
|
||||||
image: alpine
|
|
||||||
commands:
|
|
||||||
- rm -rf /build/*
|
|
||||||
volumes:
|
|
||||||
- name: build
|
|
||||||
path: /build
|
|
||||||
when:
|
|
||||||
event: tag
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- name: build
|
|
||||||
host:
|
|
||||||
path: /tmp/dip/build
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: default-linux-amd64
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build
|
|
||||||
image: golang
|
image: golang
|
||||||
commands:
|
commands:
|
||||||
- ./ci-build.sh build
|
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
||||||
environment:
|
environment:
|
||||||
GOOS: linux
|
|
||||||
GOARCH: amd64
|
GOARCH: amd64
|
||||||
volumes:
|
when:
|
||||||
- name: build
|
event:
|
||||||
path: /build
|
exclude:
|
||||||
|
- tag
|
||||||
volumes:
|
- name: build-linux-arm64
|
||||||
- name: build
|
image: golang
|
||||||
host:
|
commands:
|
||||||
path: /tmp/dip/build
|
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
||||||
|
environment:
|
||||||
depends_on:
|
GOARCH: arm64
|
||||||
- cleanup-before
|
when:
|
||||||
|
event:
|
||||||
|
exclude:
|
||||||
|
- tag
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: gitea-release
|
name: gitea-release-linux
|
||||||
|
|
||||||
|
environment:
|
||||||
|
GOOS: linux
|
||||||
|
GOOPTIONS: -mod=vendor
|
||||||
|
SRCFILES: cmd/dip/*.go
|
||||||
|
PROJECTNAME: dip
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: move
|
- name: build-linux-amd64
|
||||||
image: alpine
|
image: golang
|
||||||
commands:
|
commands:
|
||||||
- mv build/* ./
|
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
||||||
volumes:
|
- tar -czvf $PROJECTNAME-$DRONE_TAG-$GOOS-$GOARCH.tar.gz $PROJECTNAME
|
||||||
- name: build
|
- echo $PROJECTNAME $DRONE_TAG > VERSION
|
||||||
path: /drone/src/build
|
environment:
|
||||||
|
GOARCH: amd64
|
||||||
when:
|
when:
|
||||||
event: tag
|
event:
|
||||||
|
- tag
|
||||||
|
- name: build-linux-arm64
|
||||||
|
image: golang
|
||||||
|
commands:
|
||||||
|
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
|
||||||
|
- tar -czvf $PROJECTNAME-$DRONE_TAG-$GOOS-$GOARCH.tar.gz $PROJECTNAME
|
||||||
|
- echo $PROJECTNAME $DRONE_TAG > VERSION
|
||||||
|
environment:
|
||||||
|
GOARCH: arm64
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
- name: release
|
- name: release
|
||||||
image: plugins/gitea-release
|
image: plugins/gitea-release
|
||||||
settings:
|
settings:
|
||||||
@ -70,49 +76,6 @@ steps:
|
|||||||
- sha256
|
- sha256
|
||||||
- sha512
|
- sha512
|
||||||
title: VERSION
|
title: VERSION
|
||||||
volumes:
|
|
||||||
- name: build
|
|
||||||
path: /drone/src/build
|
|
||||||
when:
|
when:
|
||||||
event: tag
|
event:
|
||||||
- name: ls
|
- tag
|
||||||
image: alpine
|
|
||||||
commands:
|
|
||||||
- find .
|
|
||||||
volumes:
|
|
||||||
- name: build
|
|
||||||
path: /drone/src/build
|
|
||||||
when:
|
|
||||||
event: tag
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- name: build
|
|
||||||
host:
|
|
||||||
path: /tmp/dip/build
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- default-linux-amd64
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: cleanup-after
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: clean
|
|
||||||
image: alpine
|
|
||||||
commands:
|
|
||||||
- rm -rf /build/*
|
|
||||||
volumes:
|
|
||||||
- name: build
|
|
||||||
path: /build
|
|
||||||
when:
|
|
||||||
event: tag
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- name: build
|
|
||||||
host:
|
|
||||||
path: /tmp/dip/build
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- gitea-release
|
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -24,3 +24,5 @@ main-packr.go
|
|||||||
|
|
||||||
# executable file
|
# executable file
|
||||||
/dip
|
/dip
|
||||||
|
|
||||||
|
/geoip
|
9
Dockerfile
Normal file
9
Dockerfile
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
ADD dip /dip
|
||||||
|
|
||||||
|
RUN apt update -y && apt install -y ca-certificates && apt clean
|
||||||
|
|
||||||
|
ENTRYPOINT ["/dip","-port","8989"]
|
||||||
|
|
||||||
|
EXPOSE 8989/tcp
|
21
Makefile
21
Makefile
@ -1,21 +0,0 @@
|
|||||||
# dip Makefile
|
|
||||||
|
|
||||||
PROJECT=dip
|
|
||||||
GOCMD=go
|
|
||||||
GOBUILDCMD=${GOCMD} build
|
|
||||||
GOOPTIONS=-mod=vendor -ldflags="-s -w" -o ${PROJECT}
|
|
||||||
PACKRCMD=${GOPATH}/bin/packr2
|
|
||||||
RMCMD=/bin/rm
|
|
||||||
|
|
||||||
SRCFILES=cmd/dip/*.go
|
|
||||||
|
|
||||||
all: build
|
|
||||||
|
|
||||||
build:
|
|
||||||
${PACKRCMD}
|
|
||||||
${GOBUILDCMD} ${GOOPTIONS} ${SRCFILES}
|
|
||||||
|
|
||||||
clean:
|
|
||||||
${RMCMD} ${PROJECT}
|
|
||||||
${PACKRCMD} clean
|
|
||||||
|
|
13
README.md
13
README.md
@ -1,21 +1,14 @@
|
|||||||
# dip
|
# dip
|
||||||
[![Build Status](https://drone.paulbsd.com/api/badges/paulbsd/dip/status.svg)](https://drone.paulbsd.com/paulbsd/dip)
|
[![Build Status](https://drone.paulbsd.com/api/badges/paulbsd/dip/status.svg)](https://drone.paulbsd.com/paulbsd/dip)
|
||||||
|
|
||||||
dip is a small webservice designed to return public ip address
|
dip is a small webservice retrieving the IP addressing information
|
||||||
|
|
||||||
## Howto
|
## Howto
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
Install packr to create embedded files in binary executable file
|
|
||||||
```bash
|
|
||||||
go get -u github.com/gobuffalo/packr/v2/packr2
|
|
||||||
```
|
|
||||||
|
|
||||||
### Build
|
### Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make
|
go build cmd/dip/dip.go
|
||||||
```
|
```
|
||||||
|
|
||||||
### Play
|
### Play
|
||||||
@ -37,7 +30,7 @@ curl -H "Accept: text/html" http://localhost:8080/
|
|||||||
## License
|
## License
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Copyright (c) 2020 PaulBSD
|
Copyright (c) 2020, 2021, 2022, 2023 PaulBSD
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
66
ci-build.sh
66
ci-build.sh
@ -1,66 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
PROJECTNAME=dip
|
|
||||||
RELEASENAME=${PROJECTNAME}
|
|
||||||
VERSION="0"
|
|
||||||
|
|
||||||
GOOPTIONS="-mod=vendor"
|
|
||||||
SRCFILES=cmd/dip/*.go
|
|
||||||
|
|
||||||
build() {
|
|
||||||
echo "Begin of build"
|
|
||||||
if [[ ! -z $DRONE_TAG ]]
|
|
||||||
then
|
|
||||||
echo "Drone tag set, let's do a release"
|
|
||||||
VERSION=$DRONE_TAG
|
|
||||||
echo "${PROJECTNAME} ${VERSION}" > /build/VERSION
|
|
||||||
elif [[ ! -z $DRONE_TAG ]]
|
|
||||||
then
|
|
||||||
echo "Drone not set, let's only do a build"
|
|
||||||
VERSION=$DRONE_COMMIT
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -z $VERSION && ! -z $GOOS && ! -z $GOARCH ]]
|
|
||||||
then
|
|
||||||
echo "Let's set a release name"
|
|
||||||
RELEASENAME=${PROJECTNAME}-${VERSION}-${GOOS}-${GOARCH}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Getting packr2 and building embedded files"
|
|
||||||
go install github.com/gobuffalo/packr/v2/packr2@latest
|
|
||||||
packr2
|
|
||||||
|
|
||||||
echo "Building project"
|
|
||||||
go build -o ${PROJECTNAME} ${GOOPTIONS} ${SRCFILES}
|
|
||||||
|
|
||||||
if [[ ! -z $DRONE_TAG ]]
|
|
||||||
then
|
|
||||||
echo "Let's make archives"
|
|
||||||
mkdir -p /build
|
|
||||||
tar -czvf /build/${RELEASENAME}.tar.gz ${PROJECTNAME}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Removing binary file"
|
|
||||||
rm ${PROJECTNAME}
|
|
||||||
|
|
||||||
echo "End of build"
|
|
||||||
}
|
|
||||||
|
|
||||||
clean() {
|
|
||||||
rm -rf $RELEASEDIR
|
|
||||||
}
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
"build")
|
|
||||||
build
|
|
||||||
;;
|
|
||||||
"clean")
|
|
||||||
clean
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "No options choosen"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
@ -1,17 +1,30 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "git.paulbsd.com/paulbsd/dip/packrd"
|
"os"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/dip/src/config"
|
"git.paulbsd.com/paulbsd/dip/src/config"
|
||||||
|
"git.paulbsd.com/paulbsd/dip/src/dip"
|
||||||
"git.paulbsd.com/paulbsd/dip/src/ws"
|
"git.paulbsd.com/paulbsd/dip/src/ws"
|
||||||
|
staticfiles "git.paulbsd.com/paulbsd/dip/static"
|
||||||
|
templatefiles "git.paulbsd.com/paulbsd/dip/templates"
|
||||||
"git.paulbsd.com/paulbsd/dip/utils"
|
"git.paulbsd.com/paulbsd/dip/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var config config.Config
|
var config config.Config
|
||||||
|
var Templates = &templatefiles.Templates
|
||||||
|
var Static = &staticfiles.Static
|
||||||
utils.Flags(&config.Host, &config.Port)
|
utils.Flags(&config.Host, &config.Port)
|
||||||
|
|
||||||
ws := ws.WS{}
|
ws := ws.WS{}
|
||||||
ws.Page.Title = "Public IP Address Service"
|
ws.Page.Title = "Public IP Address Service"
|
||||||
ws.RunServer(config)
|
dip.Init()
|
||||||
|
|
||||||
|
memcacheconn, ok := os.LookupEnv("MEMCACHECONN")
|
||||||
|
if ok {
|
||||||
|
dip.MemcacheConn = memcacheconn
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.RunServer(config, Templates, Static)
|
||||||
}
|
}
|
||||||
|
53
go.mod
53
go.mod
@ -1,46 +1,27 @@
|
|||||||
module git.paulbsd.com/paulbsd/dip
|
module git.paulbsd.com/paulbsd/dip
|
||||||
|
|
||||||
go 1.17
|
go 1.23
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gobuffalo/packr/v2 v2.8.1
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
|
||||||
github.com/karrick/godirwalk v1.16.1 // indirect
|
github.com/labstack/echo/v4 v4.12.0
|
||||||
github.com/labstack/echo/v4 v4.6.1
|
github.com/likexian/whois v1.15.4
|
||||||
github.com/likexian/whois-parser-go v1.15.1 // indirect
|
github.com/likexian/whois-parser v1.24.19
|
||||||
github.com/mattn/go-colorable v0.1.11 // indirect
|
github.com/oschwald/geoip2-golang v1.11.0
|
||||||
github.com/rogpeppe/go-internal v1.8.0 // indirect
|
|
||||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
|
||||||
github.com/stretchr/testify v1.7.0 // indirect
|
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20211111213525-f221eed1c01e // indirect
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
|
||||||
golang.org/x/text v0.3.7 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/likexian/whois v1.12.4
|
|
||||||
github.com/likexian/whois-parser v1.22.0
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
|
||||||
github.com/gobuffalo/logger v1.0.6 // indirect
|
|
||||||
github.com/gobuffalo/packd v1.0.1 // indirect
|
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
github.com/labstack/gommon v0.3.1 // indirect
|
github.com/likexian/gokit v0.25.15 // indirect
|
||||||
github.com/likexian/gokit v0.25.6 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/markbates/errx v1.1.0 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/markbates/oncer v1.0.0 // indirect
|
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
|
||||||
github.com/markbates/safe v1.0.1 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
|
||||||
github.com/spf13/cobra v1.2.1 // indirect
|
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
golang.org/x/net v0.0.0-20211111160137-58aab5ef257a // indirect
|
golang.org/x/crypto v0.26.0 // indirect
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
golang.org/x/net v0.28.0 // indirect
|
||||||
golang.org/x/tools v0.1.7 // indirect
|
golang.org/x/sys v0.24.0 // indirect
|
||||||
|
golang.org/x/text v0.17.0 // indirect
|
||||||
|
golang.org/x/time v0.6.0 // indirect
|
||||||
)
|
)
|
||||||
|
803
go.sum
803
go.sum
@ -1,758 +1,61 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
|
||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
|
||||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
|
||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
|
||||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
|
||||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
|
||||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
|
||||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
|
||||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
|
||||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
|
||||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
|
||||||
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/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
|
|
||||||
github.com/gobuffalo/logger v1.0.4 h1:HFJRqL7AmL4QNvQb9Grss9sDz+3u02VBgAoR03A7q4o=
|
|
||||||
github.com/gobuffalo/logger v1.0.4/go.mod h1:/GRUdWb+gM3shxj0P5jiV6ecVS3X0aboJvl+hBu0HeE=
|
|
||||||
github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU=
|
|
||||||
github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs=
|
|
||||||
github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM=
|
|
||||||
github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI=
|
|
||||||
github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0=
|
|
||||||
github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY=
|
|
||||||
github.com/gobuffalo/packr/v2 v2.8.1 h1:tkQpju6i3EtMXJ9uoF5GT6kB+LMTimDWD8Xvbz6zDVA=
|
|
||||||
github.com/gobuffalo/packr/v2 v2.8.1/go.mod h1:c/PLlOuTU+p3SybaJATW3H6lX/iK7xEz5OeMf+NnJpg=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
||||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/likexian/gokit v0.25.15 h1:QjospM1eXhdMMHwZRpMKKAHY/Wig9wgcREmLtf9NslY=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/likexian/gokit v0.25.15/go.mod h1:S2QisdsxLEHWeD/XI0QMVeggp+jbxYqUxMvSBil7MRg=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/likexian/whois v1.15.3 h1:0emFSUSUj98Q12Wer3iM3eROPXjg+CyUBlibGPNbKHw=
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
github.com/likexian/whois v1.15.3/go.mod h1:a6sGAAKEb+O3JRBuW2x/QDM80l5hJ07p0+SjQkJ1c+0=
|
||||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/likexian/whois v1.15.4 h1:r5En62c+S9HKFgJtdh2WsdmRGTcxE4WUtGBdZkSBXmM=
|
||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/likexian/whois v1.15.4/go.mod h1:rXFTPcQdNlPQBJCQpPWTSIDGzzmgKBftmhdOOcLpwXk=
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/likexian/whois-parser v1.24.18 h1:Xolieo/uwjNwhmQN/oDDNlwFajHipdHedyPBgzG44kw=
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
github.com/likexian/whois-parser v1.24.18/go.mod h1:k5zmKRZ7xPg1TLv3BGT4g/LOPRIMhvdNMeB0F53V/jk=
|
||||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
github.com/likexian/whois-parser v1.24.19 h1:vT8lWhnV8ogkdaYLyef6IvE5VTHVCwlUDG5BUXCx06k=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/likexian/whois-parser v1.24.19/go.mod h1:rAtaofg2luol09H+ogDzGIfcG8ig1NtM5R16uQADDz4=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/oschwald/geoip2-golang v1.11.0 h1:hNENhCn1Uyzhf9PTmquXENiWS6AlxAEnBII6r8krA3w=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
|
||||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
|
||||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
|
||||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
|
||||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
|
||||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
|
||||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
|
||||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
|
||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
|
||||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
|
||||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
|
||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
github.com/karrick/godirwalk v1.15.8/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
|
||||||
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
|
|
||||||
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/labstack/echo/v4 v4.1.17 h1:PQIBaRplyRy3OjwILGkPg89JRtH2x5bssi59G2EL3fo=
|
|
||||||
github.com/labstack/echo/v4 v4.1.17/go.mod h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ=
|
|
||||||
github.com/labstack/echo/v4 v4.6.1 h1:OMVsrnNFzYlGSdaiYGHbgWQnr+JM7NG+B9suCPie14M=
|
|
||||||
github.com/labstack/echo/v4 v4.6.1/go.mod h1:RnjgMWNDB9g/HucVWhQYNQP9PvbYf6adqftqryo7s9k=
|
|
||||||
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
|
||||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
|
||||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
|
||||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
|
||||||
github.com/likexian/gokit v0.23.3/go.mod h1:/asXq96N3H5gVxyfyNuQO7HFoSorzcU+ZMEImyBGZB8=
|
|
||||||
github.com/likexian/gokit v0.25.6 h1:DZuMrmfgXErhdfI9SIS6tVMZ5QbRMP3aruHNq5lGcMI=
|
|
||||||
github.com/likexian/gokit v0.25.6/go.mod h1:q1LC+z3cBymJuE4oeiWiIPhJceUa0nptg4Id8tSzjZI=
|
|
||||||
github.com/likexian/whois v1.12.4 h1:NqUNc9LC4G5Fq62o6a3nw/HO8haJDULEudcJPyPMwXg=
|
|
||||||
github.com/likexian/whois v1.12.4/go.mod h1:SfdfmB72mSdrC/8eLjYkeaEJp9t1MPAgp0ebCzZfYXw=
|
|
||||||
github.com/likexian/whois-parser v1.22.0 h1:YXSNvDNBy+cZG+2JZWJvWbMHrDY35r6Etpu1TNDPYW0=
|
|
||||||
github.com/likexian/whois-parser v1.22.0/go.mod h1:2bJqtH4tNPanBvOp/3Kj3Sd12S9vxTbsJ0+0zjRc3ow=
|
|
||||||
github.com/likexian/whois-parser-go v1.15.1 h1:IqGTdKYHxi+c7zNR6GR4s1HUKD+C/pFDT6yeyEfaAUQ=
|
|
||||||
github.com/likexian/whois-parser-go v1.15.1/go.mod h1:zbLK4/FJW/zO2K5wZmHe+Fu6q5JygxJg+cQkYPA3nNI=
|
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
|
||||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
|
||||||
github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
|
|
||||||
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
|
|
||||||
github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
|
|
||||||
github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
|
|
||||||
github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
|
|
||||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
|
||||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
|
||||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
|
||||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
|
||||||
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
|
|
||||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
|
||||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
|
||||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
|
||||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
|
||||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
|
||||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
|
||||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
|
||||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
|
||||||
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
|
||||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
|
||||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
|
||||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
|
||||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
|
||||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
|
||||||
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
|
||||||
github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
|
|
||||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
|
||||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
|
||||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
|
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
|
||||||
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 h1:Z04ewVs7JhXaYkmDhBERPi41gnltfQpMWDnTnQbaCqk=
|
|
||||||
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20211111160137-58aab5ef257a h1:c83jeVQW0KGKNaKBRfelNYNHaev+qawl9yaA825s8XE=
|
|
||||||
golang.org/x/net v0.0.0-20211111160137-58aab5ef257a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211111213525-f221eed1c01e h1:zeJt6jBtVDK23XK9QXcmG0FvO0elikp0dYZQZOeL1y0=
|
|
||||||
golang.org/x/sys v0.0.0-20211111213525-f221eed1c01e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0/DyDUBKSXK7CMFkVcV0=
|
|
||||||
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|
||||||
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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
|
||||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
|
||||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
|
||||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
|
||||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
|
||||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
|
||||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
|
||||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
|
||||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
|
||||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
|
||||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|
||||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|
||||||
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=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
||||||
|
10
packr.go
10
packr.go
@ -1,10 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gobuffalo/packr/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
packr.New("static", "./static")
|
|
||||||
packr.New("templates", "./templates")
|
|
||||||
}
|
|
5
scripts/build_amd64.sh
Executable file
5
scripts/build_amd64.sh
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export GOARCH=amd64
|
||||||
|
go generate cmd/dip/dip.go
|
||||||
|
go build -mod=vendor cmd/dip/dip.go
|
7
scripts/kube_deploy.sh
Executable file
7
scripts/kube_deploy.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./scripts/build_amd64.sh
|
||||||
|
docker build -t dip:latest .
|
||||||
|
docker tag dip:latest registry.paulbsd.com/images/dip:latest
|
||||||
|
docker push registry.paulbsd.com/images/dip:latest
|
||||||
|
kubectl rollout restart deployment dip
|
103
src/dip/main.go
103
src/dip/main.go
@ -1,26 +1,75 @@
|
|||||||
package dip
|
package dip
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.paulbsd.com/paulbsd/dip/src/geoip"
|
||||||
|
"github.com/bradfitz/gomemcache/memcache"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/likexian/whois"
|
"github.com/likexian/whois"
|
||||||
whoisparser "github.com/likexian/whois-parser"
|
whoisparser "github.com/likexian/whois-parser"
|
||||||
|
"github.com/oschwald/geoip2-golang"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetIPInfo returns IP address mail informations
|
const defaultLanguage = "en"
|
||||||
func (ip *IP) GetIPInfo(c echo.Context) (err error) {
|
const cacheMaxTime = 604800
|
||||||
if c.QueryParam("ip") != "" {
|
|
||||||
ip.IP = c.QueryParam("ip")
|
var citydb *geoip2.Reader
|
||||||
} else {
|
var asndb *geoip2.Reader
|
||||||
|
var MemcacheConn string = ""
|
||||||
|
|
||||||
|
func Init() (err error) {
|
||||||
|
citydb, asndb, err = geoip.InitGeoIP()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
log.Println("failed to get geoip database")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIPInfo returns IP address informations
|
||||||
|
func (ip *IP) GetIPInfo(c echo.Context) (cached bool, err error) {
|
||||||
|
var mcenabled bool
|
||||||
|
var mc *memcache.Client
|
||||||
|
if MemcacheConn != "" {
|
||||||
|
mc = memcache.New(MemcacheConn)
|
||||||
|
mc.Timeout, err = time.ParseDuration("1s")
|
||||||
|
mcenabled = true
|
||||||
|
defer mc.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
ip.IP = c.Param("ip")
|
||||||
|
if c.Param("ip") == "" {
|
||||||
ip.IP = c.RealIP()
|
ip.IP = c.RealIP()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mcenabled {
|
||||||
|
item, err := mc.Get(ip.IP)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error from cache", ip.IP, err)
|
||||||
|
cached = false
|
||||||
|
} else {
|
||||||
|
cachedip := IP{}
|
||||||
|
err = json.Unmarshal(item.Value, &cachedip)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
*ip = cachedip
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = ip.CheckIPAddress()
|
err = ip.CheckIPAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
ip.IP = c.RealIP()
|
||||||
|
err = ip.CheckIPAddress()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ip.GetHostname()
|
err = ip.GetHostname()
|
||||||
@ -28,6 +77,21 @@ func (ip *IP) GetIPInfo(c echo.Context) (err error) {
|
|||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = ip.GetGeoIP()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mcenabled && !cached {
|
||||||
|
go func() {
|
||||||
|
dt, err := json.Marshal(*ip)
|
||||||
|
err = mc.Set(&memcache.Item{Key: ip.IP, Value: dt, Expiration: cacheMaxTime})
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err, "test")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
/*err = ip.GetWhois()
|
/*err = ip.GetWhois()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
@ -66,10 +130,37 @@ func (ip *IP) GetWhois() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ip *IP) GetGeoIP() (err error) {
|
||||||
|
i := net.ParseIP(ip.IP)
|
||||||
|
city, err := citydb.City(i)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
asn, err := asndb.ASN(i)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ip.City = city.City.Names[defaultLanguage]
|
||||||
|
ip.Country = city.Country.Names[defaultLanguage]
|
||||||
|
ip.As = AS{
|
||||||
|
Number: int(asn.AutonomousSystemNumber),
|
||||||
|
Org: asn.AutonomousSystemOrganization,
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// IP defines ip main struct
|
// IP defines ip main struct
|
||||||
type IP struct {
|
type IP struct {
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
Hostname string `json:"hostname"`
|
Hostname string `json:"hostname"`
|
||||||
City string `json:"city"`
|
City string `json:"city"`
|
||||||
Country string `json:"country"`
|
Country string `json:"country"`
|
||||||
|
As AS `json:"as"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AS struct {
|
||||||
|
Number int `json:"number"`
|
||||||
|
Org string `json:"org"`
|
||||||
}
|
}
|
||||||
|
97
src/geoip/main.go
Normal file
97
src/geoip/main.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package geoip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
geoip2 "github.com/oschwald/geoip2-golang"
|
||||||
|
)
|
||||||
|
|
||||||
|
const RootURL = "https://git.paulbsd.com/paulbsd/GeoLite.mmdb/releases/download/%s/%s"
|
||||||
|
const APIUrl = "https://git.paulbsd.com/api/v1/repos/paulbsd/GeoLite.mmdb/releases"
|
||||||
|
|
||||||
|
const CityFilename = "GeoLite2-City.mmdb"
|
||||||
|
const ASNFilename = "GeoLite2-ASN.mmdb"
|
||||||
|
|
||||||
|
func GetLastVersion() (result string, err error) {
|
||||||
|
var apiresults []struct {
|
||||||
|
Tag string `json:"tag_name"`
|
||||||
|
}
|
||||||
|
res, err := http.Get(APIUrl)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
body, err := io.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(body, &apiresults)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var tags []string
|
||||||
|
for _, t := range apiresults {
|
||||||
|
tags = append(tags, t.Tag)
|
||||||
|
}
|
||||||
|
sort.Sort(sort.Reverse(sort.StringSlice(tags)))
|
||||||
|
|
||||||
|
result = tags[0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitGeoIP() (citydb *geoip2.Reader, asndb *geoip2.Reader, err error) {
|
||||||
|
version, err := GetLastVersion()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var dbs map[string]string = map[string]string{
|
||||||
|
"city": fmt.Sprintf(RootURL, version, CityFilename),
|
||||||
|
"asn": fmt.Sprintf(RootURL, version, ASNFilename)}
|
||||||
|
log.Printf("Fetching GeoLite.mmdb version %s\n", version)
|
||||||
|
citydb, err = FetchDB(dbs["city"], version)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asndb, err = FetchDB(dbs["asn"], version)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func FetchDB(db string, version string) (reader *geoip2.Reader, err error) {
|
||||||
|
if _, err := os.Stat("geoip"); err != nil {
|
||||||
|
os.MkdirAll("geoip", 0777)
|
||||||
|
}
|
||||||
|
|
||||||
|
splited := strings.Split(db, "/")
|
||||||
|
filename := strings.Replace(splited[len(splited)-1], ".", fmt.Sprintf("-%s.", version), 1)
|
||||||
|
dbpath := fmt.Sprintf("%s/%s", "geoip", filename)
|
||||||
|
|
||||||
|
if _, err := os.Stat(dbpath); err != nil {
|
||||||
|
resp, err := http.Get(db)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
file, err := os.Create(dbpath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
_, err = io.Copy(file, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return geoip2.Open(dbpath)
|
||||||
|
}
|
@ -1,24 +1,31 @@
|
|||||||
package static
|
package static
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"embed"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetStatic returns static file content
|
// GetStatic returns static file content
|
||||||
func GetStatic(box *packr.Box, c echo.Context) (err error) {
|
func GetStatic(staticfiles *embed.FS, c echo.Context) (err error) {
|
||||||
name := c.Param("*")
|
name := c.Param("*")
|
||||||
cnt, _ := box.FindString(name)
|
content, err := staticfiles.ReadFile(name)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasSuffix(name, ".js") {
|
if strings.HasSuffix(name, ".js") {
|
||||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJavaScript)
|
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJavaScript)
|
||||||
} else if strings.HasSuffix(name, ".css") {
|
} else if strings.HasSuffix(name, ".css") {
|
||||||
c.Response().Header().Set(echo.HeaderContentType, "text/css")
|
c.Response().Header().Set(echo.HeaderContentType, "text/css")
|
||||||
|
} else if strings.HasSuffix(name, ".ico") {
|
||||||
|
c.Response().Header().Set(echo.HeaderContentType, "image/x-icon")
|
||||||
}
|
}
|
||||||
return c.String(http.StatusOK, cnt)
|
c.Response().Header().Add(echo.HeaderCacheControl, "max-age=172800")
|
||||||
|
return c.String(http.StatusOK, string(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static defines static file
|
// Static defines static file
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package templates
|
package templates
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"embed"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,16 +15,21 @@ func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Con
|
|||||||
if strings.HasSuffix(name, ".html") {
|
if strings.HasSuffix(name, ".html") {
|
||||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8)
|
c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8)
|
||||||
}
|
}
|
||||||
|
c.Response().Header().Add(echo.HeaderCacheControl, "max-age=172800")
|
||||||
return t.templates.ExecuteTemplate(w, name, data)
|
return t.templates.ExecuteTemplate(w, name, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildTemplates converts packr packages to html/template
|
// BuildTemplates converts embedded files to html/template
|
||||||
func BuildTemplates(box *packr.Box) (builttemplates *Template, err error) {
|
func BuildTemplates(templatefiles *embed.FS) (builttemplates *Template, err error) {
|
||||||
tmpl := template.New("templates")
|
tmpl := template.New("templates")
|
||||||
|
|
||||||
for _, filename := range box.List() {
|
folder, err := templatefiles.ReadDir(".")
|
||||||
tmplContent, _ := box.FindString(filename)
|
for _, filename := range folder {
|
||||||
tmpl.New(filename).Parse(tmplContent)
|
content, err := templatefiles.ReadFile(filename.Name())
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
tmpl.New(filename.Name()).Parse(string(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
builttemplates = &Template{
|
builttemplates = &Template{
|
||||||
@ -33,29 +39,6 @@ func BuildTemplates(box *packr.Box) (builttemplates *Template, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// BuildTemplatesDir converts packr packages to html/template
|
|
||||||
func BuildTemplatesDir(dir string) (builttemplates *Template, err error) {
|
|
||||||
tmpl := template.New("templates")
|
|
||||||
|
|
||||||
err = pkger.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
freader, _ := pkger.Open(path)
|
|
||||||
tmplContent, err := ioutil.ReadAll(freader)
|
|
||||||
tmpl.New(info.Name()).Parse(string(tmplContent))
|
|
||||||
fmt.Println(info.Name(), tmplContent)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
|
|
||||||
builttemplates = &Template{
|
|
||||||
templates: tmpl,
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Template is a template struct
|
// Template is a template struct
|
||||||
type Template struct {
|
type Template struct {
|
||||||
templates *template.Template
|
templates *template.Template
|
||||||
|
@ -1,49 +1,65 @@
|
|||||||
package ws
|
package ws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/dip/src/config"
|
"git.paulbsd.com/paulbsd/dip/src/config"
|
||||||
"git.paulbsd.com/paulbsd/dip/src/static"
|
"git.paulbsd.com/paulbsd/dip/src/static"
|
||||||
"git.paulbsd.com/paulbsd/dip/src/templates"
|
"git.paulbsd.com/paulbsd/dip/src/templates"
|
||||||
"github.com/gobuffalo/packr/v2"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitServer instanciate the main echo instance
|
// InitServer instanciate the main echo instance
|
||||||
func (ws *WS) InitServer() (err error) {
|
func (ws *WS) InitServer(templatefiles *embed.FS, staticfiles *embed.FS) (err error) {
|
||||||
ws.e = echo.New()
|
ws.e = echo.New()
|
||||||
|
ws.e.Pre(middleware.RemoveTrailingSlash())
|
||||||
ws.e.HideBanner = true
|
ws.e.HideBanner = true
|
||||||
ws.e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
|
ws.e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
|
||||||
Level: 5,
|
Level: 5,
|
||||||
}))
|
}))
|
||||||
ws.e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
|
ws.e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
|
||||||
AllowOrigins: []string{"*"},
|
AllowOrigins: []string{"*"},
|
||||||
AllowMethods: []string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete},
|
AllowMethods: []string{http.MethodGet},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
ws.templatesbox = packr.New("templates", "../../templates")
|
builtTemplates, _ := templates.BuildTemplates(templatefiles)
|
||||||
ws.staticbox = packr.New("static", "../../static")
|
|
||||||
|
|
||||||
builtTemplates, _ := templates.BuildTemplates(ws.templatesbox)
|
|
||||||
ws.e.Renderer = builtTemplates
|
ws.e.Renderer = builtTemplates
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunServer runs the webserver
|
// RunServer runs the webserver
|
||||||
func (ws *WS) RunServer(config config.Config) (err error) {
|
func (ws *WS) RunServer(config config.Config, templatefiles *embed.FS, staticfiles *embed.FS) (err error) {
|
||||||
ws.InitServer()
|
ws.InitServer(templatefiles, staticfiles)
|
||||||
|
|
||||||
ws.e.GET("/", ws.Page.Index)
|
ws.e.GET("/", func(c echo.Context) (err error) {
|
||||||
ws.e.GET("/static/*", func(c echo.Context) error {
|
ws.Page.Process(c, "")
|
||||||
return static.GetStatic(ws.staticbox, c)
|
return
|
||||||
|
})
|
||||||
|
ws.e.GET("/:ip", func(c echo.Context) (err error) {
|
||||||
|
ws.Page.Process(c, "")
|
||||||
|
return
|
||||||
|
})
|
||||||
|
ws.e.GET("/json", func(c echo.Context) (err error) {
|
||||||
|
ws.Page.Process(c, "json")
|
||||||
|
return
|
||||||
|
})
|
||||||
|
ws.e.GET("/json/:ip", func(c echo.Context) (err error) {
|
||||||
|
ws.Page.Process(c, "json")
|
||||||
|
return
|
||||||
|
})
|
||||||
|
ws.e.GET("/static/*", func(c echo.Context) (err error) {
|
||||||
|
return static.GetStatic(staticfiles, c)
|
||||||
|
})
|
||||||
|
ws.e.GET("/health", func(c echo.Context) (err error) {
|
||||||
|
return c.String(http.StatusOK, "OK")
|
||||||
|
})
|
||||||
|
ws.e.HEAD("/health", func(c echo.Context) (err error) {
|
||||||
|
return c.String(http.StatusOK, "OK")
|
||||||
})
|
})
|
||||||
ws.e.GET("/json", ws.Page.JSON)
|
|
||||||
ws.e.OPTIONS("/", echo.MethodNotAllowedHandler)
|
|
||||||
|
|
||||||
ws.e.Logger.Fatal(ws.e.Start(fmt.Sprintf("%s:%s", config.Host, config.Port)))
|
ws.e.Logger.Fatal(ws.e.Start(fmt.Sprintf("%s:%s", config.Host, config.Port)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -51,6 +67,4 @@ func (ws *WS) RunServer(config config.Config) (err error) {
|
|||||||
type WS struct {
|
type WS struct {
|
||||||
Page Page
|
Page Page
|
||||||
e *echo.Echo
|
e *echo.Echo
|
||||||
templatesbox *packr.Box
|
|
||||||
staticbox *packr.Box
|
|
||||||
}
|
}
|
||||||
|
@ -2,33 +2,36 @@ package ws
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/dip/src/dip"
|
"git.paulbsd.com/paulbsd/dip/src/dip"
|
||||||
"git.paulbsd.com/paulbsd/dip/src/templates"
|
"git.paulbsd.com/paulbsd/dip/src/templates"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Page) GetContent(c echo.Context) (err error) {
|
func (p *Page) GetContent(c echo.Context) (cached bool, err error) {
|
||||||
var ip dip.IP
|
var ip dip.IP
|
||||||
err = ip.GetIPInfo(c)
|
cached, err = ip.GetIPInfo(c)
|
||||||
p.IP = &ip
|
p.IP = &ip
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index returns main webpage
|
// Process returns main webpage or a JSON
|
||||||
func (p *Page) Index(c echo.Context) (err error) {
|
func (p *Page) Process(c echo.Context, querytype string) (err error) {
|
||||||
p.GetContent(c)
|
cached, err := p.GetContent(c)
|
||||||
if strings.Contains(c.Request().Header.Get(echo.HeaderAccept), echo.MIMETextHTML) {
|
c.Response().Header().Set("X-Cached", "false")
|
||||||
return c.Render(http.StatusOK, "index.html", p)
|
if cached {
|
||||||
|
c.Response().Header().Set("X-Cached", "true")
|
||||||
}
|
}
|
||||||
|
if querytype == "json" {
|
||||||
return c.JSONPretty(http.StatusOK, p.IP, " ")
|
return c.JSONPretty(http.StatusOK, p.IP, " ")
|
||||||
}
|
}
|
||||||
|
if accept, ok := c.Request().Header["Accept"]; ok {
|
||||||
func (p *Page) JSON(c echo.Context) (err error) {
|
if accept[0] == "*/*" {
|
||||||
p.GetContent(c)
|
|
||||||
return c.JSONPretty(http.StatusOK, p.IP, " ")
|
return c.JSONPretty(http.StatusOK, p.IP, " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c.Render(http.StatusOK, "index.html", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Page defines Web page
|
// Page defines Web page
|
||||||
|
BIN
static/images/favicon.ico
Normal file
BIN
static/images/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
3
static/js/axios.min.js
vendored
3
static/js/axios.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,24 +1,39 @@
|
|||||||
var vue = new Vue({
|
const dip_ip = document.getElementById("dip_ip");
|
||||||
el: '#dip_main_div',
|
const dip_hostname = document.getElementById("dip_hostname");
|
||||||
|
const dip_city = document.getElementById("dip_city");
|
||||||
|
const dip_country = document.getElementById("dip_country");
|
||||||
|
const dip_as_number = document.getElementById("dip_as_number");
|
||||||
|
const dip_as_org = document.getElementById("dip_as_org");
|
||||||
|
|
||||||
data () {
|
function setData(res) {
|
||||||
return {
|
dip_ip.innerHTML = res["ip"];
|
||||||
title: "Public IP Address service",
|
dip_hostname.innerHTML = res["hostname"];
|
||||||
dip: {"ip": null,
|
dip_city.innerHTML = res["city"];
|
||||||
"hostname": null,
|
dip_country.innerHTML = res["country"];
|
||||||
"city": null,
|
dip_as_number.innerHTML = res["as"]["number"];
|
||||||
"country": null},
|
dip_as_org.innerHTML = res["as"]["org"];
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateIP() {
|
||||||
|
let ip = "";
|
||||||
|
|
||||||
|
if (window.location.pathname.length > 4) {
|
||||||
|
ip = window.location.pathname.split("/")[1];
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
mounted () {
|
const localdata = localStorage.getItem("data");
|
||||||
axios.get("https://ip.paulbsd.com")
|
if (localdata) {
|
||||||
.then(response => {
|
const data = JSON.parse(localdata);
|
||||||
this.dip = response.data
|
setData(data);
|
||||||
})
|
}
|
||||||
.catch(err => {
|
|
||||||
// Manage the state of the application if the request
|
fetch(`/json/${ip}`).then((response) => {
|
||||||
// has failed
|
response.json().then((data) => {
|
||||||
|
setData(data);
|
||||||
|
localStorage.setItem("data",JSON.stringify(data));
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
updateIP()
|
||||||
|
setInterval(updateIP,1000);
|
||||||
|
6
static/js/vue.min.js
vendored
6
static/js/vue.min.js
vendored
File diff suppressed because one or more lines are too long
12
static/main.go
Normal file
12
static/main.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package staticfiles
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
)
|
||||||
|
|
||||||
|
// include of embedded files
|
||||||
|
//
|
||||||
|
//go:embed css/*
|
||||||
|
//go:embed js/*
|
||||||
|
//go:embed images/*
|
||||||
|
var Static embed.FS
|
@ -4,12 +4,11 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<link rel="icon" href="static/images/favicon.ico"/>
|
||||||
<link rel="stylesheet" href="static/css/main.css" />
|
<link rel="stylesheet" href="static/css/main.css" />
|
||||||
<link rel="stylesheet" href="static/css/uikit.min.css" />
|
<link rel="stylesheet" href="static/css/uikit.min.css" />
|
||||||
<link rel="stylesheet" href="static/css/font-awesome.min.css" />
|
<link rel="stylesheet" href="static/css/font-awesome.min.css" />
|
||||||
|
|
||||||
<script src="static/js/uikit.min.js"></script>
|
<script src="static/js/uikit.min.js"></script>
|
||||||
<script src="static/js/uikit-icons.min.js"></script>
|
<script src="static/js/uikit-icons.min.js"></script>
|
||||||
<script src="static/js/axios.min.js"></script>
|
|
||||||
<script src="static/js/vue.min.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
|
@ -1,27 +1,37 @@
|
|||||||
<html>
|
<html>
|
||||||
{{ template "head.html" .}}
|
{{ template "head.html" .}}
|
||||||
<body>
|
|
||||||
|
<body>
|
||||||
<div id="dip_main_div">
|
<div id="dip_main_div">
|
||||||
<h1 class="dip_h1">{{ .Title }}</h1>
|
<h1 class="dip_h1">{{ .Title }}</h1>
|
||||||
<table class="uk-table uk-table-striped uk-table-hover">
|
<table class="uk-table uk-table-striped uk-table-hover">
|
||||||
<caption>IP informations</caption>
|
<caption>IP informations</caption>
|
||||||
<tr>
|
<tr>
|
||||||
<td>IP</td>
|
<td>IP</td>
|
||||||
<td>{{ "{{" }} dip.ip {{ "}}" }}</td>
|
<td id="dip_ip"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Reverse DNS</td>
|
<td>Reverse DNS</td>
|
||||||
<td>{{ "{{" }} dip.hostname {{ "}}" }}</td>
|
<td id="dip_hostname"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>City</td>
|
<td>City</td>
|
||||||
<td>{{ "{{" }} dip.city {{ "}}" }}</td>
|
<td id="dip_city"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Country</td>
|
<td>Country</td>
|
||||||
<td>{{ "{{" }} dip.country {{ "}}" }}</td>
|
<td id="dip_country"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>AS number</td>
|
||||||
|
<td id="dip_as_number"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>AS name</td>
|
||||||
|
<td id="dip_as_org"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</div>
|
</div>
|
||||||
{{ template "footer_js.html" .}}
|
{{ template "footer_js.html" .}}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
10
templates/main.go
Normal file
10
templates/main.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package templatefiles
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
)
|
||||||
|
|
||||||
|
// include of embedded files
|
||||||
|
//
|
||||||
|
//go:embed *.html
|
||||||
|
var Templates embed.FS
|
9
vendor/github.com/bradfitz/gomemcache/AUTHORS
generated
vendored
Normal file
9
vendor/github.com/bradfitz/gomemcache/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
The following people & companies are the copyright holders of this
|
||||||
|
package. Feel free to add to this list if you or your employer cares,
|
||||||
|
otherwise it's implicit from the git log.
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
|
||||||
|
- Brad Fitzpatrick
|
||||||
|
- Google, Inc. (from Googlers contributing)
|
||||||
|
- Anybody else in the git log.
|
202
vendor/github.com/bradfitz/gomemcache/LICENSE
generated
vendored
Normal file
202
vendor/github.com/bradfitz/gomemcache/LICENSE
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
776
vendor/github.com/bradfitz/gomemcache/memcache/memcache.go
generated
vendored
Normal file
776
vendor/github.com/bradfitz/gomemcache/memcache/memcache.go
generated
vendored
Normal file
@ -0,0 +1,776 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2011 The gomemcache AUTHORS
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package memcache provides a client for the memcached cache server.
|
||||||
|
package memcache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Similar to:
|
||||||
|
// https://godoc.org/google.golang.org/appengine/memcache
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrCacheMiss means that a Get failed because the item wasn't present.
|
||||||
|
ErrCacheMiss = errors.New("memcache: cache miss")
|
||||||
|
|
||||||
|
// ErrCASConflict means that a CompareAndSwap call failed due to the
|
||||||
|
// cached value being modified between the Get and the CompareAndSwap.
|
||||||
|
// If the cached value was simply evicted rather than replaced,
|
||||||
|
// ErrNotStored will be returned instead.
|
||||||
|
ErrCASConflict = errors.New("memcache: compare-and-swap conflict")
|
||||||
|
|
||||||
|
// ErrNotStored means that a conditional write operation (i.e. Add or
|
||||||
|
// CompareAndSwap) failed because the condition was not satisfied.
|
||||||
|
ErrNotStored = errors.New("memcache: item not stored")
|
||||||
|
|
||||||
|
// ErrServer means that a server error occurred.
|
||||||
|
ErrServerError = errors.New("memcache: server error")
|
||||||
|
|
||||||
|
// ErrNoStats means that no statistics were available.
|
||||||
|
ErrNoStats = errors.New("memcache: no statistics available")
|
||||||
|
|
||||||
|
// ErrMalformedKey is returned when an invalid key is used.
|
||||||
|
// Keys must be at maximum 250 bytes long and not
|
||||||
|
// contain whitespace or control characters.
|
||||||
|
ErrMalformedKey = errors.New("malformed: key is too long or contains invalid characters")
|
||||||
|
|
||||||
|
// ErrNoServers is returned when no servers are configured or available.
|
||||||
|
ErrNoServers = errors.New("memcache: no servers configured or available")
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultTimeout is the default socket read/write timeout.
|
||||||
|
DefaultTimeout = 500 * time.Millisecond
|
||||||
|
|
||||||
|
// DefaultMaxIdleConns is the default maximum number of idle connections
|
||||||
|
// kept for any single address.
|
||||||
|
DefaultMaxIdleConns = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
const buffered = 8 // arbitrary buffered channel size, for readability
|
||||||
|
|
||||||
|
// resumableError returns true if err is only a protocol-level cache error.
|
||||||
|
// This is used to determine whether or not a server connection should
|
||||||
|
// be re-used or not. If an error occurs, by default we don't reuse the
|
||||||
|
// connection, unless it was just a cache error.
|
||||||
|
func resumableError(err error) bool {
|
||||||
|
switch err {
|
||||||
|
case ErrCacheMiss, ErrCASConflict, ErrNotStored, ErrMalformedKey:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func legalKey(key string) bool {
|
||||||
|
if len(key) > 250 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < len(key); i++ {
|
||||||
|
if key[i] <= ' ' || key[i] == 0x7f {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
crlf = []byte("\r\n")
|
||||||
|
space = []byte(" ")
|
||||||
|
resultOK = []byte("OK\r\n")
|
||||||
|
resultStored = []byte("STORED\r\n")
|
||||||
|
resultNotStored = []byte("NOT_STORED\r\n")
|
||||||
|
resultExists = []byte("EXISTS\r\n")
|
||||||
|
resultNotFound = []byte("NOT_FOUND\r\n")
|
||||||
|
resultDeleted = []byte("DELETED\r\n")
|
||||||
|
resultEnd = []byte("END\r\n")
|
||||||
|
resultOk = []byte("OK\r\n")
|
||||||
|
resultTouched = []byte("TOUCHED\r\n")
|
||||||
|
|
||||||
|
resultClientErrorPrefix = []byte("CLIENT_ERROR ")
|
||||||
|
versionPrefix = []byte("VERSION")
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a memcache client using the provided server(s)
|
||||||
|
// with equal weight. If a server is listed multiple times,
|
||||||
|
// it gets a proportional amount of weight.
|
||||||
|
func New(server ...string) *Client {
|
||||||
|
ss := new(ServerList)
|
||||||
|
ss.SetServers(server...)
|
||||||
|
return NewFromSelector(ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFromSelector returns a new Client using the provided ServerSelector.
|
||||||
|
func NewFromSelector(ss ServerSelector) *Client {
|
||||||
|
return &Client{selector: ss}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client is a memcache client.
|
||||||
|
// It is safe for unlocked use by multiple concurrent goroutines.
|
||||||
|
type Client struct {
|
||||||
|
// DialContext connects to the address on the named network using the
|
||||||
|
// provided context.
|
||||||
|
//
|
||||||
|
// To connect to servers using TLS (memcached running with "--enable-ssl"),
|
||||||
|
// use a DialContext func that uses tls.Dialer.DialContext. See this
|
||||||
|
// package's tests as an example.
|
||||||
|
DialContext func(ctx context.Context, network, address string) (net.Conn, error)
|
||||||
|
|
||||||
|
// Timeout specifies the socket read/write timeout.
|
||||||
|
// If zero, DefaultTimeout is used.
|
||||||
|
Timeout time.Duration
|
||||||
|
|
||||||
|
// MaxIdleConns specifies the maximum number of idle connections that will
|
||||||
|
// be maintained per address. If less than one, DefaultMaxIdleConns will be
|
||||||
|
// used.
|
||||||
|
//
|
||||||
|
// Consider your expected traffic rates and latency carefully. This should
|
||||||
|
// be set to a number higher than your peak parallel requests.
|
||||||
|
MaxIdleConns int
|
||||||
|
|
||||||
|
selector ServerSelector
|
||||||
|
|
||||||
|
lk sync.Mutex
|
||||||
|
freeconn map[string][]*conn
|
||||||
|
}
|
||||||
|
|
||||||
|
// Item is an item to be got or stored in a memcached server.
|
||||||
|
type Item struct {
|
||||||
|
// Key is the Item's key (250 bytes maximum).
|
||||||
|
Key string
|
||||||
|
|
||||||
|
// Value is the Item's value.
|
||||||
|
Value []byte
|
||||||
|
|
||||||
|
// Flags are server-opaque flags whose semantics are entirely
|
||||||
|
// up to the app.
|
||||||
|
Flags uint32
|
||||||
|
|
||||||
|
// Expiration is the cache expiration time, in seconds: either a relative
|
||||||
|
// time from now (up to 1 month), or an absolute Unix epoch time.
|
||||||
|
// Zero means the Item has no expiration time.
|
||||||
|
Expiration int32
|
||||||
|
|
||||||
|
// CasID is the compare and swap ID.
|
||||||
|
//
|
||||||
|
// It's populated by get requests and then the same value is
|
||||||
|
// required for a CompareAndSwap request to succeed.
|
||||||
|
CasID uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// conn is a connection to a server.
|
||||||
|
type conn struct {
|
||||||
|
nc net.Conn
|
||||||
|
rw *bufio.ReadWriter
|
||||||
|
addr net.Addr
|
||||||
|
c *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// release returns this connection back to the client's free pool
|
||||||
|
func (cn *conn) release() {
|
||||||
|
cn.c.putFreeConn(cn.addr, cn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cn *conn) extendDeadline() {
|
||||||
|
cn.nc.SetDeadline(time.Now().Add(cn.c.netTimeout()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// condRelease releases this connection if the error pointed to by err
|
||||||
|
// is nil (not an error) or is only a protocol level error (e.g. a
|
||||||
|
// cache miss). The purpose is to not recycle TCP connections that
|
||||||
|
// are bad.
|
||||||
|
func (cn *conn) condRelease(err *error) {
|
||||||
|
if *err == nil || resumableError(*err) {
|
||||||
|
cn.release()
|
||||||
|
} else {
|
||||||
|
cn.nc.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) putFreeConn(addr net.Addr, cn *conn) {
|
||||||
|
c.lk.Lock()
|
||||||
|
defer c.lk.Unlock()
|
||||||
|
if c.freeconn == nil {
|
||||||
|
c.freeconn = make(map[string][]*conn)
|
||||||
|
}
|
||||||
|
freelist := c.freeconn[addr.String()]
|
||||||
|
if len(freelist) >= c.maxIdleConns() {
|
||||||
|
cn.nc.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.freeconn[addr.String()] = append(freelist, cn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getFreeConn(addr net.Addr) (cn *conn, ok bool) {
|
||||||
|
c.lk.Lock()
|
||||||
|
defer c.lk.Unlock()
|
||||||
|
if c.freeconn == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
freelist, ok := c.freeconn[addr.String()]
|
||||||
|
if !ok || len(freelist) == 0 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
cn = freelist[len(freelist)-1]
|
||||||
|
c.freeconn[addr.String()] = freelist[:len(freelist)-1]
|
||||||
|
return cn, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) netTimeout() time.Duration {
|
||||||
|
if c.Timeout != 0 {
|
||||||
|
return c.Timeout
|
||||||
|
}
|
||||||
|
return DefaultTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) maxIdleConns() int {
|
||||||
|
if c.MaxIdleConns > 0 {
|
||||||
|
return c.MaxIdleConns
|
||||||
|
}
|
||||||
|
return DefaultMaxIdleConns
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConnectTimeoutError is the error type used when it takes
|
||||||
|
// too long to connect to the desired host. This level of
|
||||||
|
// detail can generally be ignored.
|
||||||
|
type ConnectTimeoutError struct {
|
||||||
|
Addr net.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cte *ConnectTimeoutError) Error() string {
|
||||||
|
return "memcache: connect timeout to " + cte.Addr.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) dial(addr net.Addr) (net.Conn, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), c.netTimeout())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
dialerContext := c.DialContext
|
||||||
|
if dialerContext == nil {
|
||||||
|
dialer := net.Dialer{
|
||||||
|
Timeout: c.netTimeout(),
|
||||||
|
}
|
||||||
|
dialerContext = dialer.DialContext
|
||||||
|
}
|
||||||
|
|
||||||
|
nc, err := dialerContext(ctx, addr.Network(), addr.String())
|
||||||
|
if err == nil {
|
||||||
|
return nc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if ne, ok := err.(net.Error); ok && ne.Timeout() {
|
||||||
|
return nil, &ConnectTimeoutError{addr}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getConn(addr net.Addr) (*conn, error) {
|
||||||
|
cn, ok := c.getFreeConn(addr)
|
||||||
|
if ok {
|
||||||
|
cn.extendDeadline()
|
||||||
|
return cn, nil
|
||||||
|
}
|
||||||
|
nc, err := c.dial(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cn = &conn{
|
||||||
|
nc: nc,
|
||||||
|
addr: addr,
|
||||||
|
rw: bufio.NewReadWriter(bufio.NewReader(nc), bufio.NewWriter(nc)),
|
||||||
|
c: c,
|
||||||
|
}
|
||||||
|
cn.extendDeadline()
|
||||||
|
return cn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) onItem(item *Item, fn func(*Client, *bufio.ReadWriter, *Item) error) error {
|
||||||
|
addr, err := c.selector.PickServer(item.Key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cn, err := c.getConn(addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cn.condRelease(&err)
|
||||||
|
if err = fn(c, cn.rw, item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) FlushAll() error {
|
||||||
|
return c.selector.Each(c.flushAllFromAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the item for the given key. ErrCacheMiss is returned for a
|
||||||
|
// memcache cache miss. The key must be at most 250 bytes in length.
|
||||||
|
func (c *Client) Get(key string) (item *Item, err error) {
|
||||||
|
err = c.withKeyAddr(key, func(addr net.Addr) error {
|
||||||
|
return c.getFromAddr(addr, []string{key}, func(it *Item) { item = it })
|
||||||
|
})
|
||||||
|
if err == nil && item == nil {
|
||||||
|
err = ErrCacheMiss
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Touch updates the expiry for the given key. The seconds parameter is either
|
||||||
|
// a Unix timestamp or, if seconds is less than 1 month, the number of seconds
|
||||||
|
// into the future at which time the item will expire. Zero means the item has
|
||||||
|
// no expiration time. ErrCacheMiss is returned if the key is not in the cache.
|
||||||
|
// The key must be at most 250 bytes in length.
|
||||||
|
func (c *Client) Touch(key string, seconds int32) (err error) {
|
||||||
|
return c.withKeyAddr(key, func(addr net.Addr) error {
|
||||||
|
return c.touchFromAddr(addr, []string{key}, seconds)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) withKeyAddr(key string, fn func(net.Addr) error) (err error) {
|
||||||
|
if !legalKey(key) {
|
||||||
|
return ErrMalformedKey
|
||||||
|
}
|
||||||
|
addr, err := c.selector.PickServer(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fn(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) withAddrRw(addr net.Addr, fn func(*bufio.ReadWriter) error) (err error) {
|
||||||
|
cn, err := c.getConn(addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cn.condRelease(&err)
|
||||||
|
return fn(cn.rw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) withKeyRw(key string, fn func(*bufio.ReadWriter) error) error {
|
||||||
|
return c.withKeyAddr(key, func(addr net.Addr) error {
|
||||||
|
return c.withAddrRw(addr, fn)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getFromAddr(addr net.Addr, keys []string, cb func(*Item)) error {
|
||||||
|
return c.withAddrRw(addr, func(rw *bufio.ReadWriter) error {
|
||||||
|
if _, err := fmt.Fprintf(rw, "gets %s\r\n", strings.Join(keys, " ")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := rw.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := parseGetResponse(rw.Reader, cb); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// flushAllFromAddr send the flush_all command to the given addr
|
||||||
|
func (c *Client) flushAllFromAddr(addr net.Addr) error {
|
||||||
|
return c.withAddrRw(addr, func(rw *bufio.ReadWriter) error {
|
||||||
|
if _, err := fmt.Fprintf(rw, "flush_all\r\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := rw.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
line, err := rw.ReadSlice('\n')
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case bytes.Equal(line, resultOk):
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("memcache: unexpected response line from flush_all: %q", string(line))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ping sends the version command to the given addr
|
||||||
|
func (c *Client) ping(addr net.Addr) error {
|
||||||
|
return c.withAddrRw(addr, func(rw *bufio.ReadWriter) error {
|
||||||
|
if _, err := fmt.Fprintf(rw, "version\r\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := rw.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
line, err := rw.ReadSlice('\n')
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case bytes.HasPrefix(line, versionPrefix):
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("memcache: unexpected response line from ping: %q", string(line))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) touchFromAddr(addr net.Addr, keys []string, expiration int32) error {
|
||||||
|
return c.withAddrRw(addr, func(rw *bufio.ReadWriter) error {
|
||||||
|
for _, key := range keys {
|
||||||
|
if _, err := fmt.Fprintf(rw, "touch %s %d\r\n", key, expiration); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := rw.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
line, err := rw.ReadSlice('\n')
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case bytes.Equal(line, resultTouched):
|
||||||
|
break
|
||||||
|
case bytes.Equal(line, resultNotFound):
|
||||||
|
return ErrCacheMiss
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("memcache: unexpected response line from touch: %q", string(line))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMulti is a batch version of Get. The returned map from keys to
|
||||||
|
// items may have fewer elements than the input slice, due to memcache
|
||||||
|
// cache misses. Each key must be at most 250 bytes in length.
|
||||||
|
// If no error is returned, the returned map will also be non-nil.
|
||||||
|
func (c *Client) GetMulti(keys []string) (map[string]*Item, error) {
|
||||||
|
var lk sync.Mutex
|
||||||
|
m := make(map[string]*Item)
|
||||||
|
addItemToMap := func(it *Item) {
|
||||||
|
lk.Lock()
|
||||||
|
defer lk.Unlock()
|
||||||
|
m[it.Key] = it
|
||||||
|
}
|
||||||
|
|
||||||
|
keyMap := make(map[net.Addr][]string)
|
||||||
|
for _, key := range keys {
|
||||||
|
if !legalKey(key) {
|
||||||
|
return nil, ErrMalformedKey
|
||||||
|
}
|
||||||
|
addr, err := c.selector.PickServer(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
keyMap[addr] = append(keyMap[addr], key)
|
||||||
|
}
|
||||||
|
|
||||||
|
ch := make(chan error, buffered)
|
||||||
|
for addr, keys := range keyMap {
|
||||||
|
go func(addr net.Addr, keys []string) {
|
||||||
|
ch <- c.getFromAddr(addr, keys, addItemToMap)
|
||||||
|
}(addr, keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
for _ = range keyMap {
|
||||||
|
if ge := <-ch; ge != nil {
|
||||||
|
err = ge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseGetResponse reads a GET response from r and calls cb for each
|
||||||
|
// read and allocated Item
|
||||||
|
func parseGetResponse(r *bufio.Reader, cb func(*Item)) error {
|
||||||
|
for {
|
||||||
|
line, err := r.ReadSlice('\n')
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if bytes.Equal(line, resultEnd) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
it := new(Item)
|
||||||
|
size, err := scanGetResponseLine(line, it)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
it.Value = make([]byte, size+2)
|
||||||
|
_, err = io.ReadFull(r, it.Value)
|
||||||
|
if err != nil {
|
||||||
|
it.Value = nil
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !bytes.HasSuffix(it.Value, crlf) {
|
||||||
|
it.Value = nil
|
||||||
|
return fmt.Errorf("memcache: corrupt get result read")
|
||||||
|
}
|
||||||
|
it.Value = it.Value[:size]
|
||||||
|
cb(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scanGetResponseLine populates it and returns the declared size of the item.
|
||||||
|
// It does not read the bytes of the item.
|
||||||
|
func scanGetResponseLine(line []byte, it *Item) (size int, err error) {
|
||||||
|
pattern := "VALUE %s %d %d %d\r\n"
|
||||||
|
dest := []interface{}{&it.Key, &it.Flags, &size, &it.CasID}
|
||||||
|
if bytes.Count(line, space) == 3 {
|
||||||
|
pattern = "VALUE %s %d %d\r\n"
|
||||||
|
dest = dest[:3]
|
||||||
|
}
|
||||||
|
n, err := fmt.Sscanf(string(line), pattern, dest...)
|
||||||
|
if err != nil || n != len(dest) {
|
||||||
|
return -1, fmt.Errorf("memcache: unexpected line in get response: %q", line)
|
||||||
|
}
|
||||||
|
return size, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set writes the given item, unconditionally.
|
||||||
|
func (c *Client) Set(item *Item) error {
|
||||||
|
return c.onItem(item, (*Client).set)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) set(rw *bufio.ReadWriter, item *Item) error {
|
||||||
|
return c.populateOne(rw, "set", item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add writes the given item, if no value already exists for its
|
||||||
|
// key. ErrNotStored is returned if that condition is not met.
|
||||||
|
func (c *Client) Add(item *Item) error {
|
||||||
|
return c.onItem(item, (*Client).add)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) add(rw *bufio.ReadWriter, item *Item) error {
|
||||||
|
return c.populateOne(rw, "add", item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace writes the given item, but only if the server *does*
|
||||||
|
// already hold data for this key
|
||||||
|
func (c *Client) Replace(item *Item) error {
|
||||||
|
return c.onItem(item, (*Client).replace)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) replace(rw *bufio.ReadWriter, item *Item) error {
|
||||||
|
return c.populateOne(rw, "replace", item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append appends the given item to the existing item, if a value already
|
||||||
|
// exists for its key. ErrNotStored is returned if that condition is not met.
|
||||||
|
func (c *Client) Append(item *Item) error {
|
||||||
|
return c.onItem(item, (*Client).append)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) append(rw *bufio.ReadWriter, item *Item) error {
|
||||||
|
return c.populateOne(rw, "append", item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepend prepends the given item to the existing item, if a value already
|
||||||
|
// exists for its key. ErrNotStored is returned if that condition is not met.
|
||||||
|
func (c *Client) Prepend(item *Item) error {
|
||||||
|
return c.onItem(item, (*Client).prepend)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) prepend(rw *bufio.ReadWriter, item *Item) error {
|
||||||
|
return c.populateOne(rw, "prepend", item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompareAndSwap writes the given item that was previously returned
|
||||||
|
// by Get, if the value was neither modified or evicted between the
|
||||||
|
// Get and the CompareAndSwap calls. The item's Key should not change
|
||||||
|
// between calls but all other item fields may differ. ErrCASConflict
|
||||||
|
// is returned if the value was modified in between the
|
||||||
|
// calls. ErrNotStored is returned if the value was evicted in between
|
||||||
|
// the calls.
|
||||||
|
func (c *Client) CompareAndSwap(item *Item) error {
|
||||||
|
return c.onItem(item, (*Client).cas)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) cas(rw *bufio.ReadWriter, item *Item) error {
|
||||||
|
return c.populateOne(rw, "cas", item)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) populateOne(rw *bufio.ReadWriter, verb string, item *Item) error {
|
||||||
|
if !legalKey(item.Key) {
|
||||||
|
return ErrMalformedKey
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
if verb == "cas" {
|
||||||
|
_, err = fmt.Fprintf(rw, "%s %s %d %d %d %d\r\n",
|
||||||
|
verb, item.Key, item.Flags, item.Expiration, len(item.Value), item.CasID)
|
||||||
|
} else {
|
||||||
|
_, err = fmt.Fprintf(rw, "%s %s %d %d %d\r\n",
|
||||||
|
verb, item.Key, item.Flags, item.Expiration, len(item.Value))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = rw.Write(item.Value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := rw.Write(crlf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := rw.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
line, err := rw.ReadSlice('\n')
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case bytes.Equal(line, resultStored):
|
||||||
|
return nil
|
||||||
|
case bytes.Equal(line, resultNotStored):
|
||||||
|
return ErrNotStored
|
||||||
|
case bytes.Equal(line, resultExists):
|
||||||
|
return ErrCASConflict
|
||||||
|
case bytes.Equal(line, resultNotFound):
|
||||||
|
return ErrCacheMiss
|
||||||
|
}
|
||||||
|
return fmt.Errorf("memcache: unexpected response line from %q: %q", verb, string(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeReadLine(rw *bufio.ReadWriter, format string, args ...interface{}) ([]byte, error) {
|
||||||
|
_, err := fmt.Fprintf(rw, format, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rw.Flush(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
line, err := rw.ReadSlice('\n')
|
||||||
|
return line, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeExpectf(rw *bufio.ReadWriter, expect []byte, format string, args ...interface{}) error {
|
||||||
|
line, err := writeReadLine(rw, format, args...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case bytes.Equal(line, resultOK):
|
||||||
|
return nil
|
||||||
|
case bytes.Equal(line, expect):
|
||||||
|
return nil
|
||||||
|
case bytes.Equal(line, resultNotStored):
|
||||||
|
return ErrNotStored
|
||||||
|
case bytes.Equal(line, resultExists):
|
||||||
|
return ErrCASConflict
|
||||||
|
case bytes.Equal(line, resultNotFound):
|
||||||
|
return ErrCacheMiss
|
||||||
|
}
|
||||||
|
return fmt.Errorf("memcache: unexpected response line: %q", string(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes the item with the provided key. The error ErrCacheMiss is
|
||||||
|
// returned if the item didn't already exist in the cache.
|
||||||
|
func (c *Client) Delete(key string) error {
|
||||||
|
return c.withKeyRw(key, func(rw *bufio.ReadWriter) error {
|
||||||
|
return writeExpectf(rw, resultDeleted, "delete %s\r\n", key)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteAll deletes all items in the cache.
|
||||||
|
func (c *Client) DeleteAll() error {
|
||||||
|
return c.withKeyRw("", func(rw *bufio.ReadWriter) error {
|
||||||
|
return writeExpectf(rw, resultDeleted, "flush_all\r\n")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ping checks all instances if they are alive. Returns error if any
|
||||||
|
// of them is down.
|
||||||
|
func (c *Client) Ping() error {
|
||||||
|
return c.selector.Each(c.ping)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment atomically increments key by delta. The return value is
|
||||||
|
// the new value after being incremented or an error. If the value
|
||||||
|
// didn't exist in memcached the error is ErrCacheMiss. The value in
|
||||||
|
// memcached must be an decimal number, or an error will be returned.
|
||||||
|
// On 64-bit overflow, the new value wraps around.
|
||||||
|
func (c *Client) Increment(key string, delta uint64) (newValue uint64, err error) {
|
||||||
|
return c.incrDecr("incr", key, delta)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrement atomically decrements key by delta. The return value is
|
||||||
|
// the new value after being decremented or an error. If the value
|
||||||
|
// didn't exist in memcached the error is ErrCacheMiss. The value in
|
||||||
|
// memcached must be an decimal number, or an error will be returned.
|
||||||
|
// On underflow, the new value is capped at zero and does not wrap
|
||||||
|
// around.
|
||||||
|
func (c *Client) Decrement(key string, delta uint64) (newValue uint64, err error) {
|
||||||
|
return c.incrDecr("decr", key, delta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) incrDecr(verb, key string, delta uint64) (uint64, error) {
|
||||||
|
var val uint64
|
||||||
|
err := c.withKeyRw(key, func(rw *bufio.ReadWriter) error {
|
||||||
|
line, err := writeReadLine(rw, "%s %s %d\r\n", verb, key, delta)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case bytes.Equal(line, resultNotFound):
|
||||||
|
return ErrCacheMiss
|
||||||
|
case bytes.HasPrefix(line, resultClientErrorPrefix):
|
||||||
|
errMsg := line[len(resultClientErrorPrefix) : len(line)-2]
|
||||||
|
return errors.New("memcache: client error: " + string(errMsg))
|
||||||
|
}
|
||||||
|
val, err = strconv.ParseUint(string(line[:len(line)-2]), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return val, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes any open connections.
|
||||||
|
//
|
||||||
|
// It returns the first error encountered closing connections, but always
|
||||||
|
// closes all connections.
|
||||||
|
//
|
||||||
|
// After Close, the Client may still be used.
|
||||||
|
func (c *Client) Close() error {
|
||||||
|
c.lk.Lock()
|
||||||
|
defer c.lk.Unlock()
|
||||||
|
var ret error
|
||||||
|
for _, conns := range c.freeconn {
|
||||||
|
for _, c := range conns {
|
||||||
|
if err := c.nc.Close(); err != nil && ret == nil {
|
||||||
|
ret = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.freeconn = nil
|
||||||
|
return ret
|
||||||
|
}
|
129
vendor/github.com/bradfitz/gomemcache/memcache/selector.go
generated
vendored
Normal file
129
vendor/github.com/bradfitz/gomemcache/memcache/selector.go
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2011 The gomemcache AUTHORS
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package memcache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash/crc32"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ServerSelector is the interface that selects a memcache server
|
||||||
|
// as a function of the item's key.
|
||||||
|
//
|
||||||
|
// All ServerSelector implementations must be safe for concurrent use
|
||||||
|
// by multiple goroutines.
|
||||||
|
type ServerSelector interface {
|
||||||
|
// PickServer returns the server address that a given item
|
||||||
|
// should be shared onto.
|
||||||
|
PickServer(key string) (net.Addr, error)
|
||||||
|
Each(func(net.Addr) error) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerList is a simple ServerSelector. Its zero value is usable.
|
||||||
|
type ServerList struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
addrs []net.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
// staticAddr caches the Network() and String() values from any net.Addr.
|
||||||
|
type staticAddr struct {
|
||||||
|
ntw, str string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStaticAddr(a net.Addr) net.Addr {
|
||||||
|
return &staticAddr{
|
||||||
|
ntw: a.Network(),
|
||||||
|
str: a.String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *staticAddr) Network() string { return s.ntw }
|
||||||
|
func (s *staticAddr) String() string { return s.str }
|
||||||
|
|
||||||
|
// SetServers changes a ServerList's set of servers at runtime and is
|
||||||
|
// safe for concurrent use by multiple goroutines.
|
||||||
|
//
|
||||||
|
// Each server is given equal weight. A server is given more weight
|
||||||
|
// if it's listed multiple times.
|
||||||
|
//
|
||||||
|
// SetServers returns an error if any of the server names fail to
|
||||||
|
// resolve. No attempt is made to connect to the server. If any error
|
||||||
|
// is returned, no changes are made to the ServerList.
|
||||||
|
func (ss *ServerList) SetServers(servers ...string) error {
|
||||||
|
naddr := make([]net.Addr, len(servers))
|
||||||
|
for i, server := range servers {
|
||||||
|
if strings.Contains(server, "/") {
|
||||||
|
addr, err := net.ResolveUnixAddr("unix", server)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
naddr[i] = newStaticAddr(addr)
|
||||||
|
} else {
|
||||||
|
tcpaddr, err := net.ResolveTCPAddr("tcp", server)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
naddr[i] = newStaticAddr(tcpaddr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ss.mu.Lock()
|
||||||
|
defer ss.mu.Unlock()
|
||||||
|
ss.addrs = naddr
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each iterates over each server calling the given function
|
||||||
|
func (ss *ServerList) Each(f func(net.Addr) error) error {
|
||||||
|
ss.mu.RLock()
|
||||||
|
defer ss.mu.RUnlock()
|
||||||
|
for _, a := range ss.addrs {
|
||||||
|
if err := f(a); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// keyBufPool returns []byte buffers for use by PickServer's call to
|
||||||
|
// crc32.ChecksumIEEE to avoid allocations. (but doesn't avoid the
|
||||||
|
// copies, which at least are bounded in size and small)
|
||||||
|
var keyBufPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
b := make([]byte, 256)
|
||||||
|
return &b
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ss *ServerList) PickServer(key string) (net.Addr, error) {
|
||||||
|
ss.mu.RLock()
|
||||||
|
defer ss.mu.RUnlock()
|
||||||
|
if len(ss.addrs) == 0 {
|
||||||
|
return nil, ErrNoServers
|
||||||
|
}
|
||||||
|
if len(ss.addrs) == 1 {
|
||||||
|
return ss.addrs[0], nil
|
||||||
|
}
|
||||||
|
bufp := keyBufPool.Get().(*[]byte)
|
||||||
|
n := copy(*bufp, key)
|
||||||
|
cs := crc32.ChecksumIEEE((*bufp)[:n])
|
||||||
|
keyBufPool.Put(bufp)
|
||||||
|
|
||||||
|
return ss.addrs[cs%uint32(len(ss.addrs))], nil
|
||||||
|
}
|
29
vendor/github.com/gobuffalo/logger/.gitignore
generated
vendored
29
vendor/github.com/gobuffalo/logger/.gitignore
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
*.log
|
|
||||||
.DS_Store
|
|
||||||
doc
|
|
||||||
tmp
|
|
||||||
pkg
|
|
||||||
*.gem
|
|
||||||
*.pid
|
|
||||||
coverage
|
|
||||||
coverage.data
|
|
||||||
build/*
|
|
||||||
*.pbxuser
|
|
||||||
*.mode1v3
|
|
||||||
.svn
|
|
||||||
profile
|
|
||||||
.console_history
|
|
||||||
.sass-cache/*
|
|
||||||
.rake_tasks~
|
|
||||||
*.log.lck
|
|
||||||
solr/
|
|
||||||
.jhw-cache/
|
|
||||||
jhw.*
|
|
||||||
*.sublime*
|
|
||||||
node_modules/
|
|
||||||
dist/
|
|
||||||
generated/
|
|
||||||
.vendor/
|
|
||||||
bin/*
|
|
||||||
gin-bin
|
|
||||||
.idea/
|
|
21
vendor/github.com/gobuffalo/logger/LICENSE
generated
vendored
21
vendor/github.com/gobuffalo/logger/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2019 Mark Bates
|
|
||||||
|
|
||||||
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.
|
|
61
vendor/github.com/gobuffalo/logger/Makefile
generated
vendored
61
vendor/github.com/gobuffalo/logger/Makefile
generated
vendored
@ -1,61 +0,0 @@
|
|||||||
TAGS ?= ""
|
|
||||||
GO_BIN ?= "go"
|
|
||||||
|
|
||||||
install:
|
|
||||||
$(GO_BIN) install -tags ${TAGS} -v .
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
tidy:
|
|
||||||
ifeq ($(GO111MODULE),on)
|
|
||||||
$(GO_BIN) mod tidy
|
|
||||||
else
|
|
||||||
echo skipping go mod tidy
|
|
||||||
endif
|
|
||||||
|
|
||||||
deps:
|
|
||||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
build:
|
|
||||||
$(GO_BIN) build -v .
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
test:
|
|
||||||
$(GO_BIN) test -cover -tags ${TAGS} ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
ci-deps:
|
|
||||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
|
||||||
|
|
||||||
ci-test:
|
|
||||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
|
||||||
|
|
||||||
lint:
|
|
||||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
|
||||||
golangci-lint run --enable-all
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
update:
|
|
||||||
ifeq ($(GO111MODULE),on)
|
|
||||||
rm go.*
|
|
||||||
$(GO_BIN) mod init
|
|
||||||
$(GO_BIN) mod tidy
|
|
||||||
else
|
|
||||||
$(GO_BIN) get -u -tags ${TAGS}
|
|
||||||
endif
|
|
||||||
make test
|
|
||||||
make install
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
release-test:
|
|
||||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
release:
|
|
||||||
$(GO_BIN) get github.com/gobuffalo/release
|
|
||||||
make tidy
|
|
||||||
release -y -f version.go --skip-packr
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
|
|
||||||
|
|
24
vendor/github.com/gobuffalo/logger/README.md
generated
vendored
24
vendor/github.com/gobuffalo/logger/README.md
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
<p align="center"><img src="https://github.com/gobuffalo/buffalo/blob/master/logo.svg" width="360"></p>
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://godoc.org/github.com/gobuffalo/logger"><img src="https://godoc.org/github.com/gobuffalo/logger?status.svg" alt="GoDoc" /></a>
|
|
||||||
|
|
||||||
![Tests](https://github.com/gobuffalo/logger/actions/workflows/tests.yml/badge.svg)
|
|
||||||
|
|
||||||
<a href="https://goreportcard.com/report/github.com/gobuffalo/logger"><img src="https://goreportcard.com/badge/github.com/gobuffalo/logger" alt="Go Report Card" /></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
# Logger
|
|
||||||
|
|
||||||
The [`logger.Logger`](https://godoc.org/github.com/gobuffalo/logger#Logger) interface is used throughout Buffalo apps, and other systems, to log a whole manner of things.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ go get -u github.com/gobuffalo/logger
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
* [GoDoc](https://godoc.org/github.com/gobuffalo/logger)
|
|
||||||
* [General Buffalo Documentation](https://gobuffalo.io)
|
|
18
vendor/github.com/gobuffalo/logger/SHOULDERS.md
generated
vendored
18
vendor/github.com/gobuffalo/logger/SHOULDERS.md
generated
vendored
@ -1,18 +0,0 @@
|
|||||||
# github.com/gobuffalo/logger Stands on the Shoulders of Giants
|
|
||||||
|
|
||||||
github.com/gobuffalo/logger does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
|
||||||
|
|
||||||
Thank you to the following **GIANTS**:
|
|
||||||
|
|
||||||
|
|
||||||
* [github.com/gobuffalo/envy](https://godoc.org/github.com/gobuffalo/envy)
|
|
||||||
|
|
||||||
* [github.com/konsorten/go-windows-terminal-sequences](https://godoc.org/github.com/konsorten/go-windows-terminal-sequences)
|
|
||||||
|
|
||||||
* [github.com/rogpeppe/go-internal](https://godoc.org/github.com/rogpeppe/go-internal)
|
|
||||||
|
|
||||||
* [github.com/sirupsen/logrus](https://godoc.org/github.com/sirupsen/logrus)
|
|
||||||
|
|
||||||
* [golang.org/x/term](https://godoc.org/golang.org/x/term)
|
|
||||||
|
|
||||||
* [golang.org/x/sys](https://godoc.org/golang.org/x/sys)
|
|
154
vendor/github.com/gobuffalo/logger/formatter.go
generated
vendored
154
vendor/github.com/gobuffalo/logger/formatter.go
generated
vendored
@ -1,154 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
// I really don't want to have this, but until (if) https://github.com/sirupsen/logrus/pull/606 is merged we're stuck with all this code. And yes, this is ALL needed just to remove some blank space in the logs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
red = 31
|
|
||||||
yellow = 33
|
|
||||||
blue = 36
|
|
||||||
gray = 37
|
|
||||||
)
|
|
||||||
|
|
||||||
// textFormatter formats logs into text
|
|
||||||
type textFormatter struct {
|
|
||||||
ForceColors bool
|
|
||||||
isTerminal bool
|
|
||||||
sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *textFormatter) init(entry *logrus.Entry) {
|
|
||||||
if entry.Logger != nil {
|
|
||||||
f.isTerminal = checkIfTerminal(entry.Logger.Out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultTimestampFormat = time.RFC3339
|
|
||||||
|
|
||||||
// Format renders a single log entry
|
|
||||||
func (f *textFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
|
||||||
prefixFieldClashes(entry.Data)
|
|
||||||
|
|
||||||
keys := make([]string, 0, len(entry.Data))
|
|
||||||
for k := range entry.Data {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
var b *bytes.Buffer
|
|
||||||
if entry.Buffer != nil {
|
|
||||||
b = entry.Buffer
|
|
||||||
} else {
|
|
||||||
b = &bytes.Buffer{}
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Do(func() { f.init(entry) })
|
|
||||||
|
|
||||||
isColored := (f.ForceColors || f.isTerminal)
|
|
||||||
|
|
||||||
if isColored {
|
|
||||||
f.printColored(b, entry, keys)
|
|
||||||
} else {
|
|
||||||
f.appendKeyValue(b, "level", entry.Level.String())
|
|
||||||
f.appendKeyValue(b, "time", entry.Time.Format(defaultTimestampFormat))
|
|
||||||
if entry.Message != "" {
|
|
||||||
f.appendKeyValue(b, "msg", entry.Message)
|
|
||||||
}
|
|
||||||
for _, key := range keys {
|
|
||||||
f.appendKeyValue(b, key, entry.Data[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b.WriteByte('\n')
|
|
||||||
return b.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *textFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry, keys []string) {
|
|
||||||
var levelColor int
|
|
||||||
switch entry.Level {
|
|
||||||
case logrus.DebugLevel:
|
|
||||||
levelColor = gray
|
|
||||||
case logrus.WarnLevel:
|
|
||||||
levelColor = yellow
|
|
||||||
case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
|
|
||||||
levelColor = red
|
|
||||||
default:
|
|
||||||
levelColor = blue
|
|
||||||
}
|
|
||||||
|
|
||||||
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
|
||||||
|
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]", levelColor, levelText, entry.Time.Format(defaultTimestampFormat))
|
|
||||||
|
|
||||||
if entry.Message != "" {
|
|
||||||
fmt.Fprintf(b, " %s", entry.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, k := range keys {
|
|
||||||
v := entry.Data[k]
|
|
||||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
|
||||||
f.appendValue(b, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *textFormatter) needsQuoting(text string) bool {
|
|
||||||
if len(text) == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, ch := range text {
|
|
||||||
if !((ch >= 'a' && ch <= 'z') ||
|
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
|
||||||
(ch >= '0' && ch <= '9') ||
|
|
||||||
ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *textFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
|
||||||
if b.Len() > 0 {
|
|
||||||
b.WriteByte(' ')
|
|
||||||
}
|
|
||||||
b.WriteString(key)
|
|
||||||
b.WriteByte('=')
|
|
||||||
f.appendValue(b, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *textFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
|
||||||
stringVal, ok := value.(string)
|
|
||||||
if !ok {
|
|
||||||
stringVal = fmt.Sprint(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !f.needsQuoting(stringVal) {
|
|
||||||
b.WriteString(stringVal)
|
|
||||||
} else {
|
|
||||||
b.WriteString(fmt.Sprintf("%q", stringVal))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func prefixFieldClashes(data logrus.Fields) {
|
|
||||||
if t, ok := data["time"]; ok {
|
|
||||||
data["fields.time"] = t
|
|
||||||
}
|
|
||||||
|
|
||||||
if m, ok := data["msg"]; ok {
|
|
||||||
data["fields.msg"] = m
|
|
||||||
}
|
|
||||||
|
|
||||||
if l, ok := data["level"]; ok {
|
|
||||||
data["fields.level"] = l
|
|
||||||
}
|
|
||||||
}
|
|
25
vendor/github.com/gobuffalo/logger/level.go
generated
vendored
25
vendor/github.com/gobuffalo/logger/level.go
generated
vendored
@ -1,25 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
import "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
// Level of the logger
|
|
||||||
type Level = logrus.Level
|
|
||||||
|
|
||||||
const (
|
|
||||||
// PanicLevel level, highest level of severity. Logs and then calls panic with the
|
|
||||||
// message passed to Debug, Info, ...
|
|
||||||
PanicLevel = logrus.PanicLevel
|
|
||||||
// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
|
|
||||||
// logging level is set to Panic.
|
|
||||||
FatalLevel = logrus.FatalLevel
|
|
||||||
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
|
|
||||||
// Commonly used for hooks to send errors to an error tracking service.
|
|
||||||
ErrorLevel = logrus.ErrorLevel
|
|
||||||
// WarnLevel level. Non-critical entries that deserve eyes.
|
|
||||||
WarnLevel = logrus.WarnLevel
|
|
||||||
// InfoLevel level. General operational entries about what's going on inside the
|
|
||||||
// application.
|
|
||||||
InfoLevel = logrus.InfoLevel
|
|
||||||
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
|
|
||||||
DebugLevel = logrus.DebugLevel
|
|
||||||
)
|
|
67
vendor/github.com/gobuffalo/logger/logger.go
generated
vendored
67
vendor/github.com/gobuffalo/logger/logger.go
generated
vendored
@ -1,67 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FieldLogger interface
|
|
||||||
type FieldLogger interface {
|
|
||||||
Logger
|
|
||||||
WithField(string, interface{}) FieldLogger
|
|
||||||
WithFields(map[string]interface{}) FieldLogger
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logger interface is used throughout Buffalo
|
|
||||||
// apps to log a whole manner of things.
|
|
||||||
type Logger interface {
|
|
||||||
Debugf(string, ...interface{})
|
|
||||||
Infof(string, ...interface{})
|
|
||||||
Printf(string, ...interface{})
|
|
||||||
Warnf(string, ...interface{})
|
|
||||||
Errorf(string, ...interface{})
|
|
||||||
Fatalf(string, ...interface{})
|
|
||||||
Debug(...interface{})
|
|
||||||
Info(...interface{})
|
|
||||||
Warn(...interface{})
|
|
||||||
Error(...interface{})
|
|
||||||
Fatal(...interface{})
|
|
||||||
Panic(...interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseLevel(level string) (Level, error) {
|
|
||||||
l, err := logrus.ParseLevel(level)
|
|
||||||
return Level(l), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLogger based on the specified log level, defaults to "debug".
|
|
||||||
// See `New` for more details.
|
|
||||||
func NewLogger(level string) FieldLogger {
|
|
||||||
lvl, err := logrus.ParseLevel(level)
|
|
||||||
if err != nil {
|
|
||||||
lvl = logrus.DebugLevel
|
|
||||||
}
|
|
||||||
return New(lvl)
|
|
||||||
}
|
|
||||||
|
|
||||||
// New based on the specified log level, defaults to "debug".
|
|
||||||
// This logger will log to the STDOUT in a human readable,
|
|
||||||
// but parseable form.
|
|
||||||
/*
|
|
||||||
Example: time="2016-12-01T21:02:07-05:00" level=info duration=225.283µs human_size="106 B" method=GET path="/" render=199.79µs request_id=2265736089 size=106 status=200
|
|
||||||
*/
|
|
||||||
func New(lvl Level) FieldLogger {
|
|
||||||
e := os.Getenv("GO_ENV")
|
|
||||||
if len(e) == 0 {
|
|
||||||
e = "development"
|
|
||||||
}
|
|
||||||
dev := e == "development"
|
|
||||||
l := logrus.New()
|
|
||||||
l.SetOutput(os.Stdout)
|
|
||||||
l.Level = lvl
|
|
||||||
l.Formatter = &textFormatter{
|
|
||||||
ForceColors: dev,
|
|
||||||
}
|
|
||||||
return Logrus{l}
|
|
||||||
}
|
|
34
vendor/github.com/gobuffalo/logger/logrus.go
generated
vendored
34
vendor/github.com/gobuffalo/logger/logrus.go
generated
vendored
@ -1,34 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ Logger = Logrus{}
|
|
||||||
var _ FieldLogger = Logrus{}
|
|
||||||
var _ Outable = Logrus{}
|
|
||||||
|
|
||||||
// Logrus is a Logger implementation backed by sirupsen/logrus
|
|
||||||
type Logrus struct {
|
|
||||||
logrus.FieldLogger
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOutput will try and set the output of the underlying
|
|
||||||
// logrus.FieldLogger if it can
|
|
||||||
func (l Logrus) SetOutput(w io.Writer) {
|
|
||||||
if lg, ok := l.FieldLogger.(Outable); ok {
|
|
||||||
lg.SetOutput(w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithField returns a new Logger with the field added
|
|
||||||
func (l Logrus) WithField(s string, i interface{}) FieldLogger {
|
|
||||||
return Logrus{l.FieldLogger.WithField(s, i)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithFields returns a new Logger with the fields added
|
|
||||||
func (l Logrus) WithFields(m map[string]interface{}) FieldLogger {
|
|
||||||
return Logrus{l.FieldLogger.WithFields(m)}
|
|
||||||
}
|
|
8
vendor/github.com/gobuffalo/logger/outable.go
generated
vendored
8
vendor/github.com/gobuffalo/logger/outable.go
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// Outable interface for loggers that allow setting the output writer
|
|
||||||
type Outable interface {
|
|
||||||
SetOutput(out io.Writer)
|
|
||||||
}
|
|
19
vendor/github.com/gobuffalo/logger/terminal_check.go
generated
vendored
19
vendor/github.com/gobuffalo/logger/terminal_check.go
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
// +build !appengine
|
|
||||||
|
|
||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"golang.org/x/term"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
|
||||||
switch v := w.(type) {
|
|
||||||
case *os.File:
|
|
||||||
return term.IsTerminal(int(v.Fd()))
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
11
vendor/github.com/gobuffalo/logger/terminal_check_appengine.go
generated
vendored
11
vendor/github.com/gobuffalo/logger/terminal_check_appengine.go
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
// +build appengine
|
|
||||||
|
|
||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIfTerminal(w io.Writer) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
4
vendor/github.com/gobuffalo/logger/version.go
generated
vendored
4
vendor/github.com/gobuffalo/logger/version.go
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
// Version of the logger
|
|
||||||
const Version = "v1.0.6"
|
|
29
vendor/github.com/gobuffalo/packd/.gitignore
generated
vendored
29
vendor/github.com/gobuffalo/packd/.gitignore
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
*.log
|
|
||||||
.DS_Store
|
|
||||||
doc
|
|
||||||
tmp
|
|
||||||
pkg
|
|
||||||
*.gem
|
|
||||||
*.pid
|
|
||||||
coverage
|
|
||||||
coverage.data
|
|
||||||
build/*
|
|
||||||
*.pbxuser
|
|
||||||
*.mode1v3
|
|
||||||
.svn
|
|
||||||
profile
|
|
||||||
.console_history
|
|
||||||
.sass-cache/*
|
|
||||||
.rake_tasks~
|
|
||||||
*.log.lck
|
|
||||||
solr/
|
|
||||||
.jhw-cache/
|
|
||||||
jhw.*
|
|
||||||
*.sublime*
|
|
||||||
node_modules/
|
|
||||||
dist/
|
|
||||||
generated/
|
|
||||||
.vendor/
|
|
||||||
bin/*
|
|
||||||
gin-bin
|
|
||||||
.idea/
|
|
21
vendor/github.com/gobuffalo/packd/LICENSE
generated
vendored
21
vendor/github.com/gobuffalo/packd/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2019 Mark Bates
|
|
||||||
|
|
||||||
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.
|
|
61
vendor/github.com/gobuffalo/packd/Makefile
generated
vendored
61
vendor/github.com/gobuffalo/packd/Makefile
generated
vendored
@ -1,61 +0,0 @@
|
|||||||
TAGS ?= ""
|
|
||||||
GO_BIN ?= "go"
|
|
||||||
|
|
||||||
install:
|
|
||||||
$(GO_BIN) install -tags ${TAGS} -v .
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
tidy:
|
|
||||||
ifeq ($(GO111MODULE),on)
|
|
||||||
$(GO_BIN) mod tidy
|
|
||||||
else
|
|
||||||
echo skipping go mod tidy
|
|
||||||
endif
|
|
||||||
|
|
||||||
deps:
|
|
||||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
build:
|
|
||||||
$(GO_BIN) build -v .
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
test:
|
|
||||||
$(GO_BIN) test -cover -tags ${TAGS} ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
ci-deps:
|
|
||||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
|
||||||
|
|
||||||
ci-test:
|
|
||||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
|
||||||
|
|
||||||
lint:
|
|
||||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
|
||||||
golangci-lint run --enable-all
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
update:
|
|
||||||
ifeq ($(GO111MODULE),on)
|
|
||||||
rm go.*
|
|
||||||
$(GO_BIN) mod init
|
|
||||||
$(GO_BIN) mod tidy
|
|
||||||
else
|
|
||||||
$(GO_BIN) get -u -tags ${TAGS}
|
|
||||||
endif
|
|
||||||
make test
|
|
||||||
make install
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
release-test:
|
|
||||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
release:
|
|
||||||
$(GO_BIN) get github.com/gobuffalo/release
|
|
||||||
make tidy
|
|
||||||
release -y -f version.go --skip-packr
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
|
|
||||||
|
|
24
vendor/github.com/gobuffalo/packd/README.md
generated
vendored
24
vendor/github.com/gobuffalo/packd/README.md
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
<p align="center"><img src="https://github.com/gobuffalo/buffalo/blob/master/logo.svg" width="360"></p>
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://godoc.org/github.com/gobuffalo/packd"><img src="https://godoc.org/github.com/gobuffalo/packd?status.svg" alt="GoDoc" /></a>
|
|
||||||
<a href="https://travis-ci.org/gobuffalo/packd"><img src="https://travis-ci.org/gobuffalo/packd.svg?branch=master" alt="Build Status" /></a>
|
|
||||||
<a href="https://goreportcard.com/report/github.com/gobuffalo/packd"><img src="https://goreportcard.com/badge/github.com/gobuffalo/packd" alt="Go Report Card" /></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
# github.com/gobuffalo/packd
|
|
||||||
|
|
||||||
This is a collection of interfaces designed to make using [github.com/gobuffalo/packr](https://github.com/gobuffalo/packr) easier, and to make the transition between v1 and v2 as seamless as possible.
|
|
||||||
|
|
||||||
They can, and should, be used for testing, alternate Box implementations, etc...
|
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ go get -u -v github.com/gobuffalo/packd
|
|
||||||
```
|
|
||||||
|
|
||||||
## Memory Box
|
|
||||||
|
|
||||||
The [`packd#MemoryBox`](https://godoc.org/github.com/gobuffalo/packd#MemoryBox) is a complete, thread-safe, implementation of [`packd#Box`](https://godoc.org/github.com/gobuffalo/packd#Box)
|
|
10
vendor/github.com/gobuffalo/packd/SHOULDERS.md
generated
vendored
10
vendor/github.com/gobuffalo/packd/SHOULDERS.md
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
# github.com/gobuffalo/packd Stands on the Shoulders of Giants
|
|
||||||
|
|
||||||
github.com/gobuffalo/packd does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
|
||||||
|
|
||||||
Thank you to the following **GIANTS**:
|
|
||||||
|
|
||||||
|
|
||||||
* [github.com/davecgh/go-spew](https://godoc.org/github.com/davecgh/go-spew)
|
|
||||||
|
|
||||||
* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify)
|
|
126
vendor/github.com/gobuffalo/packd/file.go
generated
vendored
126
vendor/github.com/gobuffalo/packd/file.go
generated
vendored
@ -1,126 +0,0 @@
|
|||||||
package packd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ File = &virtualFile{}
|
|
||||||
var _ io.Reader = &virtualFile{}
|
|
||||||
var _ io.Writer = &virtualFile{}
|
|
||||||
var _ fmt.Stringer = &virtualFile{}
|
|
||||||
|
|
||||||
type virtualFile struct {
|
|
||||||
io.Reader
|
|
||||||
name string
|
|
||||||
info fileInfo
|
|
||||||
original []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f virtualFile) Name() string {
|
|
||||||
return f.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *virtualFile) Seek(offset int64, whence int) (int64, error) {
|
|
||||||
return f.Reader.(*bytes.Reader).Seek(offset, whence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f virtualFile) FileInfo() (os.FileInfo, error) {
|
|
||||||
return f.info, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *virtualFile) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f virtualFile) Readdir(count int) ([]os.FileInfo, error) {
|
|
||||||
return []os.FileInfo{f.info}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f virtualFile) Stat() (os.FileInfo, error) {
|
|
||||||
return f.info, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f virtualFile) String() string {
|
|
||||||
return string(f.original)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads the next len(p) bytes from the virtualFile and
|
|
||||||
// rewind read offset to 0 when it met EOF.
|
|
||||||
func (f *virtualFile) Read(p []byte) (int, error) {
|
|
||||||
i, err := f.Reader.Read(p)
|
|
||||||
|
|
||||||
if i == 0 || err == io.EOF {
|
|
||||||
f.Seek(0, io.SeekStart)
|
|
||||||
}
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write copies byte slice p to content of virtualFile.
|
|
||||||
func (f *virtualFile) Write(p []byte) (int, error) {
|
|
||||||
return f.write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// write copies byte slice or data from io.Reader to content of the
|
|
||||||
// virtualFile and update related information of the virtualFile.
|
|
||||||
func (f *virtualFile) write(d interface{}) (c int, err error) {
|
|
||||||
bb := &bytes.Buffer{}
|
|
||||||
switch d.(type) {
|
|
||||||
case []byte:
|
|
||||||
c, err = bb.Write(d.([]byte))
|
|
||||||
case io.Reader:
|
|
||||||
if d != nil {
|
|
||||||
i64, e := io.Copy(bb, d.(io.Reader))
|
|
||||||
c = int(i64)
|
|
||||||
err = e
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("unknown type of argument")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return c, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f.info.size = int64(c)
|
|
||||||
f.info.modTime = time.Now()
|
|
||||||
f.original = bb.Bytes()
|
|
||||||
f.Reader = bytes.NewReader(f.original)
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFile returns a new "virtual" file
|
|
||||||
func NewFile(name string, r io.Reader) (File, error) {
|
|
||||||
return buildFile(name, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDir returns a new "virtual" directory
|
|
||||||
func NewDir(name string) (File, error) {
|
|
||||||
v, err := buildFile(name, nil)
|
|
||||||
if err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
v.info.isDir = true
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildFile(name string, r io.Reader) (*virtualFile, error) {
|
|
||||||
vf := &virtualFile{
|
|
||||||
name: name,
|
|
||||||
info: fileInfo{
|
|
||||||
Path: name,
|
|
||||||
modTime: time.Now(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
if r != nil {
|
|
||||||
_, err = vf.write(r)
|
|
||||||
} else {
|
|
||||||
_, err = vf.write([]byte{}) // for safety
|
|
||||||
}
|
|
||||||
return vf, err
|
|
||||||
}
|
|
39
vendor/github.com/gobuffalo/packd/file_info.go
generated
vendored
39
vendor/github.com/gobuffalo/packd/file_info.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
package packd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ os.FileInfo = fileInfo{}
|
|
||||||
|
|
||||||
type fileInfo struct {
|
|
||||||
Path string
|
|
||||||
size int64
|
|
||||||
modTime time.Time
|
|
||||||
isDir bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f fileInfo) Name() string {
|
|
||||||
return f.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f fileInfo) Size() int64 {
|
|
||||||
return f.size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f fileInfo) Mode() os.FileMode {
|
|
||||||
return 0444
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f fileInfo) ModTime() time.Time {
|
|
||||||
return f.modTime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f fileInfo) IsDir() bool {
|
|
||||||
return f.isDir
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f fileInfo) Sys() interface{} {
|
|
||||||
return nil
|
|
||||||
}
|
|
83
vendor/github.com/gobuffalo/packd/interfaces.go
generated
vendored
83
vendor/github.com/gobuffalo/packd/interfaces.go
generated
vendored
@ -1,83 +0,0 @@
|
|||||||
package packd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
type WalkFunc func(string, File) error
|
|
||||||
|
|
||||||
// Box represents the entirety of the necessary
|
|
||||||
// interfaces to form a "full" box.
|
|
||||||
// github.com/gobuffalo/packr#Box is an example of this interface.
|
|
||||||
type Box interface {
|
|
||||||
HTTPBox
|
|
||||||
Lister
|
|
||||||
Addable
|
|
||||||
Finder
|
|
||||||
Walkable
|
|
||||||
Haser
|
|
||||||
}
|
|
||||||
|
|
||||||
type Haser interface {
|
|
||||||
Has(string) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type Walker interface {
|
|
||||||
Walk(wf WalkFunc) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Walkable interface {
|
|
||||||
Walker
|
|
||||||
WalkPrefix(prefix string, wf WalkFunc) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Finder interface {
|
|
||||||
Find(string) ([]byte, error)
|
|
||||||
FindString(name string) (string, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type HTTPBox interface {
|
|
||||||
Open(name string) (http.File, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Lister interface {
|
|
||||||
List() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Addable interface {
|
|
||||||
AddString(path string, t string) error
|
|
||||||
AddBytes(path string, t []byte) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type SimpleFile interface {
|
|
||||||
fmt.Stringer
|
|
||||||
io.Reader
|
|
||||||
io.Writer
|
|
||||||
Name() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type HTTPFile interface {
|
|
||||||
SimpleFile
|
|
||||||
io.Closer
|
|
||||||
io.Seeker
|
|
||||||
Readdir(count int) ([]os.FileInfo, error)
|
|
||||||
Stat() (os.FileInfo, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type File interface {
|
|
||||||
HTTPFile
|
|
||||||
FileInfo() (os.FileInfo, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LegacyBox represents deprecated methods
|
|
||||||
// that older Box implementations might have had.
|
|
||||||
// github.com/gobuffalo/packr v1 is an example of a LegacyBox.
|
|
||||||
type LegacyBox interface {
|
|
||||||
String(name string) string
|
|
||||||
MustString(name string) (string, error)
|
|
||||||
Bytes(name string) []byte
|
|
||||||
MustBytes(name string) ([]byte, error)
|
|
||||||
}
|
|
29
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/.gitignore
generated
vendored
29
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/.gitignore
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
*.log
|
|
||||||
.DS_Store
|
|
||||||
doc
|
|
||||||
tmp
|
|
||||||
pkg
|
|
||||||
*.gem
|
|
||||||
*.pid
|
|
||||||
coverage
|
|
||||||
coverage.data
|
|
||||||
build/*
|
|
||||||
*.pbxuser
|
|
||||||
*.mode1v3
|
|
||||||
.svn
|
|
||||||
profile
|
|
||||||
.console_history
|
|
||||||
.sass-cache/*
|
|
||||||
.rake_tasks~
|
|
||||||
*.log.lck
|
|
||||||
solr/
|
|
||||||
.jhw-cache/
|
|
||||||
jhw.*
|
|
||||||
*.sublime*
|
|
||||||
node_modules/
|
|
||||||
dist/
|
|
||||||
generated/
|
|
||||||
.vendor/
|
|
||||||
bin/*
|
|
||||||
gin-bin
|
|
||||||
.idea/
|
|
21
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/LICENSE
generated
vendored
21
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2019 Mark Bates
|
|
||||||
|
|
||||||
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.
|
|
61
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/Makefile
generated
vendored
61
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/Makefile
generated
vendored
@ -1,61 +0,0 @@
|
|||||||
TAGS ?= ""
|
|
||||||
GO_BIN ?= "go"
|
|
||||||
|
|
||||||
install:
|
|
||||||
$(GO_BIN) install -tags ${TAGS} -v .
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
tidy:
|
|
||||||
ifeq ($(GO111MODULE),on)
|
|
||||||
$(GO_BIN) mod tidy
|
|
||||||
else
|
|
||||||
echo skipping go mod tidy
|
|
||||||
endif
|
|
||||||
|
|
||||||
deps:
|
|
||||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
build:
|
|
||||||
$(GO_BIN) build -v .
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
test:
|
|
||||||
$(GO_BIN) test -cover -tags ${TAGS} ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
ci-deps:
|
|
||||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
|
||||||
|
|
||||||
ci-test:
|
|
||||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
|
||||||
|
|
||||||
lint:
|
|
||||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
|
||||||
golangci-lint run --enable-all
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
update:
|
|
||||||
ifeq ($(GO111MODULE),on)
|
|
||||||
rm go.*
|
|
||||||
$(GO_BIN) mod init
|
|
||||||
$(GO_BIN) mod tidy
|
|
||||||
else
|
|
||||||
$(GO_BIN) get -u -tags ${TAGS}
|
|
||||||
endif
|
|
||||||
make test
|
|
||||||
make install
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
release-test:
|
|
||||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
release:
|
|
||||||
$(GO_BIN) get github.com/gobuffalo/release
|
|
||||||
make tidy
|
|
||||||
release -y -f version.go --skip-packr
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
# github.com/markbates/errx Stands on the Shoulders of Giants
|
|
||||||
|
|
||||||
github.com/markbates/errx does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
|
||||||
|
|
||||||
Thank you to the following **GIANTS**:
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
|||||||
variables:
|
|
||||||
GOBIN: "$(GOPATH)/bin" # Go binaries path
|
|
||||||
GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path
|
|
||||||
modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
- job: Windows
|
|
||||||
pool:
|
|
||||||
vmImage: "vs2017-win2016"
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go 1.10:
|
|
||||||
go_version: "1.10"
|
|
||||||
go 1.11 (on):
|
|
||||||
go_version: "1.11.5"
|
|
||||||
GO111MODULE: "on"
|
|
||||||
go 1.11 (off):
|
|
||||||
go_version: "1.11.5"
|
|
||||||
GO111MODULE: "off"
|
|
||||||
go 1.12 (on):
|
|
||||||
go_version: "1.12"
|
|
||||||
GO111MODULE: "on"
|
|
||||||
go 1.12 (off):
|
|
||||||
go_version: "1.12"
|
|
||||||
GO111MODULE: "off"
|
|
||||||
steps:
|
|
||||||
- template: azure-tests.yml
|
|
||||||
|
|
||||||
- job: macOS
|
|
||||||
pool:
|
|
||||||
vmImage: "macOS-10.13"
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go 1.10:
|
|
||||||
go_version: "1.10"
|
|
||||||
go 1.11 (on):
|
|
||||||
go_version: "1.11.5"
|
|
||||||
GO111MODULE: "on"
|
|
||||||
go 1.11 (off):
|
|
||||||
go_version: "1.11.5"
|
|
||||||
GO111MODULE: "off"
|
|
||||||
go 1.12 (on):
|
|
||||||
go_version: "1.12"
|
|
||||||
GO111MODULE: "on"
|
|
||||||
go 1.12 (off):
|
|
||||||
go_version: "1.12"
|
|
||||||
GO111MODULE: "off"
|
|
||||||
steps:
|
|
||||||
- template: azure-tests.yml
|
|
||||||
|
|
||||||
- job: Linux
|
|
||||||
pool:
|
|
||||||
vmImage: "ubuntu-16.04"
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go 1.10:
|
|
||||||
go_version: "1.10"
|
|
||||||
go 1.11 (on):
|
|
||||||
go_version: "1.11.5"
|
|
||||||
GO111MODULE: "on"
|
|
||||||
go 1.11 (off):
|
|
||||||
go_version: "1.11.5"
|
|
||||||
GO111MODULE: "off"
|
|
||||||
go 1.12 (on):
|
|
||||||
go_version: "1.12"
|
|
||||||
GO111MODULE: "on"
|
|
||||||
go 1.12 (off):
|
|
||||||
go_version: "1.12"
|
|
||||||
GO111MODULE: "off"
|
|
||||||
steps:
|
|
||||||
- template: azure-tests.yml
|
|
@ -1,19 +0,0 @@
|
|||||||
steps:
|
|
||||||
- task: GoTool@0
|
|
||||||
inputs:
|
|
||||||
version: $(go_version)
|
|
||||||
- task: Bash@3
|
|
||||||
inputs:
|
|
||||||
targetType: inline
|
|
||||||
script: |
|
|
||||||
mkdir -p "$(GOBIN)"
|
|
||||||
mkdir -p "$(GOPATH)/pkg"
|
|
||||||
mkdir -p "$(modulePath)"
|
|
||||||
shopt -s extglob
|
|
||||||
mv !(gopath) "$(modulePath)"
|
|
||||||
displayName: "Setup Go Workspace"
|
|
||||||
- script: |
|
|
||||||
go get -t -v ./...
|
|
||||||
go test -race ./...
|
|
||||||
workingDirectory: "$(modulePath)"
|
|
||||||
displayName: "Tests"
|
|
23
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/errx.go
generated
vendored
23
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/errx.go
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
package errx
|
|
||||||
|
|
||||||
// go2 errors
|
|
||||||
type Wrapper interface {
|
|
||||||
Unwrap() error
|
|
||||||
}
|
|
||||||
|
|
||||||
// pkg/errors
|
|
||||||
type Causer interface {
|
|
||||||
Cause() error
|
|
||||||
}
|
|
||||||
|
|
||||||
func Unwrap(err error) error {
|
|
||||||
switch e := err.(type) {
|
|
||||||
case Wrapper:
|
|
||||||
return e.Unwrap()
|
|
||||||
case Causer:
|
|
||||||
return e.Cause()
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var Cause = Unwrap
|
|
@ -1,4 +0,0 @@
|
|||||||
package errx
|
|
||||||
|
|
||||||
// Version of errx
|
|
||||||
const Version = "v1.0.0"
|
|
70
vendor/github.com/gobuffalo/packd/map.go
generated
vendored
70
vendor/github.com/gobuffalo/packd/map.go
generated
vendored
@ -1,70 +0,0 @@
|
|||||||
package packd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ByteMap wraps sync.Map and uses the following types:
|
|
||||||
// key: string
|
|
||||||
// value: []byte
|
|
||||||
type ByteMap struct {
|
|
||||||
data sync.Map
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the key from the map
|
|
||||||
func (m *ByteMap) Delete(key string) {
|
|
||||||
m.data.Delete(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the key from the map.
|
|
||||||
// Returns []byte or bool.
|
|
||||||
// A false return indicates either the key was not found
|
|
||||||
// or the value is not of type []byte
|
|
||||||
func (m *ByteMap) Load(key string) ([]byte, bool) {
|
|
||||||
i, ok := m.data.Load(key)
|
|
||||||
if !ok {
|
|
||||||
return []byte(``), false
|
|
||||||
}
|
|
||||||
s, ok := i.([]byte)
|
|
||||||
return s, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadOrStore will return an existing key or
|
|
||||||
// store the value if not already in the map
|
|
||||||
func (m *ByteMap) LoadOrStore(key string, value []byte) ([]byte, bool) {
|
|
||||||
i, _ := m.data.LoadOrStore(key, value)
|
|
||||||
s, ok := i.([]byte)
|
|
||||||
return s, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Range over the []byte values in the map
|
|
||||||
func (m *ByteMap) Range(f func(key string, value []byte) bool) {
|
|
||||||
m.data.Range(func(k, v interface{}) bool {
|
|
||||||
key, ok := k.(string)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
value, ok := v.([]byte)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return f(key, value)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store a []byte in the map
|
|
||||||
func (m *ByteMap) Store(key string, value []byte) {
|
|
||||||
m.data.Store(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys returns a list of keys in the map
|
|
||||||
func (m *ByteMap) Keys() []string {
|
|
||||||
var keys []string
|
|
||||||
m.Range(func(key string, value []byte) bool {
|
|
||||||
keys = append(keys, key)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
sort.Strings(keys)
|
|
||||||
return keys
|
|
||||||
}
|
|
156
vendor/github.com/gobuffalo/packd/memory_box.go
generated
vendored
156
vendor/github.com/gobuffalo/packd/memory_box.go
generated
vendored
@ -1,156 +0,0 @@
|
|||||||
package packd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ Addable = NewMemoryBox()
|
|
||||||
var _ Finder = NewMemoryBox()
|
|
||||||
var _ Lister = NewMemoryBox()
|
|
||||||
var _ HTTPBox = NewMemoryBox()
|
|
||||||
var _ Haser = NewMemoryBox()
|
|
||||||
var _ Walkable = NewMemoryBox()
|
|
||||||
var _ Box = NewMemoryBox()
|
|
||||||
|
|
||||||
// MemoryBox is a thread-safe, in-memory, implementation of the Box interface.
|
|
||||||
type MemoryBox struct {
|
|
||||||
files *ByteMap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) Has(path string) bool {
|
|
||||||
_, ok := m.files.Load(path)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) List() []string {
|
|
||||||
var names []string
|
|
||||||
m.files.Range(func(key string, value []byte) bool {
|
|
||||||
names = append(names, key)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
sort.Strings(names)
|
|
||||||
return names
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) Open(path string) (http.File, error) {
|
|
||||||
cpath := strings.TrimPrefix(path, "/")
|
|
||||||
|
|
||||||
if filepath.Ext(cpath) == "" {
|
|
||||||
// it's a directory
|
|
||||||
return NewDir(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cpath) == 0 {
|
|
||||||
cpath = "index.html"
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := m.Find(cpath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cpath = filepath.FromSlash(cpath)
|
|
||||||
|
|
||||||
f, err := NewFile(cpath, bytes.NewReader(b))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) FindString(path string) (string, error) {
|
|
||||||
bb, err := m.Find(path)
|
|
||||||
return string(bb), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) Find(path string) (ret []byte, e error) {
|
|
||||||
res, ok := m.files.Load(path)
|
|
||||||
if !ok {
|
|
||||||
|
|
||||||
var b []byte
|
|
||||||
lpath := strings.ToLower(path)
|
|
||||||
err := m.Walk(func(p string, file File) error {
|
|
||||||
lp := strings.ToLower(p)
|
|
||||||
if lp != lpath {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res := file.String()
|
|
||||||
b = []byte(res)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return b, os.ErrNotExist
|
|
||||||
}
|
|
||||||
if len(b) == 0 {
|
|
||||||
return b, os.ErrNotExist
|
|
||||||
}
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) AddString(path string, t string) error {
|
|
||||||
return m.AddBytes(path, []byte(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) AddBytes(path string, t []byte) error {
|
|
||||||
m.files.Store(path, t)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) Walk(wf WalkFunc) error {
|
|
||||||
var err error
|
|
||||||
m.files.Range(func(path string, b []byte) bool {
|
|
||||||
var f File
|
|
||||||
f, err = NewFile(path, bytes.NewReader(b))
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
err = wf(path, f)
|
|
||||||
if err != nil {
|
|
||||||
if errx.Unwrap(err) == filepath.SkipDir {
|
|
||||||
err = nil
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
if errx.Unwrap(err) == filepath.SkipDir {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) WalkPrefix(pre string, wf WalkFunc) error {
|
|
||||||
return m.Walk(func(path string, file File) error {
|
|
||||||
if strings.HasPrefix(path, pre) {
|
|
||||||
return wf(path, file)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryBox) Remove(path string) {
|
|
||||||
m.files.Delete(path)
|
|
||||||
m.files.Delete(strings.ToLower(path))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMemoryBox returns a configured *MemoryBox
|
|
||||||
func NewMemoryBox() *MemoryBox {
|
|
||||||
return &MemoryBox{
|
|
||||||
files: &ByteMap{},
|
|
||||||
}
|
|
||||||
}
|
|
43
vendor/github.com/gobuffalo/packd/skip_walker.go
generated
vendored
43
vendor/github.com/gobuffalo/packd/skip_walker.go
generated
vendored
@ -1,43 +0,0 @@
|
|||||||
package packd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var CommonSkipPrefixes = []string{".", "_", "node_modules", "vendor"}
|
|
||||||
|
|
||||||
// SkipWalker will walk the Walker and call the WalkFunc for files who's directories
|
|
||||||
// do no match any of the skipPrefixes. If no skipPrefixes are passed, then
|
|
||||||
// CommonSkipPrefixes is used
|
|
||||||
func SkipWalker(walker Walker, skipPrefixes []string, wf WalkFunc) error {
|
|
||||||
if len(skipPrefixes) == 0 {
|
|
||||||
skipPrefixes = append(skipPrefixes, CommonSkipPrefixes...)
|
|
||||||
}
|
|
||||||
return walker.Walk(func(path string, file File) error {
|
|
||||||
fi, err := file.FileInfo()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
path = strings.Replace(path, "\\", "/", -1)
|
|
||||||
|
|
||||||
parts := strings.Split(path, "/")
|
|
||||||
if !fi.IsDir() {
|
|
||||||
parts = parts[:len(parts)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, base := range parts {
|
|
||||||
if base != "." {
|
|
||||||
for _, skip := range skipPrefixes {
|
|
||||||
skip = strings.ToLower(skip)
|
|
||||||
lbase := strings.ToLower(base)
|
|
||||||
if strings.HasPrefix(lbase, skip) {
|
|
||||||
return filepath.SkipDir
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return wf(path, file)
|
|
||||||
})
|
|
||||||
}
|
|
4
vendor/github.com/gobuffalo/packd/version.go
generated
vendored
4
vendor/github.com/gobuffalo/packd/version.go
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
package packd
|
|
||||||
|
|
||||||
// Version of packd
|
|
||||||
const Version = "v0.3.0"
|
|
3
vendor/github.com/gobuffalo/packr/v2/.gometalinter.json
generated
vendored
3
vendor/github.com/gobuffalo/packr/v2/.gometalinter.json
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"Enable": ["vet", "golint", "goimports", "deadcode", "gotype", "ineffassign", "misspell", "nakedret", "unconvert", "megacheck", "varcheck"]
|
|
||||||
}
|
|
42
vendor/github.com/gobuffalo/packr/v2/.goreleaser.yml
generated
vendored
42
vendor/github.com/gobuffalo/packr/v2/.goreleaser.yml
generated
vendored
@ -1,42 +0,0 @@
|
|||||||
# Code generated by github.com/gobuffalo/release. DO NOT EDIT.
|
|
||||||
# Edit .goreleaser.yml.plush instead
|
|
||||||
|
|
||||||
builds:
|
|
||||||
-
|
|
||||||
goos:
|
|
||||||
- darwin
|
|
||||||
- linux
|
|
||||||
- windows
|
|
||||||
goarch:
|
|
||||||
- ppc64le
|
|
||||||
- 386
|
|
||||||
- amd64
|
|
||||||
env:
|
|
||||||
- CGO_ENABLED=0
|
|
||||||
ignore:
|
|
||||||
- goos: darwin
|
|
||||||
goarch: ppc64le
|
|
||||||
- goos: windows
|
|
||||||
goarch: ppc64le
|
|
||||||
main: ./packr2/main.go
|
|
||||||
binary: packr2
|
|
||||||
|
|
||||||
checksum:
|
|
||||||
name_template: 'checksums.txt'
|
|
||||||
|
|
||||||
snapshot:
|
|
||||||
name_template: "{{ .Tag }}-next"
|
|
||||||
|
|
||||||
changelog:
|
|
||||||
sort: asc
|
|
||||||
filters:
|
|
||||||
exclude:
|
|
||||||
- '^docs:'
|
|
||||||
- '^test:'
|
|
||||||
|
|
||||||
brews:
|
|
||||||
-
|
|
||||||
github:
|
|
||||||
owner: gobuffalo
|
|
||||||
name: homebrew-tap
|
|
||||||
|
|
39
vendor/github.com/gobuffalo/packr/v2/.goreleaser.yml.plush
generated
vendored
39
vendor/github.com/gobuffalo/packr/v2/.goreleaser.yml.plush
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
builds:
|
|
||||||
-
|
|
||||||
goos:
|
|
||||||
- darwin
|
|
||||||
- linux
|
|
||||||
- windows
|
|
||||||
goarch:
|
|
||||||
- ppc64le
|
|
||||||
- 386
|
|
||||||
- amd64
|
|
||||||
env:
|
|
||||||
- CGO_ENABLED=0
|
|
||||||
ignore:
|
|
||||||
- goos: darwin
|
|
||||||
goarch: ppc64le
|
|
||||||
- goos: windows
|
|
||||||
goarch: ppc64le
|
|
||||||
main: ./packr2/main.go
|
|
||||||
binary: packr2
|
|
||||||
|
|
||||||
checksum:
|
|
||||||
name_template: 'checksums.txt'
|
|
||||||
|
|
||||||
snapshot:
|
|
||||||
name_template: "{{ .Tag }}-next"
|
|
||||||
|
|
||||||
changelog:
|
|
||||||
sort: asc
|
|
||||||
filters:
|
|
||||||
exclude:
|
|
||||||
- '^docs:'
|
|
||||||
- '^test:'
|
|
||||||
<%= if (brew) { %>
|
|
||||||
brews:
|
|
||||||
-
|
|
||||||
github:
|
|
||||||
owner: gobuffalo
|
|
||||||
name: homebrew-tap
|
|
||||||
<% } %>
|
|
8
vendor/github.com/gobuffalo/packr/v2/LICENSE.txt
generated
vendored
8
vendor/github.com/gobuffalo/packr/v2/LICENSE.txt
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
Copyright (c) 2016 Mark Bates
|
|
||||||
|
|
||||||
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.
|
|
46
vendor/github.com/gobuffalo/packr/v2/Makefile
generated
vendored
46
vendor/github.com/gobuffalo/packr/v2/Makefile
generated
vendored
@ -1,46 +0,0 @@
|
|||||||
TAGS ?= "sqlite"
|
|
||||||
GO_BIN ?= go
|
|
||||||
|
|
||||||
install: deps
|
|
||||||
echo "installing packr v2"
|
|
||||||
packr2
|
|
||||||
$(GO_BIN) install -v ./packr2
|
|
||||||
|
|
||||||
tidy:
|
|
||||||
ifeq ($(GO111MODULE),on)
|
|
||||||
$(GO_BIN) mod tidy
|
|
||||||
else
|
|
||||||
echo skipping go mod tidy
|
|
||||||
endif
|
|
||||||
|
|
||||||
deps:
|
|
||||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
|
||||||
$(GO_BIN) install -v ./packr2
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
build: deps
|
|
||||||
packr2
|
|
||||||
$(GO_BIN) build -v ./packr2
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
test:
|
|
||||||
packr2
|
|
||||||
$(GO_BIN) test -tags ${TAGS} ./...
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
lint:
|
|
||||||
gometalinter --vendor ./... --deadline=1m --skip=internal
|
|
||||||
|
|
||||||
update:
|
|
||||||
$(GO_BIN) get -u -tags ${TAGS} ./...
|
|
||||||
make tidy
|
|
||||||
make install
|
|
||||||
make test
|
|
||||||
make tidy
|
|
||||||
|
|
||||||
release-test:
|
|
||||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
|
||||||
|
|
||||||
release:
|
|
||||||
release -y -f version.go
|
|
||||||
make tidy
|
|
239
vendor/github.com/gobuffalo/packr/v2/README.md
generated
vendored
239
vendor/github.com/gobuffalo/packr/v2/README.md
generated
vendored
@ -1,239 +0,0 @@
|
|||||||
**NOTICE: Please consider migrating your projects to github.com/markbates/pkger. It has an idiomatic API, minimal dependencies, a stronger test suite (tested directly against the std lib counterparts), transparent tooling, and more.**
|
|
||||||
|
|
||||||
https://blog.gobuffalo.io/introducing-pkger-static-file-embedding-in-go-1ce76dc79c65
|
|
||||||
|
|
||||||
# Packr (v2)
|
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/gobuffalo/packr/v2?status.svg)](https://godoc.org/github.com/gobuffalo/packr/v2)
|
|
||||||
|
|
||||||
Packr is a simple solution for bundling static assets inside of Go binaries. Most importantly it does it in a way that is friendly to developers while they are developing.
|
|
||||||
|
|
||||||
## Intro Video
|
|
||||||
|
|
||||||
To get an idea of the what and why of Packr, please enjoy this short video: [https://vimeo.com/219863271](https://vimeo.com/219863271).
|
|
||||||
|
|
||||||
## Library Installation
|
|
||||||
|
|
||||||
```text
|
|
||||||
$ go get -u github.com/gobuffalo/packr/v2/...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Binary Installation
|
|
||||||
|
|
||||||
```text
|
|
||||||
$ go get -u github.com/gobuffalo/packr/v2/packr2
|
|
||||||
```
|
|
||||||
|
|
||||||
## New File Format FAQs
|
|
||||||
|
|
||||||
In version `v2.0.0` the file format changed and is not backward compatible with the `packr-v1.x` library.
|
|
||||||
|
|
||||||
#### Can `packr-v1.x` read the new format?
|
|
||||||
|
|
||||||
No, it can not. Because of the way the new file format works porting it to `packr-v1.x` would be difficult. PRs are welcome though. :)
|
|
||||||
|
|
||||||
#### Can `packr-v2.x` read `packr-v1.x` files?
|
|
||||||
|
|
||||||
Yes it can, but that ability will eventually be phased out. Because of that we recommend moving to the new format.
|
|
||||||
|
|
||||||
#### Can `packr-v2.x` generate `packr-v1.x` files?
|
|
||||||
|
|
||||||
Yes it can, but that ability will eventually be phased out. Because of that we recommend moving to the new format.
|
|
||||||
|
|
||||||
The `--legacy` command is available on all commands that generate `-packr.go` files.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ packr2 --legacy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### In Code
|
|
||||||
|
|
||||||
The first step in using Packr is to create a new box. A box represents a folder on disk. Once you have a box you can get `string` or `[]byte` representations of the file.
|
|
||||||
|
|
||||||
```go
|
|
||||||
// set up a new box by giving it a name and an optional (relative) path to a folder on disk:
|
|
||||||
box := packr.New("My Box", "./templates")
|
|
||||||
|
|
||||||
// Get the string representation of a file, or an error if it doesn't exist:
|
|
||||||
html, err := box.FindString("index.html")
|
|
||||||
|
|
||||||
// Get the []byte representation of a file, or an error if it doesn't exist:
|
|
||||||
html, err := box.Find("index.html")
|
|
||||||
```
|
|
||||||
|
|
||||||
### What is a Box?
|
|
||||||
|
|
||||||
A box represents a folder, and any sub-folders, on disk that you want to have access to in your binary. When compiling a binary using the `packr2` CLI the contents of the folder will be converted into Go files that can be compiled inside of a "standard" go binary. Inside of the compiled binary the files will be read from memory. When working locally the files will be read directly off of disk. This is a seamless switch that doesn't require any special attention on your part.
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
|
||||||
Assume the follow directory structure:
|
|
||||||
|
|
||||||
```
|
|
||||||
├── main.go
|
|
||||||
└── templates
|
|
||||||
├── admin
|
|
||||||
│ └── index.html
|
|
||||||
└── index.html
|
|
||||||
```
|
|
||||||
|
|
||||||
The following program will read the `./templates/admin/index.html` file and print it out.
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
box := packr.New("myBox", "./templates")
|
|
||||||
|
|
||||||
s, err := box.FindString("admin/index.html")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
fmt.Println(s)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Development Made Easy
|
|
||||||
|
|
||||||
In order to get static files into a Go binary, those files must first be converted to Go code. To do that, Packr, ships with a few tools to help build binaries. See below.
|
|
||||||
|
|
||||||
During development, however, it is painful to have to keep running a tool to compile those files.
|
|
||||||
|
|
||||||
Packr uses the following resolution rules when looking for a file:
|
|
||||||
|
|
||||||
1. Look for the file in-memory (inside a Go binary)
|
|
||||||
1. Look for the file on disk (during development)
|
|
||||||
|
|
||||||
Because Packr knows how to fall through to the file system, developers don't need to worry about constantly compiling their static files into a binary. They can work unimpeded.
|
|
||||||
|
|
||||||
Packr takes file resolution a step further. When declaring a new box you use a relative path, `./templates`. When Packr receives this call it calculates out the absolute path to that directory. By doing this it means you can be guaranteed that Packr can find your files correctly, even if you're not running in the directory that the box was created in. This helps with the problem of testing, where Go changes the `pwd` for each package, making relative paths difficult to work with. This is not a problem when using Packr.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Usage with HTTP
|
|
||||||
|
|
||||||
A box implements the [`http.FileSystem`](https://golang.org/pkg/net/http/#FileSystem) interface, meaning it can be used to serve static files.
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
box := packr.New("someBoxName", "./templates")
|
|
||||||
|
|
||||||
http.Handle("/", http.FileServer(box))
|
|
||||||
http.ListenAndServe(":3000", nil)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Building a Binary
|
|
||||||
|
|
||||||
Before you build your Go binary, run the `packr2` command first. It will look for all the boxes in your code and then generate `.go` files that pack the static files into bytes that can be bundled into the Go binary.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ packr2
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run your `go build command` like normal.
|
|
||||||
|
|
||||||
*NOTE*: It is not recommended to check-in these generated `-packr.go` files. They can be large, and can easily become out of date if not careful. It is recommended that you always run `packr2 clean` after running the `packr2` tool.
|
|
||||||
|
|
||||||
#### Cleaning Up
|
|
||||||
|
|
||||||
When you're done it is recommended that you run the `packr2 clean` command. This will remove all of the generated files that Packr created for you.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ packr2 clean
|
|
||||||
```
|
|
||||||
|
|
||||||
Why do you want to do this? Packr first looks to the information stored in these generated files, if the information isn't there it looks to disk. This makes it easy to work with in development.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Debugging
|
|
||||||
|
|
||||||
The `packr2` command passes all arguments down to the underlying `go` command, this includes the `-v` flag to print out `go build` information. Packr looks for the `-v` flag, and will turn on its own verbose logging. This is very useful for trying to understand what the `packr` command is doing when it is run.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
### Compilation Errors with Go Templates
|
|
||||||
|
|
||||||
Q: I have a program with Go template files, those files are named `foo.go` and look like the following:
|
|
||||||
|
|
||||||
```
|
|
||||||
// Copyright {{.Year}} {{.Author}}. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package {{.Project}}
|
|
||||||
```
|
|
||||||
|
|
||||||
When I run `packr2` I get errors like:
|
|
||||||
|
|
||||||
```
|
|
||||||
expected 'IDENT', found '{'
|
|
||||||
```
|
|
||||||
|
|
||||||
A: Packr works by searching your `.go` files for [`github.com/gobuffalo/packr/v2#New`](https://godoc.org/github.com/gobuffalo/packr/v2#New) or [`github.com/gobuffalo/packr/v2#NewBox`](https://godoc.org/github.com/gobuffalo/packr/v2#NewBox) calls. Because those files aren't "proper" Go files, Packr can't parse them to find the box declarations. To fix this you need to tell Packr to ignore those files when searching for boxes. A couple solutions to this problem are:
|
|
||||||
|
|
||||||
* Name the files something else. The `.tmpl` extension is the idiomatic way of naming these types of files.
|
|
||||||
* Rename the folder containing these files to start with an `_`, for example `_templates`. Packr, like Go, will ignore folders starting with the `_` character when searching for boxes.
|
|
||||||
|
|
||||||
### Dynamic Box Paths
|
|
||||||
|
|
||||||
Q: I need to set the path of a box using a variable, but `packr.New("foo", myVar)` doesn't work correctly.
|
|
||||||
|
|
||||||
A: Packr attempts to "automagically" set it's resolution directory when using [`github.com/gobuffalo/packr/v2#New`](https://godoc.org/github.com/gobuffalo/packr/v2#New), however, for dynamic paths you need to set it manually:
|
|
||||||
|
|
||||||
```go
|
|
||||||
box := packr.New("foo", "|")
|
|
||||||
box.ResolutionDir = myVar
|
|
||||||
```
|
|
||||||
|
|
||||||
### I don't want to pack files, but still use the Packr interface.
|
|
||||||
|
|
||||||
Q: I want to write code that using the Packr tools, but doesn't actually pack the files into my binary. How can I do that?
|
|
||||||
|
|
||||||
A: Using [`github.com/gobuffalo/packr/v2#Folder`](https://godoc.org/github.com/gobuffalo/packr/v2#Folder) gives you back a `*packr.Box` that can be used as normal, but is excluded by the Packr tool when compiling.
|
|
||||||
|
|
||||||
### Packr Finds No Boxes
|
|
||||||
|
|
||||||
Q: I run `packr2 -v` but it doesn't find my boxes:
|
|
||||||
|
|
||||||
```
|
|
||||||
DEBU[2019-03-18T18:48:52+01:00] *parser.Parser#NewFromRoots found prospects=0
|
|
||||||
DEBU[2019-03-18T18:48:52+01:00] found 0 boxes
|
|
||||||
```
|
|
||||||
|
|
||||||
A: Packr works by parsing `.go` files to find [`github.com/gobuffalo/packr/v2#Box`](https://godoc.org/github.com/gobuffalo/packr/v2#Box) and [`github.com/gobuffalo/packr/v2#NewBox`](https://godoc.org/github.com/gobuffalo/packr/v2#NewBox) declarations. If there aren't any `.go` in the folder that `packr2` is run in it can not find those declarations. To fix this problem run the `packr2` command in the directory containing your `.go` files.
|
|
||||||
|
|
||||||
### Box Interfaces
|
|
||||||
|
|
||||||
Q: I want to be able to easily test my applications by passing in mock boxes. How do I do that?
|
|
||||||
|
|
||||||
A: Packr boxes and files conform to the interfaces found at [`github.com/gobuffalo/packd`](https://godoc.org/github.com/gobuffalo/packd). Change your application to use those interfaces instead of the concrete Packr types.
|
|
||||||
|
|
||||||
```go
|
|
||||||
// using concrete type
|
|
||||||
func myFunc(box *packr.Box) {}
|
|
||||||
|
|
||||||
// using interfaces
|
|
||||||
func myFunc(box packd.Box) {}
|
|
||||||
```
|
|
32
vendor/github.com/gobuffalo/packr/v2/SHOULDERS.md
generated
vendored
32
vendor/github.com/gobuffalo/packr/v2/SHOULDERS.md
generated
vendored
@ -1,32 +0,0 @@
|
|||||||
# /Users/smichalak/dev/packr/v2 Stands on the Shoulders of Giants
|
|
||||||
|
|
||||||
/Users/smichalak/dev/packr/v2 does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
|
||||||
|
|
||||||
Thank you to the following **GIANTS**:
|
|
||||||
|
|
||||||
|
|
||||||
* [github.com/gobuffalo/logger](https://godoc.org/github.com/gobuffalo/logger)
|
|
||||||
|
|
||||||
* [github.com/gobuffalo/packd](https://godoc.org/github.com/gobuffalo/packd)
|
|
||||||
|
|
||||||
* [github.com/karrick/godirwalk](https://godoc.org/github.com/karrick/godirwalk)
|
|
||||||
|
|
||||||
* [github.com/konsorten/go-windows-terminal-sequences](https://godoc.org/github.com/konsorten/go-windows-terminal-sequences)
|
|
||||||
|
|
||||||
* [github.com/markbates/errx](https://godoc.org/github.com/markbates/errx)
|
|
||||||
|
|
||||||
* [github.com/markbates/oncer](https://godoc.org/github.com/markbates/oncer)
|
|
||||||
|
|
||||||
* [github.com/markbates/safe](https://godoc.org/github.com/markbates/safe)
|
|
||||||
|
|
||||||
* [github.com/rogpeppe/go-internal](https://godoc.org/github.com/rogpeppe/go-internal)
|
|
||||||
|
|
||||||
* [github.com/sirupsen/logrus](https://godoc.org/github.com/sirupsen/logrus)
|
|
||||||
|
|
||||||
* [github.com/spf13/cobra](https://godoc.org/github.com/spf13/cobra)
|
|
||||||
|
|
||||||
* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify)
|
|
||||||
|
|
||||||
* [golang.org/x/sync](https://godoc.org/golang.org/x/sync)
|
|
||||||
|
|
||||||
* [golang.org/x/tools](https://godoc.org/golang.org/x/tools)
|
|
240
vendor/github.com/gobuffalo/packr/v2/box.go
generated
vendored
240
vendor/github.com/gobuffalo/packr/v2/box.go
generated
vendored
@ -1,240 +0,0 @@
|
|||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packd"
|
|
||||||
"github.com/gobuffalo/packr/v2/file"
|
|
||||||
"github.com/gobuffalo/packr/v2/file/resolver"
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
"github.com/markbates/oncer"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ packd.Box = &Box{}
|
|
||||||
var _ packd.HTTPBox = &Box{}
|
|
||||||
var _ packd.Addable = &Box{}
|
|
||||||
var _ packd.Walkable = &Box{}
|
|
||||||
var _ packd.Finder = &Box{}
|
|
||||||
|
|
||||||
// Box represent a folder on a disk you want to
|
|
||||||
// have access to in the built Go binary.
|
|
||||||
type Box struct {
|
|
||||||
Path string `json:"path"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
ResolutionDir string `json:"resolution_dir"`
|
|
||||||
DefaultResolver resolver.Resolver `json:"default_resolver"`
|
|
||||||
resolvers resolversMap
|
|
||||||
dirs dirsMap
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBox returns a Box that can be used to
|
|
||||||
// retrieve files from either disk or the embedded
|
|
||||||
// binary.
|
|
||||||
// Deprecated: Use New instead.
|
|
||||||
func NewBox(path string) *Box {
|
|
||||||
oncer.Deprecate(0, "packr.NewBox", "Use packr.New instead.")
|
|
||||||
return New(path, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a new Box with the name of the box
|
|
||||||
// and the path of the box.
|
|
||||||
func New(name string, path string) *Box {
|
|
||||||
plog.Debug("packr", "New", "name", name, "path", path)
|
|
||||||
b, _ := findBox(name)
|
|
||||||
if b != nil {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
b = construct(name, path)
|
|
||||||
plog.Debug(b, "New", "Box", b, "ResolutionDir", b.ResolutionDir)
|
|
||||||
b, err := placeBox(b)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Folder returns a Box that will NOT be packed.
|
|
||||||
// This is useful for writing tests or tools that
|
|
||||||
// need to work with a folder at runtime.
|
|
||||||
func Folder(path string) *Box {
|
|
||||||
return New(path, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetResolver allows for the use of a custom resolver for
|
|
||||||
// the specified file
|
|
||||||
func (b *Box) SetResolver(file string, res resolver.Resolver) {
|
|
||||||
d := filepath.Dir(file)
|
|
||||||
b.dirs.Store(d, true)
|
|
||||||
plog.Debug(b, "SetResolver", "file", file, "resolver", fmt.Sprintf("%T", res))
|
|
||||||
b.resolvers.Store(resolver.Key(file), res)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddString converts t to a byteslice and delegates to AddBytes to add to b.data
|
|
||||||
func (b *Box) AddString(path string, t string) error {
|
|
||||||
return b.AddBytes(path, []byte(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddBytes sets t in b.data by the given path
|
|
||||||
func (b *Box) AddBytes(path string, t []byte) error {
|
|
||||||
m := map[string]file.File{}
|
|
||||||
f, err := file.NewFile(path, t)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m[resolver.Key(path)] = f
|
|
||||||
res := resolver.NewInMemory(m)
|
|
||||||
b.SetResolver(path, res)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindString returns either the string of the requested
|
|
||||||
// file or an error if it can not be found.
|
|
||||||
func (b *Box) FindString(name string) (string, error) {
|
|
||||||
bb, err := b.Find(name)
|
|
||||||
return string(bb), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find returns either the byte slice of the requested
|
|
||||||
// file or an error if it can not be found.
|
|
||||||
func (b *Box) Find(name string) ([]byte, error) {
|
|
||||||
f, err := b.Resolve(name)
|
|
||||||
if err != nil {
|
|
||||||
return []byte(""), err
|
|
||||||
}
|
|
||||||
bb := &bytes.Buffer{}
|
|
||||||
io.Copy(bb, f)
|
|
||||||
return bb.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has returns true if the resource exists in the box
|
|
||||||
func (b *Box) Has(name string) bool {
|
|
||||||
_, err := b.Find(name)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasDir returns true if the directory exists in the box
|
|
||||||
func (b *Box) HasDir(name string) bool {
|
|
||||||
oncer.Do("packr2/box/HasDir"+b.Name, func() {
|
|
||||||
for _, f := range b.List() {
|
|
||||||
for d := filepath.Dir(f); d != "."; d = filepath.Dir(d) {
|
|
||||||
b.dirs.Store(d, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if name == "/" {
|
|
||||||
return b.Has("index.html")
|
|
||||||
}
|
|
||||||
_, ok := b.dirs.Load(name)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open returns a File using the http.File interface
|
|
||||||
func (b *Box) Open(name string) (http.File, error) {
|
|
||||||
plog.Debug(b, "Open", "name", name)
|
|
||||||
f, err := b.Resolve(name)
|
|
||||||
if err != nil {
|
|
||||||
if len(filepath.Ext(name)) == 0 {
|
|
||||||
return b.openWoExt(name)
|
|
||||||
}
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
f, err = file.NewFileR(name, f)
|
|
||||||
plog.Debug(b, "Open", "name", f.Name(), "file", f.Name())
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Box) openWoExt(name string) (http.File, error) {
|
|
||||||
if !b.HasDir(name) {
|
|
||||||
id := path.Join(name, "index.html")
|
|
||||||
if b.Has(id) {
|
|
||||||
return b.Open(id)
|
|
||||||
}
|
|
||||||
return nil, os.ErrNotExist
|
|
||||||
}
|
|
||||||
d, err := file.NewDir(name)
|
|
||||||
plog.Debug(b, "Open", "name", name, "dir", d)
|
|
||||||
return d, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// List shows "What's in the box?"
|
|
||||||
func (b *Box) List() []string {
|
|
||||||
var keys []string
|
|
||||||
|
|
||||||
b.Walk(func(path string, info File) error {
|
|
||||||
if info == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
finfo, _ := info.FileInfo()
|
|
||||||
if !finfo.IsDir() {
|
|
||||||
keys = append(keys, path)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
sort.Strings(keys)
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve will attempt to find the file in the box,
|
|
||||||
// returning an error if the find can not be found.
|
|
||||||
func (b *Box) Resolve(key string) (file.File, error) {
|
|
||||||
key = strings.TrimPrefix(key, "/")
|
|
||||||
|
|
||||||
var r resolver.Resolver
|
|
||||||
|
|
||||||
b.resolvers.Range(func(k string, vr resolver.Resolver) bool {
|
|
||||||
lk := strings.ToLower(resolver.Key(k))
|
|
||||||
lkey := strings.ToLower(resolver.Key(key))
|
|
||||||
if lk == lkey {
|
|
||||||
r = vr
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
if r == nil {
|
|
||||||
r = b.DefaultResolver
|
|
||||||
if r == nil {
|
|
||||||
r = resolver.DefaultResolver
|
|
||||||
if r == nil {
|
|
||||||
return nil, fmt.Errorf("resolver.DefaultResolver is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
plog.Debug(r, "Resolve", "box", b.Name, "key", key)
|
|
||||||
|
|
||||||
f, err := r.Resolve(b.Name, key)
|
|
||||||
if err != nil {
|
|
||||||
z, err := resolver.ResolvePathInBase(resolver.OsPath(b.ResolutionDir), filepath.FromSlash(path.Clean("/"+resolver.OsPath(key))))
|
|
||||||
if err != nil {
|
|
||||||
plog.Debug(r, "Resolve", "box", b.Name, "key", key, "err", err)
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err = r.Resolve(b.Name, z)
|
|
||||||
if err != nil {
|
|
||||||
plog.Debug(r, "Resolve", "box", b.Name, "key", z, "err", err)
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
b, err := ioutil.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
f, err = file.NewFile(key, b)
|
|
||||||
if err != nil {
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
plog.Debug(r, "Resolve", "box", b.Name, "key", key, "file", f.Name())
|
|
||||||
return f, nil
|
|
||||||
}
|
|
73
vendor/github.com/gobuffalo/packr/v2/box_map.go
generated
vendored
73
vendor/github.com/gobuffalo/packr/v2/box_map.go
generated
vendored
@ -1,73 +0,0 @@
|
|||||||
//go:generate mapgen -name "box" -zero "nil" -go-type "*Box" -pkg "" -a "New(`test-a`, ``)" -b "New(`test-b`, ``)" -c "New(`test-c`, ``)" -bb "New(`test-bb`, ``)" -destination "packr"
|
|
||||||
// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// boxMap wraps sync.Map and uses the following types:
|
|
||||||
// key: string
|
|
||||||
// value: *Box
|
|
||||||
type boxMap struct {
|
|
||||||
data sync.Map
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the key from the map
|
|
||||||
func (m *boxMap) Delete(key string) {
|
|
||||||
m.data.Delete(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the key from the map.
|
|
||||||
// Returns *Box or bool.
|
|
||||||
// A false return indicates either the key was not found
|
|
||||||
// or the value is not of type *Box
|
|
||||||
func (m *boxMap) Load(key string) (*Box, bool) {
|
|
||||||
i, ok := m.data.Load(key)
|
|
||||||
if !ok {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
s, ok := i.(*Box)
|
|
||||||
return s, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadOrStore will return an existing key or
|
|
||||||
// store the value if not already in the map
|
|
||||||
func (m *boxMap) LoadOrStore(key string, value *Box) (*Box, bool) {
|
|
||||||
i, _ := m.data.LoadOrStore(key, value)
|
|
||||||
s, ok := i.(*Box)
|
|
||||||
return s, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Range over the *Box values in the map
|
|
||||||
func (m *boxMap) Range(f func(key string, value *Box) bool) {
|
|
||||||
m.data.Range(func(k, v interface{}) bool {
|
|
||||||
key, ok := k.(string)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
value, ok := v.(*Box)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return f(key, value)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store a *Box in the map
|
|
||||||
func (m *boxMap) Store(key string, value *Box) {
|
|
||||||
m.data.Store(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys returns a list of keys in the map
|
|
||||||
func (m *boxMap) Keys() []string {
|
|
||||||
var keys []string
|
|
||||||
m.Range(func(key string, value *Box) bool {
|
|
||||||
keys = append(keys, key)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
sort.Strings(keys)
|
|
||||||
return keys
|
|
||||||
}
|
|
79
vendor/github.com/gobuffalo/packr/v2/deprecated.go
generated
vendored
79
vendor/github.com/gobuffalo/packr/v2/deprecated.go
generated
vendored
@ -1,79 +0,0 @@
|
|||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/file"
|
|
||||||
"github.com/gobuffalo/packr/v2/file/resolver"
|
|
||||||
"github.com/markbates/oncer"
|
|
||||||
)
|
|
||||||
|
|
||||||
// File has been deprecated and file.File should be used instead
|
|
||||||
type File = file.File
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrResOutsideBox gets returned in case of the requested resources being outside the box
|
|
||||||
// Deprecated
|
|
||||||
ErrResOutsideBox = fmt.Errorf("can't find a resource outside the box")
|
|
||||||
)
|
|
||||||
|
|
||||||
// PackBytes packs bytes for a file into a box.
|
|
||||||
// Deprecated
|
|
||||||
func PackBytes(box string, name string, bb []byte) {
|
|
||||||
b := NewBox(box)
|
|
||||||
d := resolver.NewInMemory(map[string]file.File{})
|
|
||||||
f, err := file.NewFile(name, bb)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if err := d.Pack(name, f); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
b.SetResolver(name, d)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PackBytesGzip packets the gzipped compressed bytes into a box.
|
|
||||||
// Deprecated
|
|
||||||
func PackBytesGzip(box string, name string, bb []byte) error {
|
|
||||||
// TODO: this function never did what it was supposed to do!
|
|
||||||
PackBytes(box, name, bb)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PackJSONBytes packs JSON encoded bytes for a file into a box.
|
|
||||||
// Deprecated
|
|
||||||
func PackJSONBytes(box string, name string, jbb string) error {
|
|
||||||
var bb []byte
|
|
||||||
err := json.Unmarshal([]byte(jbb), &bb)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
PackBytes(box, name, bb)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes is deprecated. Use Find instead
|
|
||||||
func (b *Box) Bytes(name string) []byte {
|
|
||||||
bb, _ := b.Find(name)
|
|
||||||
oncer.Deprecate(0, "github.com/gobuffalo/packr/v2#Box.Bytes", "Use github.com/gobuffalo/packr/v2#Box.Find instead.")
|
|
||||||
return bb
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustBytes is deprecated. Use Find instead.
|
|
||||||
func (b *Box) MustBytes(name string) ([]byte, error) {
|
|
||||||
oncer.Deprecate(0, "github.com/gobuffalo/packr/v2#Box.MustBytes", "Use github.com/gobuffalo/packr/v2#Box.Find instead.")
|
|
||||||
return b.Find(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String is deprecated. Use FindString instead
|
|
||||||
func (b *Box) String(name string) string {
|
|
||||||
oncer.Deprecate(0, "github.com/gobuffalo/packr/v2#Box.String", "Use github.com/gobuffalo/packr/v2#Box.FindString instead.")
|
|
||||||
return string(b.Bytes(name))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustString is deprecated. Use FindString instead
|
|
||||||
func (b *Box) MustString(name string) (string, error) {
|
|
||||||
oncer.Deprecate(0, "github.com/gobuffalo/packr/v2#Box.MustString", "Use github.com/gobuffalo/packr/v2#Box.FindString instead.")
|
|
||||||
return b.FindString(name)
|
|
||||||
}
|
|
82
vendor/github.com/gobuffalo/packr/v2/dirs_map.go
generated
vendored
82
vendor/github.com/gobuffalo/packr/v2/dirs_map.go
generated
vendored
@ -1,82 +0,0 @@
|
|||||||
//go:generate mapgen -name "dirs" -zero "false" -go-type "bool" -pkg "" -a "nil" -b "nil" -c "nil" -bb "nil" -destination "packr"
|
|
||||||
// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// dirsMap wraps sync.Map and uses the following types:
|
|
||||||
// key: string
|
|
||||||
// value: bool
|
|
||||||
type dirsMap struct {
|
|
||||||
data sync.Map
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the key from the map
|
|
||||||
func (m *dirsMap) Delete(key string) {
|
|
||||||
m.data.Delete(m.normalizeKey(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the key from the map.
|
|
||||||
// Returns bool or bool.
|
|
||||||
// A false return indicates either the key was not found
|
|
||||||
// or the value is not of type bool
|
|
||||||
func (m *dirsMap) Load(key string) (bool, bool) {
|
|
||||||
i, ok := m.data.Load(m.normalizeKey(key))
|
|
||||||
if !ok {
|
|
||||||
return false, false
|
|
||||||
}
|
|
||||||
s, ok := i.(bool)
|
|
||||||
return s, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadOrStore will return an existing key or
|
|
||||||
// store the value if not already in the map
|
|
||||||
func (m *dirsMap) LoadOrStore(key string, value bool) (bool, bool) {
|
|
||||||
i, _ := m.data.LoadOrStore(m.normalizeKey(key), value)
|
|
||||||
s, ok := i.(bool)
|
|
||||||
return s, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Range over the bool values in the map
|
|
||||||
func (m *dirsMap) Range(f func(key string, value bool) bool) {
|
|
||||||
m.data.Range(func(k, v interface{}) bool {
|
|
||||||
key, ok := k.(string)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
value, ok := v.(bool)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return f(key, value)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store a bool in the map
|
|
||||||
func (m *dirsMap) Store(key string, value bool) {
|
|
||||||
d := m.normalizeKey(key)
|
|
||||||
m.data.Store(d, value)
|
|
||||||
m.data.Store(strings.TrimPrefix(d, "/"), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys returns a list of keys in the map
|
|
||||||
func (m *dirsMap) Keys() []string {
|
|
||||||
var keys []string
|
|
||||||
m.Range(func(key string, value bool) bool {
|
|
||||||
keys = append(keys, key)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
sort.Strings(keys)
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *dirsMap) normalizeKey(key string) string {
|
|
||||||
key = strings.Replace(key, "\\", "/", -1)
|
|
||||||
|
|
||||||
return key
|
|
||||||
}
|
|
32
vendor/github.com/gobuffalo/packr/v2/file/file.go
generated
vendored
32
vendor/github.com/gobuffalo/packr/v2/file/file.go
generated
vendored
@ -1,32 +0,0 @@
|
|||||||
package file
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packd"
|
|
||||||
)
|
|
||||||
|
|
||||||
// File represents a virtual, or physical, backing of
|
|
||||||
// a file object in a Box
|
|
||||||
type File = packd.File
|
|
||||||
|
|
||||||
// FileMappable types are capable of returning a map of
|
|
||||||
// path => File
|
|
||||||
type FileMappable interface {
|
|
||||||
FileMap() map[string]File
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFile returns a virtual File implementation
|
|
||||||
func NewFile(name string, b []byte) (File, error) {
|
|
||||||
return packd.NewFile(name, bytes.NewReader(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDir returns a virtual dir implementation
|
|
||||||
func NewDir(name string) (File, error) {
|
|
||||||
return packd.NewDir(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFileR(name string, r io.Reader) (File, error) {
|
|
||||||
return packd.NewFile(name, r)
|
|
||||||
}
|
|
38
vendor/github.com/gobuffalo/packr/v2/file/info.go
generated
vendored
38
vendor/github.com/gobuffalo/packr/v2/file/info.go
generated
vendored
@ -1,38 +0,0 @@
|
|||||||
package file
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type info struct {
|
|
||||||
Path string
|
|
||||||
Contents []byte
|
|
||||||
size int64
|
|
||||||
modTime time.Time
|
|
||||||
isDir bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f info) Name() string {
|
|
||||||
return f.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f info) Size() int64 {
|
|
||||||
return f.size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f info) Mode() os.FileMode {
|
|
||||||
return 0444
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f info) ModTime() time.Time {
|
|
||||||
return f.modTime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f info) IsDir() bool {
|
|
||||||
return f.isDir
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f info) Sys() interface{} {
|
|
||||||
return nil
|
|
||||||
}
|
|
111
vendor/github.com/gobuffalo/packr/v2/file/resolver/disk.go
generated
vendored
111
vendor/github.com/gobuffalo/packr/v2/file/resolver/disk.go
generated
vendored
@ -1,111 +0,0 @@
|
|||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/file"
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
"github.com/karrick/godirwalk"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ Resolver = &Disk{}
|
|
||||||
|
|
||||||
type Disk struct {
|
|
||||||
Root string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d Disk) String() string {
|
|
||||||
return String(&d)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Disk) Resolve(box string, name string) (file.File, error) {
|
|
||||||
var err error
|
|
||||||
path := OsPath(name)
|
|
||||||
if !filepath.IsAbs(path) {
|
|
||||||
path, err = ResolvePathInBase(OsPath(d.Root), path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fi, err := os.Stat(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fi.IsDir() {
|
|
||||||
return nil, os.ErrNotExist
|
|
||||||
}
|
|
||||||
if bb, err := ioutil.ReadFile(path); err == nil {
|
|
||||||
return file.NewFile(OsPath(name), bb)
|
|
||||||
}
|
|
||||||
return nil, os.ErrNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolvePathInBase returns a path that is guaranteed to be inside of the base directory or an error
|
|
||||||
func ResolvePathInBase(base, path string) (string, error) {
|
|
||||||
// Determine the absolute file path of the base directory
|
|
||||||
d, err := filepath.Abs(base)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the base directory if no file was requested
|
|
||||||
if path == "/" || path == "\\" {
|
|
||||||
return d, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve the absolute file path after combining the key with base
|
|
||||||
p, err := filepath.Abs(filepath.Join(d, path))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that the resolved path is inside of the base directory
|
|
||||||
if !strings.HasPrefix(p, d+string(filepath.Separator)) {
|
|
||||||
return "", os.ErrNotExist
|
|
||||||
}
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ file.FileMappable = &Disk{}
|
|
||||||
|
|
||||||
func (d *Disk) FileMap() map[string]file.File {
|
|
||||||
moot := &sync.Mutex{}
|
|
||||||
m := map[string]file.File{}
|
|
||||||
root := OsPath(d.Root)
|
|
||||||
if _, err := os.Stat(root); err != nil {
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
callback := func(path string, de *godirwalk.Dirent) error {
|
|
||||||
if _, err := os.Stat(root); err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if !de.IsRegular() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
moot.Lock()
|
|
||||||
name := strings.TrimPrefix(path, root+string(filepath.Separator))
|
|
||||||
b, err := ioutil.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m[name], err = file.NewFile(name, b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
moot.Unlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err := godirwalk.Walk(root, &godirwalk.Options{
|
|
||||||
FollowSymbolicLinks: true,
|
|
||||||
Callback: callback,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
plog.Logger.Errorf("[%s] error walking %v", root, err)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
314
vendor/github.com/gobuffalo/packr/v2/file/resolver/encoding/hex/hex.go
generated
vendored
314
vendor/github.com/gobuffalo/packr/v2/file/resolver/encoding/hex/hex.go
generated
vendored
@ -1,314 +0,0 @@
|
|||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package hex implements hexadecimal encoding and decoding.
|
|
||||||
package hex
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
const hextable = "0123456789abcdef"
|
|
||||||
|
|
||||||
// EncodedLen returns the length of an encoding of n source bytes.
|
|
||||||
// Specifically, it returns n * 2.
|
|
||||||
func EncodedLen(n int) int { return n * 2 }
|
|
||||||
|
|
||||||
// Encode encodes src into EncodedLen(len(src))
|
|
||||||
// bytes of dst. As a convenience, it returns the number
|
|
||||||
// of bytes written to dst, but this value is always EncodedLen(len(src)).
|
|
||||||
// Encode implements hexadecimal encoding.
|
|
||||||
func Encode(dst, src []byte) int {
|
|
||||||
for i, v := range src {
|
|
||||||
dst[i*2] = hextable[v>>4]
|
|
||||||
dst[i*2+1] = hextable[v&0x0f]
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(src) * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrLength reports an attempt to decode an odd-length input
|
|
||||||
// using Decode or DecodeString.
|
|
||||||
// The stream-based Decoder returns io.ErrUnexpectedEOF instead of ErrLength.
|
|
||||||
var ErrLength = fmt.Errorf("encoding/hex: odd length hex string")
|
|
||||||
|
|
||||||
// InvalidByteError values describe errors resulting from an invalid byte in a hex string.
|
|
||||||
type InvalidByteError byte
|
|
||||||
|
|
||||||
func (e InvalidByteError) Error() string {
|
|
||||||
return fmt.Sprintf("encoding/hex: invalid byte: %#U", rune(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodedLen returns the length of a decoding of x source bytes.
|
|
||||||
// Specifically, it returns x / 2.
|
|
||||||
func DecodedLen(x int) int { return x / 2 }
|
|
||||||
|
|
||||||
// Decode decodes src into DecodedLen(len(src)) bytes,
|
|
||||||
// returning the actual number of bytes written to dst.
|
|
||||||
//
|
|
||||||
// Decode expects that src contains only hexadecimal
|
|
||||||
// characters and that src has even length.
|
|
||||||
// If the input is malformed, Decode returns the number
|
|
||||||
// of bytes decoded before the error.
|
|
||||||
func Decode(dst, src []byte) (int, error) {
|
|
||||||
var i int
|
|
||||||
for i = 0; i < len(src)/2; i++ {
|
|
||||||
a, ok := fromHexChar(src[i*2])
|
|
||||||
if !ok {
|
|
||||||
return i, InvalidByteError(src[i*2])
|
|
||||||
}
|
|
||||||
b, ok := fromHexChar(src[i*2+1])
|
|
||||||
if !ok {
|
|
||||||
return i, InvalidByteError(src[i*2+1])
|
|
||||||
}
|
|
||||||
dst[i] = (a << 4) | b
|
|
||||||
}
|
|
||||||
if len(src)%2 == 1 {
|
|
||||||
// Check for invalid char before reporting bad length,
|
|
||||||
// since the invalid char (if present) is an earlier problem.
|
|
||||||
if _, ok := fromHexChar(src[i*2]); !ok {
|
|
||||||
return i, InvalidByteError(src[i*2])
|
|
||||||
}
|
|
||||||
return i, ErrLength
|
|
||||||
}
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// fromHexChar converts a hex character into its value and a success flag.
|
|
||||||
func fromHexChar(c byte) (byte, bool) {
|
|
||||||
switch {
|
|
||||||
case '0' <= c && c <= '9':
|
|
||||||
return c - '0', true
|
|
||||||
case 'a' <= c && c <= 'f':
|
|
||||||
return c - 'a' + 10, true
|
|
||||||
case 'A' <= c && c <= 'F':
|
|
||||||
return c - 'A' + 10, true
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeToString returns the hexadecimal encoding of src.
|
|
||||||
func EncodeToString(src []byte) string {
|
|
||||||
dst := make([]byte, EncodedLen(len(src)))
|
|
||||||
Encode(dst, src)
|
|
||||||
return string(dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeString returns the bytes represented by the hexadecimal string s.
|
|
||||||
//
|
|
||||||
// DecodeString expects that src contains only hexadecimal
|
|
||||||
// characters and that src has even length.
|
|
||||||
// If the input is malformed, DecodeString returns
|
|
||||||
// the bytes decoded before the error.
|
|
||||||
func DecodeString(s string) ([]byte, error) {
|
|
||||||
src := []byte(s)
|
|
||||||
// We can use the source slice itself as the destination
|
|
||||||
// because the decode loop increments by one and then the 'seen' byte is not used anymore.
|
|
||||||
n, err := Decode(src, src)
|
|
||||||
return src[:n], err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dump returns a string that contains a hex dump of the given data. The format
|
|
||||||
// of the hex dump matches the output of `hexdump -C` on the command line.
|
|
||||||
func Dump(data []byte) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
dumper := Dumper(&buf)
|
|
||||||
dumper.Write(data)
|
|
||||||
dumper.Close()
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// bufferSize is the number of hexadecimal characters to buffer in encoder and decoder.
|
|
||||||
const bufferSize = 1024
|
|
||||||
|
|
||||||
type encoder struct {
|
|
||||||
w io.Writer
|
|
||||||
err error
|
|
||||||
out [bufferSize]byte // output buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEncoder returns an io.Writer that writes lowercase hexadecimal characters to w.
|
|
||||||
func NewEncoder(w io.Writer) io.Writer {
|
|
||||||
return &encoder{w: w}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *encoder) Write(p []byte) (n int, err error) {
|
|
||||||
for len(p) > 0 && e.err == nil {
|
|
||||||
chunkSize := bufferSize / 2
|
|
||||||
if len(p) < chunkSize {
|
|
||||||
chunkSize = len(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
var written int
|
|
||||||
encoded := Encode(e.out[:], p[:chunkSize])
|
|
||||||
written, e.err = e.w.Write(e.out[:encoded])
|
|
||||||
n += written / 2
|
|
||||||
p = p[chunkSize:]
|
|
||||||
}
|
|
||||||
return n, e.err
|
|
||||||
}
|
|
||||||
|
|
||||||
type decoder struct {
|
|
||||||
r io.Reader
|
|
||||||
err error
|
|
||||||
in []byte // input buffer (encoded form)
|
|
||||||
arr [bufferSize]byte // backing array for in
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDecoder returns an io.Reader that decodes hexadecimal characters from r.
|
|
||||||
// NewDecoder expects that r contain only an even number of hexadecimal characters.
|
|
||||||
func NewDecoder(r io.Reader) io.Reader {
|
|
||||||
return &decoder{r: r}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *decoder) Read(p []byte) (n int, err error) {
|
|
||||||
// Fill internal buffer with sufficient bytes to decode
|
|
||||||
if len(d.in) < 2 && d.err == nil {
|
|
||||||
var numCopy, numRead int
|
|
||||||
numCopy = copy(d.arr[:], d.in) // Copies either 0 or 1 bytes
|
|
||||||
numRead, d.err = d.r.Read(d.arr[numCopy:])
|
|
||||||
d.in = d.arr[:numCopy+numRead]
|
|
||||||
if d.err == io.EOF && len(d.in)%2 != 0 {
|
|
||||||
if _, ok := fromHexChar(d.in[len(d.in)-1]); !ok {
|
|
||||||
d.err = InvalidByteError(d.in[len(d.in)-1])
|
|
||||||
} else {
|
|
||||||
d.err = io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode internal buffer into output buffer
|
|
||||||
if numAvail := len(d.in) / 2; len(p) > numAvail {
|
|
||||||
p = p[:numAvail]
|
|
||||||
}
|
|
||||||
numDec, err := Decode(p, d.in[:len(p)*2])
|
|
||||||
d.in = d.in[2*numDec:]
|
|
||||||
if err != nil {
|
|
||||||
d.in, d.err = nil, err // Decode error; discard input remainder
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(d.in) < 2 {
|
|
||||||
return numDec, d.err // Only expose errors when buffer fully consumed
|
|
||||||
}
|
|
||||||
return numDec, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dumper returns a WriteCloser that writes a hex dump of all written data to
|
|
||||||
// w. The format of the dump matches the output of `hexdump -C` on the command
|
|
||||||
// line.
|
|
||||||
func Dumper(w io.Writer) io.WriteCloser {
|
|
||||||
return &dumper{w: w}
|
|
||||||
}
|
|
||||||
|
|
||||||
type dumper struct {
|
|
||||||
w io.Writer
|
|
||||||
rightChars [18]byte
|
|
||||||
buf [14]byte
|
|
||||||
used int // number of bytes in the current line
|
|
||||||
n uint // number of bytes, total
|
|
||||||
closed bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func toChar(b byte) byte {
|
|
||||||
if b < 32 || b > 126 {
|
|
||||||
return '.'
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *dumper) Write(data []byte) (n int, err error) {
|
|
||||||
if h.closed {
|
|
||||||
return 0, fmt.Errorf("encoding/hex: dumper closed")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output lines look like:
|
|
||||||
// 00000010 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d |./0123456789:;<=|
|
|
||||||
// ^ offset ^ extra space ^ ASCII of line.
|
|
||||||
for i := range data {
|
|
||||||
if h.used == 0 {
|
|
||||||
// At the beginning of a line we print the current
|
|
||||||
// offset in hex.
|
|
||||||
h.buf[0] = byte(h.n >> 24)
|
|
||||||
h.buf[1] = byte(h.n >> 16)
|
|
||||||
h.buf[2] = byte(h.n >> 8)
|
|
||||||
h.buf[3] = byte(h.n)
|
|
||||||
Encode(h.buf[4:], h.buf[:4])
|
|
||||||
h.buf[12] = ' '
|
|
||||||
h.buf[13] = ' '
|
|
||||||
_, err = h.w.Write(h.buf[4:])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Encode(h.buf[:], data[i:i+1])
|
|
||||||
h.buf[2] = ' '
|
|
||||||
l := 3
|
|
||||||
if h.used == 7 {
|
|
||||||
// There's an additional space after the 8th byte.
|
|
||||||
h.buf[3] = ' '
|
|
||||||
l = 4
|
|
||||||
} else if h.used == 15 {
|
|
||||||
// At the end of the line there's an extra space and
|
|
||||||
// the bar for the right column.
|
|
||||||
h.buf[3] = ' '
|
|
||||||
h.buf[4] = '|'
|
|
||||||
l = 5
|
|
||||||
}
|
|
||||||
_, err = h.w.Write(h.buf[:l])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n++
|
|
||||||
h.rightChars[h.used] = toChar(data[i])
|
|
||||||
h.used++
|
|
||||||
h.n++
|
|
||||||
if h.used == 16 {
|
|
||||||
h.rightChars[16] = '|'
|
|
||||||
h.rightChars[17] = '\n'
|
|
||||||
_, err = h.w.Write(h.rightChars[:])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.used = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *dumper) Close() (err error) {
|
|
||||||
// See the comments in Write() for the details of this format.
|
|
||||||
if h.closed {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.closed = true
|
|
||||||
if h.used == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.buf[0] = ' '
|
|
||||||
h.buf[1] = ' '
|
|
||||||
h.buf[2] = ' '
|
|
||||||
h.buf[3] = ' '
|
|
||||||
h.buf[4] = '|'
|
|
||||||
nBytes := h.used
|
|
||||||
for h.used < 16 {
|
|
||||||
l := 3
|
|
||||||
if h.used == 7 {
|
|
||||||
l = 4
|
|
||||||
} else if h.used == 15 {
|
|
||||||
l = 5
|
|
||||||
}
|
|
||||||
_, err = h.w.Write(h.buf[:l])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.used++
|
|
||||||
}
|
|
||||||
h.rightChars[nBytes] = '|'
|
|
||||||
h.rightChars[nBytes+1] = '\n'
|
|
||||||
_, err = h.w.Write(h.rightChars[:nBytes+2])
|
|
||||||
return
|
|
||||||
}
|
|
112
vendor/github.com/gobuffalo/packr/v2/file/resolver/hex_gzip.go
generated
vendored
112
vendor/github.com/gobuffalo/packr/v2/file/resolver/hex_gzip.go
generated
vendored
@ -1,112 +0,0 @@
|
|||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/file/resolver/encoding/hex"
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ Resolver = &HexGzip{}
|
|
||||||
|
|
||||||
type HexGzip struct {
|
|
||||||
packed map[string]string
|
|
||||||
unpacked map[string]string
|
|
||||||
moot *sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hg HexGzip) String() string {
|
|
||||||
return String(&hg)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ file.FileMappable = &HexGzip{}
|
|
||||||
|
|
||||||
func (hg *HexGzip) FileMap() map[string]file.File {
|
|
||||||
hg.moot.RLock()
|
|
||||||
var names []string
|
|
||||||
for k := range hg.packed {
|
|
||||||
names = append(names, k)
|
|
||||||
}
|
|
||||||
hg.moot.RUnlock()
|
|
||||||
m := map[string]file.File{}
|
|
||||||
for _, n := range names {
|
|
||||||
if f, err := hg.Resolve("", n); err == nil {
|
|
||||||
m[n] = f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hg *HexGzip) Resolve(box string, name string) (file.File, error) {
|
|
||||||
plog.Debug(hg, "Resolve", "box", box, "name", name)
|
|
||||||
hg.moot.Lock()
|
|
||||||
defer hg.moot.Unlock()
|
|
||||||
|
|
||||||
if s, ok := hg.unpacked[name]; ok {
|
|
||||||
return file.NewFile(name, []byte(s))
|
|
||||||
}
|
|
||||||
packed, ok := hg.packed[name]
|
|
||||||
if !ok {
|
|
||||||
return nil, os.ErrNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
unpacked, err := UnHexGzipString(packed)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := file.NewFile(OsPath(name), []byte(unpacked))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hg.unpacked[name] = f.String()
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHexGzip(files map[string]string) (*HexGzip, error) {
|
|
||||||
if files == nil {
|
|
||||||
files = map[string]string{}
|
|
||||||
}
|
|
||||||
|
|
||||||
hg := &HexGzip{
|
|
||||||
packed: files,
|
|
||||||
unpacked: map[string]string{},
|
|
||||||
moot: &sync.RWMutex{},
|
|
||||||
}
|
|
||||||
|
|
||||||
return hg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func HexGzipString(s string) (string, error) {
|
|
||||||
bb := &bytes.Buffer{}
|
|
||||||
enc := hex.NewEncoder(bb)
|
|
||||||
zw := gzip.NewWriter(enc)
|
|
||||||
io.Copy(zw, strings.NewReader(s))
|
|
||||||
zw.Close()
|
|
||||||
|
|
||||||
return bb.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnHexGzipString(packed string) (string, error) {
|
|
||||||
br := bytes.NewBufferString(packed)
|
|
||||||
dec := hex.NewDecoder(br)
|
|
||||||
zr, err := gzip.NewReader(dec)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer zr.Close()
|
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(zr)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(b), nil
|
|
||||||
}
|
|
21
vendor/github.com/gobuffalo/packr/v2/file/resolver/ident.go
generated
vendored
21
vendor/github.com/gobuffalo/packr/v2/file/resolver/ident.go
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Key(s string) string {
|
|
||||||
s = strings.Replace(s, "\\", "/", -1)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func OsPath(s string) string {
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
s = strings.Replace(s, "/", string(filepath.Separator), -1)
|
|
||||||
} else {
|
|
||||||
s = strings.Replace(s, "\\", string(filepath.Separator), -1)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
63
vendor/github.com/gobuffalo/packr/v2/file/resolver/in_memory.go
generated
vendored
63
vendor/github.com/gobuffalo/packr/v2/file/resolver/in_memory.go
generated
vendored
@ -1,63 +0,0 @@
|
|||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packd"
|
|
||||||
"github.com/gobuffalo/packr/v2/file"
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ Resolver = &InMemory{}
|
|
||||||
|
|
||||||
type InMemory struct {
|
|
||||||
*packd.MemoryBox
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d InMemory) String() string {
|
|
||||||
return String(&d)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *InMemory) Resolve(box string, name string) (file.File, error) {
|
|
||||||
b, err := d.MemoryBox.Find(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return file.NewFile(name, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *InMemory) Pack(name string, f file.File) error {
|
|
||||||
plog.Debug(d, "Pack", "name", name)
|
|
||||||
b, err := ioutil.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.AddBytes(name, b)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *InMemory) FileMap() map[string]file.File {
|
|
||||||
m := map[string]file.File{}
|
|
||||||
d.Walk(func(path string, file file.File) error {
|
|
||||||
m[path] = file
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewInMemory(files map[string]file.File) *InMemory {
|
|
||||||
if files == nil {
|
|
||||||
files = map[string]file.File{}
|
|
||||||
}
|
|
||||||
box := packd.NewMemoryBox()
|
|
||||||
|
|
||||||
for p, f := range files {
|
|
||||||
if b, err := ioutil.ReadAll(f); err == nil {
|
|
||||||
box.AddBytes(p, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &InMemory{
|
|
||||||
MemoryBox: box,
|
|
||||||
}
|
|
||||||
}
|
|
7
vendor/github.com/gobuffalo/packr/v2/file/resolver/packable.go
generated
vendored
7
vendor/github.com/gobuffalo/packr/v2/file/resolver/packable.go
generated
vendored
@ -1,7 +0,0 @@
|
|||||||
package resolver
|
|
||||||
|
|
||||||
import "github.com/gobuffalo/packr/v2/file"
|
|
||||||
|
|
||||||
type Packable interface {
|
|
||||||
Pack(name string, f file.File) error
|
|
||||||
}
|
|
33
vendor/github.com/gobuffalo/packr/v2/file/resolver/resolver.go
generated
vendored
33
vendor/github.com/gobuffalo/packr/v2/file/resolver/resolver.go
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Resolver interface {
|
|
||||||
Resolve(string, string) (file.File, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultResolver() Resolver {
|
|
||||||
pwd, _ := os.Getwd()
|
|
||||||
return &Disk{
|
|
||||||
Root: pwd,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var DefaultResolver = defaultResolver()
|
|
||||||
|
|
||||||
func String(r Resolver) string {
|
|
||||||
m := map[string]interface{}{
|
|
||||||
"name": fmt.Sprintf("%T", r),
|
|
||||||
}
|
|
||||||
if fm, ok := r.(file.FileMappable); ok {
|
|
||||||
m["files"] = fm
|
|
||||||
}
|
|
||||||
b, _ := json.Marshal(m)
|
|
||||||
return string(b)
|
|
||||||
}
|
|
72
vendor/github.com/gobuffalo/packr/v2/helpers.go
generated
vendored
72
vendor/github.com/gobuffalo/packr/v2/helpers.go
generated
vendored
@ -1,72 +0,0 @@
|
|||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
)
|
|
||||||
|
|
||||||
func construct(name string, path string) *Box {
|
|
||||||
return &Box{
|
|
||||||
Path: path,
|
|
||||||
Name: name,
|
|
||||||
ResolutionDir: resolutionDir(path),
|
|
||||||
resolvers: resolversMap{},
|
|
||||||
dirs: dirsMap{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolutionDirTestFilename(filename, og string) (string, bool) {
|
|
||||||
ng := filepath.Join(filepath.Dir(filename), og)
|
|
||||||
|
|
||||||
// // this little hack courtesy of the `-cover` flag!!
|
|
||||||
cov := filepath.Join("_test", "_obj_test")
|
|
||||||
ng = strings.Replace(ng, string(filepath.Separator)+cov, "", 1)
|
|
||||||
|
|
||||||
if resolutionDirExists(ng, og) {
|
|
||||||
return ng, true
|
|
||||||
}
|
|
||||||
|
|
||||||
ng = filepath.Join(os.Getenv("GOPATH"), "src", ng)
|
|
||||||
if resolutionDirExists(ng, og) {
|
|
||||||
return ng, true
|
|
||||||
}
|
|
||||||
|
|
||||||
return og, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolutionDirExists(s, og string) bool {
|
|
||||||
_, err := os.Stat(s)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
plog.Debug("packr", "resolutionDir", "original", og, "resolved", s)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolutionDir(og string) string {
|
|
||||||
ng, _ := filepath.Abs(og)
|
|
||||||
|
|
||||||
if resolutionDirExists(ng, og) {
|
|
||||||
return ng
|
|
||||||
}
|
|
||||||
|
|
||||||
// packr.New
|
|
||||||
_, filename, _, _ := runtime.Caller(3)
|
|
||||||
ng, ok := resolutionDirTestFilename(filename, og)
|
|
||||||
if ok {
|
|
||||||
return ng
|
|
||||||
}
|
|
||||||
|
|
||||||
// packr.NewBox (deprecated)
|
|
||||||
_, filename, _, _ = runtime.Caller(4)
|
|
||||||
ng, ok = resolutionDirTestFilename(filename, og)
|
|
||||||
if ok {
|
|
||||||
return ng
|
|
||||||
}
|
|
||||||
|
|
||||||
return og
|
|
||||||
}
|
|
52
vendor/github.com/gobuffalo/packr/v2/jam/parser/args.go
generated
vendored
52
vendor/github.com/gobuffalo/packr/v2/jam/parser/args.go
generated
vendored
@ -1,52 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FromArgs is useful when writing packr store-cmd binaries.
|
|
||||||
/*
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/jam/parser"
|
|
||||||
"github.com/markbates/s3packr/s3packr"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := parser.FromArgs(os.Args[1:], func(boxes parser.Boxes) error {
|
|
||||||
for _, box := range boxes {
|
|
||||||
s3 := s3packr.New(box)
|
|
||||||
if err := s3.Pack(box); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
func FromArgs(args []string, fn func(Boxes) error) error {
|
|
||||||
if len(args) == 0 {
|
|
||||||
return fmt.Errorf("you must supply a payload")
|
|
||||||
}
|
|
||||||
payload := args[0]
|
|
||||||
if len(payload) == 0 {
|
|
||||||
return fmt.Errorf("you must supply a payload")
|
|
||||||
}
|
|
||||||
|
|
||||||
var boxes Boxes
|
|
||||||
err := json.Unmarshal([]byte(payload), &boxes)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fn(boxes)
|
|
||||||
}
|
|
40
vendor/github.com/gobuffalo/packr/v2/jam/parser/box.go
generated
vendored
40
vendor/github.com/gobuffalo/packr/v2/jam/parser/box.go
generated
vendored
@ -1,40 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Box found while parsing a file
|
|
||||||
type Box struct {
|
|
||||||
Name string // name of the box
|
|
||||||
Path string // relative path of folder NewBox("./templates")
|
|
||||||
AbsPath string // absolute path of Path
|
|
||||||
Package string // the package name the box was found in
|
|
||||||
PWD string // the PWD when the parser was run
|
|
||||||
PackageDir string // the absolute path of the package where the box was found
|
|
||||||
}
|
|
||||||
|
|
||||||
type Boxes []*Box
|
|
||||||
|
|
||||||
// String - json returned
|
|
||||||
func (b Box) String() string {
|
|
||||||
x, _ := json.Marshal(b)
|
|
||||||
return string(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBox stub from the name and the path provided
|
|
||||||
func NewBox(name string, path string) *Box {
|
|
||||||
if len(name) == 0 {
|
|
||||||
name = path
|
|
||||||
}
|
|
||||||
name = strings.Replace(name, "\"", "", -1)
|
|
||||||
pwd, _ := os.Getwd()
|
|
||||||
box := &Box{
|
|
||||||
Name: name,
|
|
||||||
Path: path,
|
|
||||||
PWD: pwd,
|
|
||||||
}
|
|
||||||
return box
|
|
||||||
}
|
|
54
vendor/github.com/gobuffalo/packr/v2/jam/parser/file.go
generated
vendored
54
vendor/github.com/gobuffalo/packr/v2/jam/parser/file.go
generated
vendored
@ -1,54 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
// File that is to be parsed
|
|
||||||
type File struct {
|
|
||||||
io.Reader
|
|
||||||
Path string
|
|
||||||
AbsPath string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name of the file "app.go"
|
|
||||||
func (f File) Name() string {
|
|
||||||
return f.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the contents of the reader
|
|
||||||
func (f *File) String() string {
|
|
||||||
src, _ := ioutil.ReadAll(f)
|
|
||||||
f.Reader = bytes.NewReader(src)
|
|
||||||
return string(src)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *File) Write(p []byte) (int, error) {
|
|
||||||
bb := &bytes.Buffer{}
|
|
||||||
i, err := bb.Write(p)
|
|
||||||
s.Reader = bb
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFile takes the name of the file you want to
|
|
||||||
// write to and a reader to reader from
|
|
||||||
func NewFile(path string, r io.Reader) *File {
|
|
||||||
if r == nil {
|
|
||||||
r = &bytes.Buffer{}
|
|
||||||
}
|
|
||||||
if seek, ok := r.(io.Seeker); ok {
|
|
||||||
seek.Seek(0, 0)
|
|
||||||
}
|
|
||||||
abs := path
|
|
||||||
if !filepath.IsAbs(path) {
|
|
||||||
abs, _ = filepath.Abs(path)
|
|
||||||
}
|
|
||||||
return &File{
|
|
||||||
Reader: r,
|
|
||||||
Path: path,
|
|
||||||
AbsPath: abs,
|
|
||||||
}
|
|
||||||
}
|
|
112
vendor/github.com/gobuffalo/packr/v2/jam/parser/finder.go
generated
vendored
112
vendor/github.com/gobuffalo/packr/v2/jam/parser/finder.go
generated
vendored
@ -1,112 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"go/build"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
"github.com/karrick/godirwalk"
|
|
||||||
"github.com/markbates/errx"
|
|
||||||
"github.com/markbates/oncer"
|
|
||||||
)
|
|
||||||
|
|
||||||
type finder struct {
|
|
||||||
id time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fd *finder) key(m, dir string) string {
|
|
||||||
return fmt.Sprintf("%s-*parser.finder#%s-%s", fd.id, m, dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
// findAllGoFiles *.go files for a given diretory
|
|
||||||
func (fd *finder) findAllGoFiles(dir string) ([]string, error) {
|
|
||||||
var err error
|
|
||||||
var names []string
|
|
||||||
oncer.Do(fd.key("findAllGoFiles", dir), func() {
|
|
||||||
plog.Debug(fd, "findAllGoFiles", "dir", dir)
|
|
||||||
|
|
||||||
callback := func(path string, do *godirwalk.Dirent) error {
|
|
||||||
ext := filepath.Ext(path)
|
|
||||||
if ext != ".go" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
//check if path is a dir
|
|
||||||
fi, err := os.Stat(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if fi.IsDir() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
names = append(names, path)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err = godirwalk.Walk(dir, &godirwalk.Options{
|
|
||||||
FollowSymbolicLinks: true,
|
|
||||||
Callback: callback,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return names, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fd *finder) findAllGoFilesImports(dir string) ([]string, error) {
|
|
||||||
var err error
|
|
||||||
var names []string
|
|
||||||
oncer.Do(fd.key("findAllGoFilesImports", dir), func() {
|
|
||||||
ctx := build.Default
|
|
||||||
|
|
||||||
if len(ctx.SrcDirs()) == 0 {
|
|
||||||
err = fmt.Errorf("no src directories found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pkg, err := ctx.ImportDir(dir, 0)
|
|
||||||
if strings.HasPrefix(pkg.ImportPath, "github.com/gobuffalo/packr") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if !strings.Contains(err.Error(), "cannot find package") {
|
|
||||||
if _, ok := errx.Unwrap(err).(*build.NoGoError); !ok {
|
|
||||||
err = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if pkg.Goroot {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(pkg.GoFiles) <= 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
plog.Debug(fd, "findAllGoFilesImports", "dir", dir)
|
|
||||||
|
|
||||||
names, _ = fd.findAllGoFiles(dir)
|
|
||||||
for _, n := range pkg.GoFiles {
|
|
||||||
names = append(names, filepath.Join(pkg.Dir, n))
|
|
||||||
}
|
|
||||||
for _, imp := range pkg.Imports {
|
|
||||||
if len(ctx.SrcDirs()) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
d := ctx.SrcDirs()[len(ctx.SrcDirs())-1]
|
|
||||||
ip := filepath.Join(d, imp)
|
|
||||||
n, err := fd.findAllGoFilesImports(ip)
|
|
||||||
if err != nil && len(n) != 0 {
|
|
||||||
names = n
|
|
||||||
return
|
|
||||||
}
|
|
||||||
names = append(names, n...)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return names, err
|
|
||||||
}
|
|
43
vendor/github.com/gobuffalo/packr/v2/jam/parser/gogen.go
generated
vendored
43
vendor/github.com/gobuffalo/packr/v2/jam/parser/gogen.go
generated
vendored
@ -1,43 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go/ast"
|
|
||||||
"go/parser"
|
|
||||||
"go/token"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packd"
|
|
||||||
"github.com/markbates/errx"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParsedFile ...
|
|
||||||
type ParsedFile struct {
|
|
||||||
File packd.SimpleFile
|
|
||||||
FileSet *token.FileSet
|
|
||||||
Ast *ast.File
|
|
||||||
Lines []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseFileMode ...
|
|
||||||
func ParseFileMode(gf packd.SimpleFile, mode parser.Mode) (ParsedFile, error) {
|
|
||||||
pf := ParsedFile{
|
|
||||||
FileSet: token.NewFileSet(),
|
|
||||||
File: gf,
|
|
||||||
}
|
|
||||||
|
|
||||||
src := gf.String()
|
|
||||||
f, err := parser.ParseFile(pf.FileSet, gf.Name(), src, mode)
|
|
||||||
if err != nil && errx.Unwrap(err) != io.EOF {
|
|
||||||
return pf, err
|
|
||||||
}
|
|
||||||
pf.Ast = f
|
|
||||||
|
|
||||||
pf.Lines = strings.Split(src, "\n")
|
|
||||||
return pf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseFile ...
|
|
||||||
func ParseFile(gf packd.SimpleFile) (ParsedFile, error) {
|
|
||||||
return ParseFileMode(gf, 0)
|
|
||||||
}
|
|
46
vendor/github.com/gobuffalo/packr/v2/jam/parser/parser.go
generated
vendored
46
vendor/github.com/gobuffalo/packr/v2/jam/parser/parser.go
generated
vendored
@ -1,46 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Parser to find boxes
|
|
||||||
type Parser struct {
|
|
||||||
Prospects []*File // a list of files to check for boxes
|
|
||||||
IgnoreImports bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the parser and run any boxes found
|
|
||||||
func (p *Parser) Run() (Boxes, error) {
|
|
||||||
var boxes Boxes
|
|
||||||
for _, pros := range p.Prospects {
|
|
||||||
plog.Debug(p, "Run", "parsing", pros.Name())
|
|
||||||
v := NewVisitor(pros)
|
|
||||||
pbr, err := v.Run()
|
|
||||||
if err != nil {
|
|
||||||
return boxes, err
|
|
||||||
}
|
|
||||||
for _, b := range pbr {
|
|
||||||
plog.Debug(p, "Run", "file", pros.Name(), "box", b.Name)
|
|
||||||
boxes = append(boxes, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pwd, _ := os.Getwd()
|
|
||||||
sort.Slice(boxes, func(a, b int) bool {
|
|
||||||
b1 := boxes[a]
|
|
||||||
return !strings.HasPrefix(b1.AbsPath, pwd)
|
|
||||||
})
|
|
||||||
return boxes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New Parser from a list of File
|
|
||||||
func New(prospects ...*File) *Parser {
|
|
||||||
return &Parser{
|
|
||||||
Prospects: prospects,
|
|
||||||
}
|
|
||||||
}
|
|
77
vendor/github.com/gobuffalo/packr/v2/jam/parser/prospect.go
generated
vendored
77
vendor/github.com/gobuffalo/packr/v2/jam/parser/prospect.go
generated
vendored
@ -1,77 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/file/resolver"
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DefaultIgnoredFolders = []string{".", "_", "vendor", "node_modules", "_fixtures", "testdata"}
|
|
||||||
|
|
||||||
func IsProspect(path string, ignore ...string) (status bool) {
|
|
||||||
// plog.Debug("parser", "IsProspect", "path", path, "ignore", ignore)
|
|
||||||
defer func() {
|
|
||||||
if status {
|
|
||||||
plog.Debug("parser", "IsProspect (TRUE)", "path", path, "status", status)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if path == "." {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
ext := filepath.Ext(path)
|
|
||||||
dir := filepath.Dir(path)
|
|
||||||
|
|
||||||
fi, _ := os.Stat(path)
|
|
||||||
if fi != nil {
|
|
||||||
if fi.IsDir() {
|
|
||||||
dir = filepath.Base(path)
|
|
||||||
} else {
|
|
||||||
if len(ext) > 0 {
|
|
||||||
dir = filepath.Base(filepath.Dir(path))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path = strings.ToLower(path)
|
|
||||||
dir = strings.ToLower(dir)
|
|
||||||
|
|
||||||
if strings.HasSuffix(path, "-packr.go") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasSuffix(path, "_test.go") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
ignore = append(ignore, DefaultIgnoredFolders...)
|
|
||||||
for i, x := range ignore {
|
|
||||||
ignore[i] = strings.TrimSpace(strings.ToLower(x))
|
|
||||||
}
|
|
||||||
|
|
||||||
parts := strings.Split(resolver.OsPath(path), string(filepath.Separator))
|
|
||||||
if len(parts) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, i := range ignore {
|
|
||||||
for _, p := range parts {
|
|
||||||
if strings.HasPrefix(p, i) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
un := filepath.Base(path)
|
|
||||||
if len(ext) != 0 {
|
|
||||||
un = filepath.Base(filepath.Dir(path))
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(un, "_") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return ext == ".go"
|
|
||||||
}
|
|
89
vendor/github.com/gobuffalo/packr/v2/jam/parser/roots.go
generated
vendored
89
vendor/github.com/gobuffalo/packr/v2/jam/parser/roots.go
generated
vendored
@ -1,89 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
"github.com/karrick/godirwalk"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RootsOptions struct {
|
|
||||||
IgnoreImports bool
|
|
||||||
Ignores []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r RootsOptions) String() string {
|
|
||||||
x, _ := json.Marshal(r)
|
|
||||||
return string(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFromRoots scans the file roots provided and returns a
|
|
||||||
// new Parser containing the prospects
|
|
||||||
func NewFromRoots(roots []string, opts *RootsOptions) (*Parser, error) {
|
|
||||||
if opts == nil {
|
|
||||||
opts = &RootsOptions{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(roots) == 0 {
|
|
||||||
pwd, _ := os.Getwd()
|
|
||||||
roots = append(roots, pwd)
|
|
||||||
}
|
|
||||||
p := New()
|
|
||||||
plog.Debug(p, "NewFromRoots", "roots", roots, "options", opts)
|
|
||||||
callback := func(path string, de *godirwalk.Dirent) error {
|
|
||||||
if IsProspect(path, opts.Ignores...) {
|
|
||||||
if de.IsDir() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
roots = append(roots, path)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if de.IsDir() {
|
|
||||||
return filepath.SkipDir
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
wopts := &godirwalk.Options{
|
|
||||||
FollowSymbolicLinks: true,
|
|
||||||
Callback: callback,
|
|
||||||
}
|
|
||||||
for _, root := range roots {
|
|
||||||
plog.Debug(p, "NewFromRoots", "walking", root)
|
|
||||||
err := godirwalk.Walk(root, wopts)
|
|
||||||
if err != nil {
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dd := map[string]string{}
|
|
||||||
fd := &finder{id: time.Now()}
|
|
||||||
for _, r := range roots {
|
|
||||||
var names []string
|
|
||||||
if opts.IgnoreImports {
|
|
||||||
names, _ = fd.findAllGoFiles(r)
|
|
||||||
} else {
|
|
||||||
names, _ = fd.findAllGoFilesImports(r)
|
|
||||||
}
|
|
||||||
for _, n := range names {
|
|
||||||
if IsProspect(n) {
|
|
||||||
plog.Debug(p, "NewFromRoots", "mapping", n)
|
|
||||||
dd[n] = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for path := range dd {
|
|
||||||
plog.Debug(p, "NewFromRoots", "reading file", path)
|
|
||||||
b, err := ioutil.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
p.Prospects = append(p.Prospects, NewFile(path, bytes.NewReader(b)))
|
|
||||||
}
|
|
||||||
plog.Debug(p, "NewFromRoots", "found prospects", len(p.Prospects))
|
|
||||||
return p, nil
|
|
||||||
}
|
|
324
vendor/github.com/gobuffalo/packr/v2/jam/parser/visitor.go
generated
vendored
324
vendor/github.com/gobuffalo/packr/v2/jam/parser/visitor.go
generated
vendored
@ -1,324 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packd"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Visitor struct {
|
|
||||||
File packd.SimpleFile
|
|
||||||
Package string
|
|
||||||
boxes map[string]*Box
|
|
||||||
errors []error
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewVisitor(f *File) *Visitor {
|
|
||||||
return &Visitor{
|
|
||||||
File: f,
|
|
||||||
boxes: map[string]*Box{},
|
|
||||||
errors: []error{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) Run() (Boxes, error) {
|
|
||||||
var boxes Boxes
|
|
||||||
pf, err := ParseFile(v.File)
|
|
||||||
if err != nil {
|
|
||||||
return boxes, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Package = pf.Ast.Name.Name
|
|
||||||
ast.Walk(v, pf.Ast)
|
|
||||||
|
|
||||||
for _, vb := range v.boxes {
|
|
||||||
boxes = append(boxes, vb)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(boxes, func(i, j int) bool {
|
|
||||||
return boxes[i].Name < boxes[j].Name
|
|
||||||
})
|
|
||||||
|
|
||||||
if len(v.errors) > 0 {
|
|
||||||
s := make([]string, len(v.errors))
|
|
||||||
for i, e := range v.errors {
|
|
||||||
s[i] = e.Error()
|
|
||||||
}
|
|
||||||
return boxes, err
|
|
||||||
}
|
|
||||||
return boxes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
|
||||||
if node == nil {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
if err := v.eval(node); err != nil {
|
|
||||||
v.errors = append(v.errors, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) eval(node ast.Node) error {
|
|
||||||
switch t := node.(type) {
|
|
||||||
case *ast.CallExpr:
|
|
||||||
return v.evalExpr(t)
|
|
||||||
case *ast.Ident:
|
|
||||||
return v.evalIdent(t)
|
|
||||||
case *ast.GenDecl:
|
|
||||||
for _, n := range t.Specs {
|
|
||||||
if err := v.eval(n); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case *ast.FuncDecl:
|
|
||||||
if t.Body == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for _, b := range t.Body.List {
|
|
||||||
if err := v.evalStmt(b); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
case *ast.ValueSpec:
|
|
||||||
for _, e := range t.Values {
|
|
||||||
if err := v.evalExpr(e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) evalStmt(stmt ast.Stmt) error {
|
|
||||||
switch t := stmt.(type) {
|
|
||||||
case *ast.ExprStmt:
|
|
||||||
return v.evalExpr(t.X)
|
|
||||||
case *ast.AssignStmt:
|
|
||||||
for _, e := range t.Rhs {
|
|
||||||
if err := v.evalArgs(e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) evalExpr(expr ast.Expr) error {
|
|
||||||
switch t := expr.(type) {
|
|
||||||
case *ast.CallExpr:
|
|
||||||
if t.Fun == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for _, a := range t.Args {
|
|
||||||
switch at := a.(type) {
|
|
||||||
case *ast.CallExpr:
|
|
||||||
if sel, ok := t.Fun.(*ast.SelectorExpr); ok {
|
|
||||||
return v.evalSelector(at, sel)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := v.evalArgs(at); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *ast.CompositeLit:
|
|
||||||
for _, e := range at.Elts {
|
|
||||||
if err := v.evalExpr(e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ft, ok := t.Fun.(*ast.SelectorExpr); ok {
|
|
||||||
return v.evalSelector(t, ft)
|
|
||||||
}
|
|
||||||
case *ast.KeyValueExpr:
|
|
||||||
return v.evalExpr(t.Value)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) evalArgs(expr ast.Expr) error {
|
|
||||||
switch at := expr.(type) {
|
|
||||||
case *ast.CompositeLit:
|
|
||||||
for _, e := range at.Elts {
|
|
||||||
if err := v.evalExpr(e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case *ast.CallExpr:
|
|
||||||
if at.Fun == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
switch st := at.Fun.(type) {
|
|
||||||
case *ast.SelectorExpr:
|
|
||||||
if err := v.evalSelector(at, st); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *ast.Ident:
|
|
||||||
return v.evalIdent(st)
|
|
||||||
}
|
|
||||||
for _, a := range at.Args {
|
|
||||||
if err := v.evalArgs(a); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) evalSelector(expr *ast.CallExpr, sel *ast.SelectorExpr) error {
|
|
||||||
x, ok := sel.X.(*ast.Ident)
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if x.Name == "packr" {
|
|
||||||
switch sel.Sel.Name {
|
|
||||||
case "New":
|
|
||||||
if len(expr.Args) != 2 {
|
|
||||||
return fmt.Errorf("`New` requires two arguments")
|
|
||||||
}
|
|
||||||
|
|
||||||
zz := func(e ast.Expr) (string, error) {
|
|
||||||
switch at := e.(type) {
|
|
||||||
case *ast.Ident:
|
|
||||||
switch at.Obj.Kind {
|
|
||||||
case ast.Var:
|
|
||||||
if as, ok := at.Obj.Decl.(*ast.AssignStmt); ok {
|
|
||||||
return v.fromVariable(as)
|
|
||||||
}
|
|
||||||
case ast.Con:
|
|
||||||
if vs, ok := at.Obj.Decl.(*ast.ValueSpec); ok {
|
|
||||||
return v.fromConstant(vs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", v.evalIdent(at)
|
|
||||||
case *ast.BasicLit:
|
|
||||||
return at.Value, nil
|
|
||||||
case *ast.CallExpr:
|
|
||||||
return "", v.evalExpr(at)
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("can't handle %T", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
k1, err := zz(expr.Args[0])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
k2, err := zz(expr.Args[1])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.addBox(k1, k2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
case "NewBox":
|
|
||||||
for _, e := range expr.Args {
|
|
||||||
switch at := e.(type) {
|
|
||||||
case *ast.Ident:
|
|
||||||
switch at.Obj.Kind {
|
|
||||||
case ast.Var:
|
|
||||||
if as, ok := at.Obj.Decl.(*ast.AssignStmt); ok {
|
|
||||||
v.addVariable("", as)
|
|
||||||
}
|
|
||||||
case ast.Con:
|
|
||||||
if vs, ok := at.Obj.Decl.(*ast.ValueSpec); ok {
|
|
||||||
v.addConstant("", vs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v.evalIdent(at)
|
|
||||||
case *ast.BasicLit:
|
|
||||||
v.addBox("", at.Value)
|
|
||||||
case *ast.CallExpr:
|
|
||||||
return v.evalExpr(at)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) evalIdent(i *ast.Ident) error {
|
|
||||||
if i.Obj == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if s, ok := i.Obj.Decl.(*ast.AssignStmt); ok {
|
|
||||||
return v.evalStmt(s)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) addBox(name string, path string) {
|
|
||||||
if len(name) == 0 {
|
|
||||||
name = path
|
|
||||||
}
|
|
||||||
name = strings.Replace(name, "\"", "", -1)
|
|
||||||
path = strings.Replace(path, "\"", "", -1)
|
|
||||||
abs := path
|
|
||||||
if _, ok := v.boxes[name]; !ok {
|
|
||||||
box := NewBox(name, path)
|
|
||||||
box.Package = v.Package
|
|
||||||
|
|
||||||
pd := filepath.Dir(v.File.Name())
|
|
||||||
pwd, _ := os.Getwd()
|
|
||||||
if !filepath.IsAbs(pd) {
|
|
||||||
pd = filepath.Join(pwd, pd)
|
|
||||||
}
|
|
||||||
box.PackageDir = pd
|
|
||||||
|
|
||||||
if !filepath.IsAbs(abs) {
|
|
||||||
abs = filepath.Join(pd, abs)
|
|
||||||
}
|
|
||||||
box.AbsPath = abs
|
|
||||||
v.boxes[name] = box
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (v *Visitor) fromVariable(as *ast.AssignStmt) (string, error) {
|
|
||||||
if len(as.Rhs) == 1 {
|
|
||||||
if bs, ok := as.Rhs[0].(*ast.BasicLit); ok {
|
|
||||||
return bs.Value, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("unable to find value from variable %v", as)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) addVariable(bn string, as *ast.AssignStmt) error {
|
|
||||||
bv, err := v.fromVariable(as)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(bn) == 0 {
|
|
||||||
bn = bv
|
|
||||||
}
|
|
||||||
v.addBox(bn, bv)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) fromConstant(vs *ast.ValueSpec) (string, error) {
|
|
||||||
if len(vs.Values) == 1 {
|
|
||||||
if bs, ok := vs.Values[0].(*ast.BasicLit); ok {
|
|
||||||
return bs.Value, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("unable to find value from constant %v", vs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Visitor) addConstant(bn string, vs *ast.ValueSpec) error {
|
|
||||||
if len(vs.Values) == 1 {
|
|
||||||
if bs, ok := vs.Values[0].(*ast.BasicLit); ok {
|
|
||||||
bv := bs.Value
|
|
||||||
if len(bn) == 0 {
|
|
||||||
bn = bv
|
|
||||||
}
|
|
||||||
v.addBox(bn, bv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
56
vendor/github.com/gobuffalo/packr/v2/packr.go
generated
vendored
56
vendor/github.com/gobuffalo/packr/v2/packr.go
generated
vendored
@ -1,56 +0,0 @@
|
|||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/file/resolver"
|
|
||||||
"github.com/gobuffalo/packr/v2/jam/parser"
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
"github.com/markbates/safe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var boxes = &boxMap{}
|
|
||||||
|
|
||||||
var _ = safe.Run(func() {
|
|
||||||
p, err := parser.NewFromRoots([]string{}, nil)
|
|
||||||
if err != nil {
|
|
||||||
plog.Logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
boxes, err := p.Run()
|
|
||||||
if err != nil {
|
|
||||||
plog.Logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, box := range boxes {
|
|
||||||
b := construct(box.Name, box.AbsPath)
|
|
||||||
_, err = placeBox(b)
|
|
||||||
if err != nil {
|
|
||||||
plog.Logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
func findBox(name string) (*Box, error) {
|
|
||||||
key := resolver.Key(name)
|
|
||||||
plog.Debug("packr", "findBox", "name", name, "key", key)
|
|
||||||
|
|
||||||
b, ok := boxes.Load(key)
|
|
||||||
if !ok {
|
|
||||||
plog.Debug("packr", "findBox", "name", name, "key", key, "found", ok)
|
|
||||||
return nil, fmt.Errorf("could not find box %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
plog.Debug(b, "found", "box", b)
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func placeBox(b *Box) (*Box, error) {
|
|
||||||
key := resolver.Key(b.Name)
|
|
||||||
eb, _ := boxes.LoadOrStore(key, b)
|
|
||||||
|
|
||||||
plog.Debug("packr", "placeBox", "name", eb.Name, "path", eb.Path, "resolution directory", eb.ResolutionDir)
|
|
||||||
return eb, nil
|
|
||||||
}
|
|
41
vendor/github.com/gobuffalo/packr/v2/plog/plog.go
generated
vendored
41
vendor/github.com/gobuffalo/packr/v2/plog/plog.go
generated
vendored
@ -1,41 +0,0 @@
|
|||||||
package plog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/logger"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Logger = logger.New(logger.ErrorLevel)
|
|
||||||
|
|
||||||
func Debug(t interface{}, m string, args ...interface{}) {
|
|
||||||
if len(args)%2 == 1 {
|
|
||||||
args = append(args, "")
|
|
||||||
}
|
|
||||||
f := logrus.Fields{}
|
|
||||||
for i := 0; i < len(args); i += 2 {
|
|
||||||
k := fmt.Sprint(args[i])
|
|
||||||
v := args[i+1]
|
|
||||||
if s, ok := v.(fmt.Stringer); ok {
|
|
||||||
f[k] = s.String()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if s, ok := v.(string); ok {
|
|
||||||
f[k] = s
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if b, err := json.Marshal(v); err == nil {
|
|
||||||
f[k] = string(b)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
f[k] = v
|
|
||||||
}
|
|
||||||
e := Logger.WithFields(f)
|
|
||||||
if s, ok := t.(string); ok {
|
|
||||||
e.Debugf("%s#%s", s, m)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
e.Debugf("%T#%s", t, m)
|
|
||||||
}
|
|
32
vendor/github.com/gobuffalo/packr/v2/pointer.go
generated
vendored
32
vendor/github.com/gobuffalo/packr/v2/pointer.go
generated
vendored
@ -1,32 +0,0 @@
|
|||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gobuffalo/packr/v2/file"
|
|
||||||
"github.com/gobuffalo/packr/v2/file/resolver"
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Pointer is a resolvr which resolves
|
|
||||||
// a file from a different box.
|
|
||||||
type Pointer struct {
|
|
||||||
ForwardBox string
|
|
||||||
ForwardPath string
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ resolver.Resolver = Pointer{}
|
|
||||||
|
|
||||||
// Resolve attempts to find the file in the specific box
|
|
||||||
// with the specified key
|
|
||||||
func (p Pointer) Resolve(box string, path string) (file.File, error) {
|
|
||||||
plog.Debug(p, "Resolve", "box", box, "path", path, "forward-box", p.ForwardBox, "forward-path", p.ForwardPath)
|
|
||||||
b, err := findBox(p.ForwardBox)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
f, err := b.Resolve(p.ForwardPath)
|
|
||||||
if err != nil {
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
plog.Debug(p, "Resolve", "box", box, "path", path, "file", f)
|
|
||||||
return file.NewFileR(path, f)
|
|
||||||
}
|
|
75
vendor/github.com/gobuffalo/packr/v2/resolvers_map.go
generated
vendored
75
vendor/github.com/gobuffalo/packr/v2/resolvers_map.go
generated
vendored
@ -1,75 +0,0 @@
|
|||||||
//go:generate mapgen -name "resolvers" -zero "nil" -go-type "resolver.Resolver" -pkg "" -a "nil" -b "nil" -c "nil" -bb "nil" -destination "packr"
|
|
||||||
// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2/file/resolver"
|
|
||||||
)
|
|
||||||
|
|
||||||
// resolversMap wraps sync.Map and uses the following types:
|
|
||||||
// key: string
|
|
||||||
// value: resolver.Resolver
|
|
||||||
type resolversMap struct {
|
|
||||||
data sync.Map
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the key from the map
|
|
||||||
func (m *resolversMap) Delete(key string) {
|
|
||||||
m.data.Delete(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the key from the map.
|
|
||||||
// Returns resolver.Resolver or bool.
|
|
||||||
// A false return indicates either the key was not found
|
|
||||||
// or the value is not of type resolver.Resolver
|
|
||||||
func (m *resolversMap) Load(key string) (resolver.Resolver, bool) {
|
|
||||||
i, ok := m.data.Load(key)
|
|
||||||
if !ok {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
s, ok := i.(resolver.Resolver)
|
|
||||||
return s, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadOrStore will return an existing key or
|
|
||||||
// store the value if not already in the map
|
|
||||||
func (m *resolversMap) LoadOrStore(key string, value resolver.Resolver) (resolver.Resolver, bool) {
|
|
||||||
i, _ := m.data.LoadOrStore(key, value)
|
|
||||||
s, ok := i.(resolver.Resolver)
|
|
||||||
return s, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Range over the resolver.Resolver values in the map
|
|
||||||
func (m *resolversMap) Range(f func(key string, value resolver.Resolver) bool) {
|
|
||||||
m.data.Range(func(k, v interface{}) bool {
|
|
||||||
key, ok := k.(string)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
value, ok := v.(resolver.Resolver)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return f(key, value)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store a resolver.Resolver in the map
|
|
||||||
func (m *resolversMap) Store(key string, value resolver.Resolver) {
|
|
||||||
m.data.Store(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys returns a list of keys in the map
|
|
||||||
func (m *resolversMap) Keys() []string {
|
|
||||||
var keys []string
|
|
||||||
m.Range(func(key string, value resolver.Resolver) bool {
|
|
||||||
keys = append(keys, key)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
sort.Strings(keys)
|
|
||||||
return keys
|
|
||||||
}
|
|
4
vendor/github.com/gobuffalo/packr/v2/version.go
generated
vendored
4
vendor/github.com/gobuffalo/packr/v2/version.go
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
package packr
|
|
||||||
|
|
||||||
// Version of Packr
|
|
||||||
const Version = "v2.8.1"
|
|
80
vendor/github.com/gobuffalo/packr/v2/walk.go
generated
vendored
80
vendor/github.com/gobuffalo/packr/v2/walk.go
generated
vendored
@ -1,80 +0,0 @@
|
|||||||
package packr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packd"
|
|
||||||
"github.com/gobuffalo/packr/v2/file"
|
|
||||||
"github.com/gobuffalo/packr/v2/file/resolver"
|
|
||||||
"github.com/gobuffalo/packr/v2/plog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WalkFunc is used to walk a box
|
|
||||||
type WalkFunc = packd.WalkFunc
|
|
||||||
|
|
||||||
// Walk will traverse the box and call the WalkFunc for each file in the box/folder.
|
|
||||||
func (b *Box) Walk(wf WalkFunc) error {
|
|
||||||
m := map[string]file.File{}
|
|
||||||
|
|
||||||
dr := b.DefaultResolver
|
|
||||||
if dr == nil {
|
|
||||||
cd := resolver.OsPath(b.ResolutionDir)
|
|
||||||
dr = &resolver.Disk{Root: cd}
|
|
||||||
}
|
|
||||||
if fm, ok := dr.(file.FileMappable); ok {
|
|
||||||
for n, f := range fm.FileMap() {
|
|
||||||
m[n] = f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
b.resolvers.Range(func(n string, r resolver.Resolver) bool {
|
|
||||||
var f file.File
|
|
||||||
f, err = r.Resolve("", n)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
keep := true
|
|
||||||
for k := range m {
|
|
||||||
if strings.EqualFold(k, n) {
|
|
||||||
keep = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if keep {
|
|
||||||
m[n] = f
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var keys = make([]string, 0, len(m))
|
|
||||||
for k := range m {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
for _, k := range keys {
|
|
||||||
osPath := resolver.OsPath(k)
|
|
||||||
plog.Debug(b, "Walk", "path", k, "osPath", osPath)
|
|
||||||
if err := wf(osPath, m[k]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WalkPrefix will call box.Walk and call the WalkFunc when it finds paths that have a matching prefix
|
|
||||||
func (b *Box) WalkPrefix(prefix string, wf WalkFunc) error {
|
|
||||||
ipref := resolver.OsPath(prefix)
|
|
||||||
return b.Walk(func(path string, f File) error {
|
|
||||||
ipath := resolver.OsPath(path)
|
|
||||||
if strings.HasPrefix(ipath, ipref) {
|
|
||||||
if err := wf(path, f); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user